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