• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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