1 /*
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ecmascript/jspandafile/literal_data_extractor.h"
17
18 #include "ecmascript/base/string_helper.h"
19 #include "ecmascript/compiler/aot_file/aot_file_manager.h"
20 #include "ecmascript/ecma_string.h"
21 #include "ecmascript/global_env.h"
22 #include "ecmascript/js_tagged_value.h"
23 #include "ecmascript/js_thread.h"
24 #include "ecmascript/module/js_module_manager.h"
25 #include "ecmascript/patch/quick_fix_manager.h"
26 #include "ecmascript/tagged_array-inl.h"
27
28 namespace panda::ecmascript {
29 using LiteralTag = panda_file::LiteralTag;
30 using StringData = panda_file::StringData;
31 using LiteralDataAccessor = panda_file::LiteralDataAccessor;
32 using LiteralValue = panda_file::LiteralDataAccessor::LiteralValue;
33
ExtractObjectDatas(JSThread * thread,const JSPandaFile * jsPandaFile,size_t index,JSMutableHandle<TaggedArray> elements,JSMutableHandle<TaggedArray> properties,JSHandle<ConstantPool> constpool,const CString & entryPoint)34 void LiteralDataExtractor::ExtractObjectDatas(JSThread *thread, const JSPandaFile *jsPandaFile, size_t index,
35 JSMutableHandle<TaggedArray> elements,
36 JSMutableHandle<TaggedArray> properties,
37 JSHandle<ConstantPool> constpool,
38 const CString &entryPoint)
39 {
40 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
41 LiteralDataAccessor lda = jsPandaFile->GetLiteralDataAccessor();
42 uint32_t num = lda.GetLiteralValsNum(index) / 2; // 2: half
43 elements.Update(factory->NewOldSpaceTaggedArray(num).GetTaggedValue());
44 properties.Update(factory->NewOldSpaceTaggedArray(num).GetTaggedValue());
45 uint32_t epos = 0;
46 uint32_t ppos = 0;
47 const uint8_t pairSize = 2;
48 uint32_t methodId = 0;
49 FunctionKind kind;
50 lda.EnumerateLiteralVals(
51 index, [elements, properties, &epos, &ppos, factory, thread, jsPandaFile,
52 &methodId, &kind, &constpool, &entryPoint](const LiteralValue &value, const LiteralTag &tag) {
53 JSTaggedValue jt = JSTaggedValue::Null();
54 bool flag = false;
55 switch (tag) {
56 case LiteralTag::INTEGER: {
57 jt = JSTaggedValue(std::get<uint32_t>(value));
58 break;
59 }
60 case LiteralTag::DOUBLE: {
61 jt = JSTaggedValue(std::get<double>(value));
62 break;
63 }
64 case LiteralTag::BOOL: {
65 jt = JSTaggedValue(std::get<bool>(value));
66 break;
67 }
68 case LiteralTag::STRING: {
69 StringData sd = jsPandaFile->GetStringData(EntityId(std::get<uint32_t>(value)));
70 EcmaString *str = factory->GetRawStringFromStringTable(sd, MemSpaceType::OLD_SPACE);
71 jt = JSTaggedValue(str);
72 uint32_t elementIndex = 0;
73 if (JSTaggedValue::ToElementIndex(jt, &elementIndex) && ppos % pairSize == 0) {
74 flag = true;
75 }
76 break;
77 }
78 case LiteralTag::METHOD: {
79 methodId = std::get<uint32_t>(value);
80 kind = FunctionKind::NORMAL_FUNCTION;
81 break;
82 }
83 case LiteralTag::GETTER: {
84 methodId = std::get<uint32_t>(value);
85 kind = FunctionKind::GETTER_FUNCTION;
86 break;
87 }
88 case LiteralTag::SETTER: {
89 methodId = std::get<uint32_t>(value);
90 kind = FunctionKind::SETTER_FUNCTION;
91 break;
92 }
93 case LiteralTag::GENERATORMETHOD: {
94 methodId = std::get<uint32_t>(value);
95 kind = FunctionKind::GENERATOR_FUNCTION;
96 break;
97 }
98 case LiteralTag::METHODAFFILIATE: {
99 uint16_t length = std::get<uint16_t>(value);
100 JSHandle<JSFunction> jsFunc =
101 DefineMethodInLiteral(thread, jsPandaFile, methodId, constpool, kind, length, entryPoint);
102 jt = jsFunc.GetTaggedValue();
103 break;
104 }
105 case LiteralTag::ACCESSOR: {
106 JSHandle<AccessorData> accessor = factory->NewAccessorData();
107 jt = accessor.GetTaggedValue();
108 break;
109 }
110 case LiteralTag::NULLVALUE: {
111 break;
112 }
113 default: {
114 LOG_ECMA(FATAL) << "this branch is unreachable";
115 UNREACHABLE();
116 break;
117 }
118 }
119 if (tag != LiteralTag::METHOD && tag != LiteralTag::GETTER && tag != LiteralTag::SETTER &&
120 tag != LiteralTag::GENERATORMETHOD) {
121 if (epos % pairSize == 0 && !flag) {
122 properties->Set(thread, ppos++, jt);
123 } else {
124 elements->Set(thread, epos++, jt);
125 }
126 }
127 });
128 }
129
GetDatasIgnoreTypeForClass(JSThread * thread,const JSPandaFile * jsPandaFile,size_t index,JSHandle<ConstantPool> constpool,const CString & entryPoint)130 JSHandle<TaggedArray> LiteralDataExtractor::GetDatasIgnoreTypeForClass(JSThread *thread,
131 const JSPandaFile *jsPandaFile, size_t index, JSHandle<ConstantPool> constpool, const CString &entryPoint)
132 {
133 LiteralDataAccessor lda = jsPandaFile->GetLiteralDataAccessor();
134 uint32_t num = lda.GetLiteralValsNum(index) / 2; // 2: half
135 // The num is 1, indicating that the current class has no member variable.
136 if (num == 1) {
137 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
138 return factory->EmptyArray();
139 }
140 return EnumerateLiteralVals(thread, lda, jsPandaFile, index, constpool, entryPoint);
141 }
142
GetDatasIgnoreType(JSThread * thread,const JSPandaFile * jsPandaFile,size_t index,JSHandle<ConstantPool> constpool,const CString & entryPoint)143 JSHandle<TaggedArray> LiteralDataExtractor::GetDatasIgnoreType(JSThread *thread, const JSPandaFile *jsPandaFile,
144 size_t index, JSHandle<ConstantPool> constpool,
145 const CString &entryPoint)
146 {
147 LiteralDataAccessor lda = jsPandaFile->GetLiteralDataAccessor();
148 return EnumerateLiteralVals(thread, lda, jsPandaFile, index, constpool, entryPoint);
149 }
150
EnumerateLiteralVals(JSThread * thread,LiteralDataAccessor & lda,const JSPandaFile * jsPandaFile,size_t index,JSHandle<ConstantPool> constpool,const CString & entryPoint)151 JSHandle<TaggedArray> LiteralDataExtractor::EnumerateLiteralVals(JSThread *thread, LiteralDataAccessor &lda,
152 const JSPandaFile *jsPandaFile, size_t index, JSHandle<ConstantPool> constpool, const CString &entryPoint)
153 {
154 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
155 uint32_t num = lda.GetLiteralValsNum(index) / 2; // 2: half
156 JSHandle<TaggedArray> literals = factory->NewOldSpaceTaggedArray(num);
157 uint32_t pos = 0;
158 uint32_t methodId = 0;
159 FunctionKind kind;
160 lda.EnumerateLiteralVals(
161 index, [literals, &pos, factory, thread, jsPandaFile, &methodId, &kind, &constpool, &entryPoint]
162 (const LiteralValue &value, const LiteralTag &tag) {
163 JSTaggedValue jt = JSTaggedValue::Null();
164 switch (tag) {
165 case LiteralTag::INTEGER: {
166 jt = JSTaggedValue(std::get<uint32_t>(value));
167 break;
168 }
169 case LiteralTag::DOUBLE: {
170 jt = JSTaggedValue(std::get<double>(value));
171 break;
172 }
173 case LiteralTag::BOOL: {
174 jt = JSTaggedValue(std::get<bool>(value));
175 break;
176 }
177 case LiteralTag::STRING: {
178 StringData sd = jsPandaFile->GetStringData(EntityId(std::get<uint32_t>(value)));
179 EcmaString *str = factory->GetRawStringFromStringTable(sd, MemSpaceType::OLD_SPACE);
180 jt = JSTaggedValue(str);
181 break;
182 }
183 case LiteralTag::METHOD: {
184 methodId = std::get<uint32_t>(value);
185 kind = FunctionKind::NORMAL_FUNCTION;
186 break;
187 }
188 case LiteralTag::GETTER: {
189 methodId = std::get<uint32_t>(value);
190 kind = FunctionKind::GETTER_FUNCTION;
191 break;
192 }
193 case LiteralTag::SETTER: {
194 methodId = std::get<uint32_t>(value);
195 kind = FunctionKind::SETTER_FUNCTION;
196 break;
197 }
198 case LiteralTag::GENERATORMETHOD: {
199 methodId = std::get<uint32_t>(value);
200 kind = FunctionKind::GENERATOR_FUNCTION;
201 break;
202 }
203 case LiteralTag::METHODAFFILIATE: {
204 uint16_t length = std::get<uint16_t>(value);
205 JSHandle<JSFunction> jsFunc =
206 DefineMethodInLiteral(thread, jsPandaFile, methodId, constpool, kind, length, entryPoint);
207 jt = jsFunc.GetTaggedValue();
208 break;
209 }
210 case LiteralTag::ACCESSOR: {
211 JSHandle<AccessorData> accessor = factory->NewAccessorData();
212 jt = accessor.GetTaggedValue();
213 break;
214 }
215 case LiteralTag::NULLVALUE: {
216 break;
217 }
218 default: {
219 LOG_ECMA(FATAL) << "this branch is unreachable";
220 UNREACHABLE();
221 break;
222 }
223 }
224 if (tag != LiteralTag::METHOD && tag != LiteralTag::GETTER && tag != LiteralTag::SETTER &&
225 tag != LiteralTag::GENERATORMETHOD) {
226 literals->Set(thread, pos++, jt);
227 } else {
228 uint32_t oldLength = literals->GetLength();
229 literals->Trim(thread, oldLength - 1);
230 }
231 });
232 return literals;
233 }
234
CreateJSFunctionInLiteral(EcmaVM * vm,JSHandle<Method> method,FunctionKind kind,ClassKind classKind)235 JSHandle<JSFunction> LiteralDataExtractor::CreateJSFunctionInLiteral(EcmaVM *vm, JSHandle<Method> method,
236 FunctionKind kind, ClassKind classKind)
237 {
238 ObjectFactory *factory = vm->GetFactory();
239 JSHandle<GlobalEnv> env = vm->GetGlobalEnv();
240 JSHandle<JSFunction> jsFunc;
241 JSHandle<JSHClass> functionClass;
242 if (classKind == ClassKind::SENDABLE) {
243 if (kind == FunctionKind::NORMAL_FUNCTION ||
244 kind == FunctionKind::GETTER_FUNCTION ||
245 kind == FunctionKind::SETTER_FUNCTION) {
246 functionClass = JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithoutProto());
247 } else if (kind == FunctionKind::ASYNC_FUNCTION) {
248 functionClass = JSHandle<JSHClass>::Cast(env->GetAsyncFunctionClass());
249 } else {
250 functionClass = JSHandle<JSHClass>::Cast(env->GetGeneratorFunctionClass());
251 }
252 jsFunc = factory->NewSFunctionByHClass(method, functionClass);
253 } else {
254 if (kind == FunctionKind::NORMAL_FUNCTION ||
255 kind == FunctionKind::GETTER_FUNCTION ||
256 kind == FunctionKind::SETTER_FUNCTION) {
257 functionClass = JSHandle<JSHClass>::Cast(env->GetFunctionClassWithoutProto());
258 } else if (kind == FunctionKind::ASYNC_FUNCTION) {
259 functionClass = JSHandle<JSHClass>::Cast(env->GetAsyncFunctionClass());
260 } else {
261 functionClass = JSHandle<JSHClass>::Cast(env->GetGeneratorFunctionClass());
262 }
263 jsFunc = factory->NewJSFunctionByHClass(method, functionClass, MemSpaceType::OLD_SPACE);
264 }
265 return jsFunc;
266 }
267
DefineMethodInLiteral(JSThread * thread,const JSPandaFile * jsPandaFile,uint32_t offset,JSHandle<ConstantPool> constpool,FunctionKind kind,uint16_t length,const CString & entryPoint,bool isLoadedAOT,uint32_t entryIndex,ClassKind classKind)268 JSHandle<JSFunction> LiteralDataExtractor::DefineMethodInLiteral(JSThread *thread, const JSPandaFile *jsPandaFile,
269 uint32_t offset, JSHandle<ConstantPool> constpool,
270 FunctionKind kind, uint16_t length,
271 const CString &entryPoint,
272 bool isLoadedAOT, uint32_t entryIndex,
273 ClassKind classKind)
274 {
275 EcmaVM *vm = thread->GetEcmaVM();
276 ObjectFactory *factory = vm->GetFactory();
277
278 auto methodLiteral = jsPandaFile->FindMethodLiteral(offset);
279 ASSERT(methodLiteral != nullptr);
280 FunctionKind literalKind = methodLiteral->GetFunctionKind();
281 if (literalKind == FunctionKind::NONE_FUNCTION || classKind == ClassKind::SENDABLE) {
282 methodLiteral->SetFunctionKind(kind);
283 } else {
284 kind = literalKind;
285 }
286 bool canFastCall = false;
287
288 CString moduleName = jsPandaFile->GetJSPandaFileDesc();
289 CString entry = JSPandaFile::ENTRY_FUNCTION_NAME;
290 if (!entryPoint.empty()) {
291 moduleName = entryPoint;
292 entry = entryPoint;
293 }
294 JSRecordInfo recordInfo;
295 bool hasRecord = jsPandaFile->CheckAndGetRecordInfo(entry, recordInfo);
296 if (!hasRecord) {
297 LOG_ECMA(FATAL) << "cannot find record '" + entry + "', please check the request path.";
298 }
299 JSMutableHandle<JSTaggedValue> module(thread, JSTaggedValue::Undefined());
300 if (jsPandaFile->IsModule(recordInfo)) {
301 module.Update(thread->GetCurrentEcmaContext()->GetModuleManager()->HostGetImportedModule(moduleName));
302 } else {
303 module.Update(factory->NewFromUtf8(moduleName));
304 }
305
306 JSHandle<Method> method = factory->NewMethod(jsPandaFile, methodLiteral, constpool,
307 module, entryIndex, isLoadedAOT, &canFastCall);
308 JSHandle<JSHClass> functionClass;
309 JSHandle<JSFunction> jsFunc = CreateJSFunctionInLiteral(vm, method, kind, classKind);
310 jsFunc->SetLength(length);
311 return jsFunc;
312 }
313
GetMethodOffsets(const JSPandaFile * jsPandaFile,size_t index,std::vector<uint32_t> & methodOffsets)314 void LiteralDataExtractor::GetMethodOffsets(const JSPandaFile *jsPandaFile, size_t index,
315 std::vector<uint32_t> &methodOffsets)
316 {
317 LiteralDataAccessor lda = jsPandaFile->GetLiteralDataAccessor();
318 lda.EnumerateLiteralVals(index, [&methodOffsets](const LiteralValue &value, const LiteralTag &tag) {
319 switch (tag) {
320 case LiteralTag::METHOD:
321 case LiteralTag::GETTER:
322 case LiteralTag::SETTER:
323 case LiteralTag::GENERATORMETHOD: {
324 methodOffsets.emplace_back(std::get<uint32_t>(value));
325 break;
326 }
327 default: {
328 break;
329 }
330 }
331 });
332 }
333
GetMethodOffsets(const JSPandaFile * jsPandaFile,EntityId id,std::vector<uint32_t> & methodOffsets)334 void LiteralDataExtractor::GetMethodOffsets(const JSPandaFile *jsPandaFile, EntityId id,
335 std::vector<uint32_t> &methodOffsets)
336 {
337 LiteralDataAccessor lda = jsPandaFile->GetLiteralDataAccessor();
338 lda.EnumerateLiteralVals(id, [&methodOffsets](const LiteralValue &value, const LiteralTag &tag) {
339 switch (tag) {
340 case LiteralTag::METHOD:
341 case LiteralTag::GETTER:
342 case LiteralTag::SETTER:
343 case LiteralTag::GENERATORMETHOD: {
344 methodOffsets.emplace_back(std::get<uint32_t>(value));
345 break;
346 }
347 default: {
348 break;
349 }
350 }
351 });
352 }
353
ExtractObjectDatas(JSThread * thread,const JSPandaFile * jsPandaFile,EntityId id,JSMutableHandle<TaggedArray> elements,JSMutableHandle<TaggedArray> properties,JSHandle<ConstantPool> constpool,const CString & entry,bool isLoadedAOT,JSHandle<AOTLiteralInfo> entryIndexes)354 void LiteralDataExtractor::ExtractObjectDatas(JSThread *thread, const JSPandaFile *jsPandaFile, EntityId id,
355 JSMutableHandle<TaggedArray> elements,
356 JSMutableHandle<TaggedArray> properties,
357 JSHandle<ConstantPool> constpool, const CString &entry,
358 bool isLoadedAOT, JSHandle<AOTLiteralInfo> entryIndexes)
359 {
360 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
361 LiteralDataAccessor lda = jsPandaFile->GetLiteralDataAccessor();
362 uint32_t num = lda.GetLiteralValsNum(id) / 2; // 2: half
363 elements.Update(factory->NewOldSpaceTaggedArray(num).GetTaggedValue());
364 properties.Update(factory->NewOldSpaceTaggedArray(num).GetTaggedValue());
365 uint32_t epos = 0;
366 uint32_t ppos = 0;
367 const uint8_t pairSize = 2;
368 uint32_t methodId = 0;
369 int pos = 0;
370 FunctionKind kind;
371 lda.EnumerateLiteralVals(
372 id, [elements, properties, &entryIndexes, &pos, &epos, &ppos, factory, thread, jsPandaFile,
373 &methodId, &kind, &constpool, &entry, &isLoadedAOT](const LiteralValue &value, const LiteralTag &tag) {
374 JSTaggedValue jt = JSTaggedValue::Null();
375 bool flag = false;
376 switch (tag) {
377 case LiteralTag::INTEGER: {
378 jt = JSTaggedValue(static_cast<int32_t>(std::get<uint32_t>(value)));
379 break;
380 }
381 case LiteralTag::DOUBLE: {
382 jt = JSTaggedValue(std::get<double>(value));
383 break;
384 }
385 case LiteralTag::BOOL: {
386 jt = JSTaggedValue(std::get<bool>(value));
387 break;
388 }
389 case LiteralTag::STRING: {
390 StringData sd = jsPandaFile->GetStringData(EntityId(std::get<uint32_t>(value)));
391 EcmaString *str = factory->GetRawStringFromStringTable(sd, MemSpaceType::OLD_SPACE);
392 jt = JSTaggedValue(str);
393 uint32_t elementIndex = 0;
394 if (JSTaggedValue::ToElementIndex(jt, &elementIndex) && ppos % pairSize == 0) {
395 flag = true;
396 }
397 break;
398 }
399 case LiteralTag::METHOD: {
400 methodId = std::get<uint32_t>(value);
401 kind = FunctionKind::NORMAL_FUNCTION;
402 break;
403 }
404 case LiteralTag::GETTER: {
405 methodId = std::get<uint32_t>(value);
406 kind = FunctionKind::GETTER_FUNCTION;
407 break;
408 }
409 case LiteralTag::SETTER: {
410 methodId = std::get<uint32_t>(value);
411 kind = FunctionKind::SETTER_FUNCTION;
412 break;
413 }
414 case LiteralTag::GENERATORMETHOD: {
415 methodId = std::get<uint32_t>(value);
416 kind = FunctionKind::GENERATOR_FUNCTION;
417 break;
418 }
419 case LiteralTag::METHODAFFILIATE: {
420 uint16_t length = std::get<uint16_t>(value);
421 int entryIndex = 0;
422 bool needSetAotFlag = (isLoadedAOT && (epos % pairSize == 0) && !flag);
423 if (needSetAotFlag) {
424 entryIndex = entryIndexes->GetObjectFromCache(pos++).GetInt();
425 // -1 : this jsfunction is a large function
426 if (entryIndex == -1) {
427 needSetAotFlag = false;
428 }
429 }
430 JSHandle<JSFunction> jsFunc =
431 DefineMethodInLiteral(thread, jsPandaFile, methodId, constpool, kind,
432 length, entry, needSetAotFlag, entryIndex);
433 jt = jsFunc.GetTaggedValue();
434 break;
435 }
436 case LiteralTag::ACCESSOR: {
437 JSHandle<AccessorData> accessor = factory->NewAccessorData();
438 jt = accessor.GetTaggedValue();
439 break;
440 }
441 case LiteralTag::NULLVALUE: {
442 break;
443 }
444 default: {
445 LOG_ECMA(FATAL) << "this branch is unreachable";
446 UNREACHABLE();
447 break;
448 }
449 }
450 if (tag != LiteralTag::METHOD && tag != LiteralTag::GETTER && tag != LiteralTag::SETTER &&
451 tag != LiteralTag::GENERATORMETHOD) {
452 if ((epos % pairSize == 0) && !flag) {
453 properties->Set(thread, ppos++, jt);
454 } else {
455 elements->Set(thread, epos++, jt);
456 }
457 }
458 });
459 }
460
GetDatasIgnoreType(JSThread * thread,const JSPandaFile * jsPandaFile,EntityId id,JSHandle<ConstantPool> constpool,const CString & entryPoint,bool isLoadedAOT,JSHandle<AOTLiteralInfo> entryIndexes,ElementsKind * newKind,ClassKind classKind)461 JSHandle<TaggedArray> LiteralDataExtractor::GetDatasIgnoreType(JSThread *thread, const JSPandaFile *jsPandaFile,
462 EntityId id, JSHandle<ConstantPool> constpool,
463 const CString &entryPoint, bool isLoadedAOT,
464 JSHandle<AOTLiteralInfo> entryIndexes,
465 ElementsKind *newKind, ClassKind classKind)
466 {
467 ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
468 LiteralDataAccessor lda = jsPandaFile->GetLiteralDataAccessor();
469 uint32_t num = lda.GetLiteralValsNum(id) / 2; // 2: half
470 JSHandle<TaggedArray> literals = JSHandle<TaggedArray>(factory->NewCOWTaggedArray(num));
471 uint32_t pos = 0;
472 uint32_t methodId = 0;
473 FunctionKind kind;
474 int index = 0;
475 lda.EnumerateLiteralVals(
476 id, [literals, &pos, factory, thread, jsPandaFile,
477 &methodId, &kind, &constpool, &entryPoint, &entryIndexes, &index, isLoadedAOT, newKind, classKind]
478 (const LiteralValue &value, const LiteralTag &tag) {
479 JSTaggedValue jt = JSTaggedValue::Null();
480 switch (tag) {
481 case LiteralTag::INTEGER: {
482 jt = JSTaggedValue(std::get<uint32_t>(value));
483 break;
484 }
485 case LiteralTag::DOUBLE: {
486 jt = JSTaggedValue(std::get<double>(value));
487 break;
488 }
489 case LiteralTag::BOOL: {
490 jt = JSTaggedValue(std::get<bool>(value));
491 break;
492 }
493 case LiteralTag::STRING: {
494 StringData sd = jsPandaFile->GetStringData(EntityId(std::get<uint32_t>(value)));
495 EcmaString *str = factory->GetRawStringFromStringTable(sd, MemSpaceType::OLD_SPACE);
496 jt = JSTaggedValue(str);
497 break;
498 }
499 case LiteralTag::METHOD: {
500 methodId = std::get<uint32_t>(value);
501 kind = FunctionKind::NORMAL_FUNCTION;
502 break;
503 }
504 case LiteralTag::GETTER: {
505 methodId = std::get<uint32_t>(value);
506 kind = FunctionKind::GETTER_FUNCTION;
507 break;
508 }
509 case LiteralTag::SETTER: {
510 methodId = std::get<uint32_t>(value);
511 kind = FunctionKind::SETTER_FUNCTION;
512 break;
513 }
514 case LiteralTag::GENERATORMETHOD: {
515 methodId = std::get<uint32_t>(value);
516 kind = FunctionKind::GENERATOR_FUNCTION;
517 break;
518 }
519 case LiteralTag::METHODAFFILIATE: {
520 uint16_t length = std::get<uint16_t>(value);
521 int entryIndex = 0;
522 bool needSetAotFlag = isLoadedAOT;
523 if (isLoadedAOT) {
524 entryIndex = entryIndexes->GetObjectFromCache(index++).GetInt();
525 if (entryIndex == -1) {
526 needSetAotFlag = false;
527 }
528 }
529 JSHandle<JSFunction> jsFunc =
530 DefineMethodInLiteral(thread, jsPandaFile, methodId, constpool,
531 kind, length, entryPoint, needSetAotFlag, entryIndex, classKind);
532 jt = jsFunc.GetTaggedValue();
533 break;
534 }
535 case LiteralTag::ACCESSOR: {
536 JSHandle<AccessorData> accessor = factory->NewAccessorData();
537 jt = accessor.GetTaggedValue();
538 break;
539 }
540 case LiteralTag::LITERALARRAY: {
541 jt = JSTaggedValue(std::get<uint32_t>(value));
542 break;
543 }
544 case LiteralTag::NULLVALUE: {
545 break;
546 }
547 default: {
548 LOG_ECMA(FATAL) << "this branch is unreachable";
549 UNREACHABLE();
550 break;
551 }
552 }
553 if (tag != LiteralTag::METHOD && tag != LiteralTag::GETTER && tag != LiteralTag::SETTER &&
554 tag != LiteralTag::GENERATORMETHOD) {
555 if (newKind != nullptr) {
556 *newKind = Elements::ToElementsKind(jt, *newKind);
557 }
558 literals->Set(thread, pos++, jt);
559 } else {
560 uint32_t oldLength = literals->GetLength();
561 literals->Trim(thread, oldLength - 1);
562 }
563 });
564 return literals;
565 }
566 } // namespace panda::ecmascript
567