• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 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 #ifndef ECMASCRIPT_ECMA_CONTEXT_H
16 #define ECMASCRIPT_ECMA_CONTEXT_H
17 
18 #include <cstdint>
19 #include <optional>
20 #include "ecmascript/base/aligned_struct.h"
21 #include "ecmascript/base/config.h"
22 #include "ecmascript/common.h"
23 #include "ecmascript/dfx/vmstat/opt_code_profiler.h"
24 #include "ecmascript/frames.h"
25 #include "ecmascript/ic/mega_ic_cache.h"
26 #include "ecmascript/js_handle.h"
27 #include "ecmascript/js_tagged_value.h"
28 #include "ecmascript/mem/c_containers.h"
29 #include "ecmascript/mem/visitor.h"
30 #include "ecmascript/module/js_module_execute_type.h"
31 #include "ecmascript/patch/patch_loader.h"
32 #include "ecmascript/stackmap/ark_stackmap.h"
33 #include "ecmascript/waiter_list.h"
34 #include "global_handle_collection.h"
35 #include "libpandafile/file.h"
36 
37 namespace panda {
38 class JSNApi;
39 namespace panda_file {
40 class File;
41 }  // namespace panda_file
42 
43 namespace ecmascript {
44 class AotConstantpoolPatcher;
45 class GlobalEnv;
46 class ObjectFactory;
47 class EcmaRuntimeStat;
48 class RegExpParserCache;
49 class JSPandaFileManager;
50 class JSPandaFile;
51 class ConstantPool;
52 class JSPromise;
53 class RegExpExecResultCache;
54 class EcmaHandleScope;
55 class SustainingJSHandleList;
56 class SustainingJSHandle;
57 enum class PromiseRejectionEvent : uint8_t;
58 
59 template<typename T>
60 class JSHandle;
61 class JSThread;
62 class JSFunction;
63 class JSPromise;
64 class JSTaggedValue;
65 class EcmaVM;
66 class ModuleManager;
67 class AOTFileManager;
68 class QuickFixManager;
69 class OptCodeProfiler;
70 class TypedOpProfiler;
71 class AbcBufferCache;
72 struct CJSInfo;
73 class FunctionProtoTransitionTable;
74 class ModuleLogger;
75 
76 namespace job {
77 class MicroJobQueue;
78 }  // namespace job
79 namespace tooling {
80 class JsDebuggerManager;
81 }  // namespace tooling
82 namespace kungfu {
83 class PGOTypeManager;
84 } // namespace kungfu
85 
86 using HostPromiseRejectionTracker = void (*)(const EcmaVM* vm,
87                                              const JSHandle<JSPromise> promise,
88                                              const JSHandle<JSTaggedValue> reason,
89                                              PromiseRejectionEvent operation,
90                                              void* data);
91 using PromiseRejectCallback = void (*)(void* info);
92 #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM)
93 using JsAotReaderCallback = std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)>;
94 #endif
95 class EcmaContext {
96 public:
97     enum JSErrorProps {
98         NAME,
99         MESSAGE,
100         STACK
101     };
102 
103     static EcmaContext *CreateAndInitialize(JSThread *thread);
104     static void CheckAndDestroy(JSThread *thread, EcmaContext *context);
105 
106     static EcmaContext *Create(JSThread *thread);
107     static bool Destroy(EcmaContext *context);
108 
109     EcmaContext(JSThread *thread);
110     ~EcmaContext();
111     struct EcmaData
112         : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
113                                      base::AlignedPointer,
114 #if ECMASCRIPT_ENABLE_MEGA_PROFILER
115                                      base::AlignedPointer,
116                                      base::AlignedUint64,
117                                      base::AlignedUint64,
118                                      base::AlignedUint64>
119 #else
120                                      base::AlignedPointer>
121 #endif
122                                      {
123         enum class Index : size_t {
124             LoadMegaICCacheIndex,
125             StoreMegaICCacheIndex,
126             PropertiesCacheIndex,
127 #if ECMASCRIPT_ENABLE_MEGA_PROFILER
128             megaUpdateCountIndex,
129             megaProbesCountIndex,
130             megaHitCountIndex,
131 #endif
132             NumOfMembers
133         };
134 #if ECMASCRIPT_ENABLE_MEGA_PROFILER
135         static_assert(static_cast<size_t>(Index::NumOfMembers) == 6);
136 #else
137         static_assert(static_cast<size_t>(Index::NumOfMembers) == 3);
138 #endif
GetLoadMegaICCacheOffsetEcmaData139         static size_t GetLoadMegaICCacheOffset(bool isArch32)
140         {
141             return GetOffset<static_cast<size_t>(Index::LoadMegaICCacheIndex)>(
142                 isArch32);
143         }
144 
GetStoreMegaICCacheOffsetEcmaData145         static size_t GetStoreMegaICCacheOffset(bool isArch32)
146         {
147             return GetOffset<static_cast<size_t>(Index::StoreMegaICCacheIndex)>(
148                 isArch32);
149         }
150 
GetPropertiesCacheOffsetEcmaData151         static size_t GetPropertiesCacheOffset(bool isArch32)
152         {
153             return GetOffset<static_cast<size_t>(Index::PropertiesCacheIndex)>(
154                 isArch32);
155         }
156 #if ECMASCRIPT_ENABLE_MEGA_PROFILER
GetMegaProbesCountOffsetEcmaData157         static size_t GetMegaProbesCountOffset(bool isArch32)
158         {
159             return GetOffset<static_cast<size_t>(Index::megaProbesCountIndex)>(
160                 isArch32);
161         }
162 
GetMegaHitCountOffsetEcmaData163         static size_t GetMegaHitCountOffset(bool isArch32)
164         {
165             return GetOffset<static_cast<size_t>(Index::megaHitCountIndex)>(
166                 isArch32);
167         }
168 #endif
169         alignas(EAS) MegaICCache *loadMegaICCache_{nullptr};
170         alignas(EAS) MegaICCache *storeMegaICCache_{nullptr};
171         alignas(EAS) PropertiesCache *propertiesCache_{nullptr};
172 #if ECMASCRIPT_ENABLE_MEGA_PROFILER
173         alignas(EAS) uint64_t megaUpdateCount_ {0};
174         alignas(EAS) uint64_t megaProbesCount_ {0};
175         alignas(EAS) uint64_t megaHitCount {0};
176 #endif
177     };
178 
GetEcmaVM()179     EcmaVM *GetEcmaVM() const
180     {
181         return vm_;
182     }
183 
184     bool Initialize();
185 
IsExecutingPendingJob()186     bool IsExecutingPendingJob() const
187     {
188         return isProcessingPendingJob_.load();
189     }
190 
191     bool HasPendingJob();
192 
193     bool ExecutePromisePendingJob();
194 
ConstCast(const EcmaContext * context)195     static EcmaContext *ConstCast(const EcmaContext *context)
196     {
197         return const_cast<EcmaContext *>(context);
198     }
199 
IsInitialized()200     bool IsInitialized() const
201     {
202         return initialized_;
203     }
204 
GetModuleManager()205     ModuleManager *GetModuleManager() const
206     {
207         return moduleManager_;
208     }
209 
GetAbcBufferCache()210     AbcBufferCache *GetAbcBufferCache() const
211     {
212         return abcBufferCache_;
213     }
214 
GetPTManager()215     kungfu::PGOTypeManager *GetPTManager() const
216     {
217         return ptManager_;
218     }
219 
GetJSThread()220     ARK_INLINE JSThread *GetJSThread() const
221     {
222         return thread_;
223     }
GetPromiseRejectCallback()224     PromiseRejectCallback GetPromiseRejectCallback() const
225     {
226         return promiseRejectCallback_;
227     }
228 
SetPromiseRejectCallback(PromiseRejectCallback cb)229     void SetPromiseRejectCallback(PromiseRejectCallback cb)
230     {
231         promiseRejectCallback_ = cb;
232     }
233 
SetData(void * data)234     void SetData(void* data)
235     {
236         data_ = data;
237     }
238 
PromiseRejectionTracker(const JSHandle<JSPromise> & promise,const JSHandle<JSTaggedValue> & reason,PromiseRejectionEvent operation)239     void PromiseRejectionTracker(const JSHandle<JSPromise> &promise,
240                                  const JSHandle<JSTaggedValue> &reason, PromiseRejectionEvent operation)
241     {
242         if (hostPromiseRejectionTracker_ != nullptr) {
243             hostPromiseRejectionTracker_(vm_, promise, reason, operation, data_);
244         }
245     }
246 
SetHostPromiseRejectionTracker(HostPromiseRejectionTracker cb)247     void SetHostPromiseRejectionTracker(HostPromiseRejectionTracker cb)
248     {
249         hostPromiseRejectionTracker_ = cb;
250     }
251     void SetupRegExpResultCache();
252     void SetupNumberToStringResultCache();
253     void SetupStringSplitResultCache();
254     void SetupStringToListResultCache();
GetRegExpCache()255     JSHandle<JSTaggedValue> GetRegExpCache() const
256     {
257         return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&regexpCache_));
258     }
259 
GetRegExpParserCache()260     RegExpParserCache *GetRegExpParserCache() const
261     {
262         ASSERT(regExpParserCache_ != nullptr);
263         return regExpParserCache_;
264     }
265 
SetRegExpCache(JSTaggedValue newCache)266     void SetRegExpCache(JSTaggedValue newCache)
267     {
268         regexpCache_ = newCache;
269     }
GetExpCacheAddress()270     uintptr_t GetExpCacheAddress()
271     {
272         return reinterpret_cast<uintptr_t>(&regexpCache_);
273     }
274 
275     void SetupRegExpGlobalResult();
276 
GetRegExpGlobalResult()277     JSHandle<JSTaggedValue> GetRegExpGlobalResult() const
278     {
279         return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&regexpGlobal_));
280     }
281 
SetRegExpGlobalResult(JSTaggedValue newResult)282     void SetRegExpGlobalResult(JSTaggedValue newResult)
283     {
284         regexpGlobal_ = newResult;
285     }
286 
GetWaiterListNode()287     WaiterListNode *GetWaiterListNode()
288     {
289         return &waiterListNode_;
290     }
291 
GetNumberToStringResultCache()292     JSHandle<JSTaggedValue> GetNumberToStringResultCache() const
293     {
294         return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&numberToStringResultCache_));
295     }
296 
SetNumberToStringResultCache(JSTaggedValue newCache)297     void SetNumberToStringResultCache(JSTaggedValue newCache)
298     {
299         numberToStringResultCache_ = newCache;
300     }
301 
GetStringSplitResultCache()302     JSHandle<JSTaggedValue> GetStringSplitResultCache() const
303     {
304         return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&stringSplitResultCache_));
305     }
306 
GetStringToListResultCache()307     JSHandle<JSTaggedValue> GetStringToListResultCache() const
308     {
309         return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&stringToListResultCache_));
310     }
311 
SetStringSplitResultCache(JSTaggedValue newCache)312     void SetStringSplitResultCache(JSTaggedValue newCache)
313     {
314         stringSplitResultCache_ = newCache;
315     }
316     JSHandle<ecmascript::JSTaggedValue> GetAndClearEcmaUncaughtException() const;
317     JSHandle<ecmascript::JSTaggedValue> GetEcmaUncaughtException() const;
318     void EnableUserUncaughtErrorHandler();
319 
320     JSHandle<ConstantPool> AddOrUpdateConstpool(const JSPandaFile *jsPandaFile,
321                                                 JSHandle<ConstantPool> constpool,
322                                                 int32_t index = 0);
323     void AddContextConstpoolCache(const JSPandaFile *jsPandaFile,
324                                   JSHandle<ConstantPool> constpool,
325                                   int32_t index);
326 
327     void UpdateConstpoolWhenDeserialAI(const std::string& fileName,
328                                        JSHandle<ConstantPool> aiCP,
329                                        int32_t index = 0);
330 
331     bool HasCachedConstpool(const JSPandaFile *jsPandaFile) const;
332 
333     void SetUnsharedConstpool(JSHandle<ConstantPool> sharedConstpool, JSTaggedValue unsharedConstpool);
334     void SetUnsharedConstpool(int32_t constpoolIndex, JSTaggedValue unsharedConstpool);
335 
336     JSTaggedValue PUBLIC_API FindConstpool(const JSPandaFile *jsPandaFile, int32_t index);
337     // For new version instruction.
338     JSTaggedValue PUBLIC_API FindConstpool(const JSPandaFile *jsPandaFile, panda_file::File::EntityId id);
339     JSTaggedValue PUBLIC_API FindOrCreateUnsharedConstpool(JSTaggedValue sharedConstpool);
340     JSTaggedValue PUBLIC_API FindUnsharedConstpool(JSTaggedValue sharedConstpool);
341     void PUBLIC_API LoadProtoTransitionTable(JSTaggedValue constpool);
342     void PUBLIC_API ResetProtoTransitionTableOnConstpool(JSTaggedValue constpool);
343     JSTaggedValue FindCachedConstpoolAndLoadAiIfNeeded(const JSPandaFile *jsPandaFile, int32_t index);
344     void EraseUnusedConstpool(const JSPandaFile *jsPandaFile, int32_t index, int32_t constpoolIndex);
345     std::optional<std::reference_wrapper<CMap<int32_t, JSTaggedValue>>> FindConstpools(
346         const JSPandaFile *jsPandaFile);
347 
348     JSHandle<ConstantPool> PUBLIC_API FindOrCreateConstPool(const JSPandaFile *jsPandaFile,
349                                                             panda_file::File::EntityId id);
350     void SetPrototypeForTransitions(JSTaggedValue trans, JSTaggedValue proto);
351     void SetObjectFunctionFromConstPool(JSHandle<ConstantPool> newConstPool);
352     void CreateAllConstpool(const JSPandaFile *jsPandaFile);
353 
354     void HandleUncaughtException(JSTaggedValue exception);
355     void HandleUncaughtException();
356     JSHandle<GlobalEnv> GetGlobalEnv() const;
GlobalEnvIsHole()357     bool GlobalEnvIsHole()
358     {
359         return globalEnv_.IsHole();
360     }
361 
362     JSHandle<job::MicroJobQueue> GetMicroJobQueue() const;
363 
364     static void PrintJSErrorInfo(JSThread *thread, const JSHandle<JSTaggedValue> &exceptionInfo);
365     static CString GetJSErrorInfo(JSThread *thread, const JSHandle<JSTaggedValue> exceptionInfo, JSErrorProps key);
366     void IterateMegaIC(RootVisitor &v);
367     void Iterate(RootVisitor &v);
368     static void MountContext(JSThread *thread);
369     static void UnmountContext(JSThread *thread);
370     void SetMicroJobQueue(job::MicroJobQueue *queue);
371     void SetGlobalEnv(GlobalEnv *global);
372     void PrintOptStat();
373 
GetOptCodeProfiler()374     OptCodeProfiler *GetOptCodeProfiler() const
375     {
376         return optCodeProfiler_;
377     }
378 
GetTypdOpProfiler()379     TypedOpProfiler *GetTypdOpProfiler() const
380     {
381         return typedOpProfiler_;
382     }
383 
GetModuleLogger()384     ModuleLogger *GetModuleLogger() const
385     {
386         return moduleLogger_;
387     }
388 
SetModuleLogger(ModuleLogger * moduleLogger)389     void SetModuleLogger(ModuleLogger *moduleLogger)
390     {
391         moduleLogger_ = moduleLogger;
392     }
393 
GetFunctionProtoTransitionTable()394     FunctionProtoTransitionTable *GetFunctionProtoTransitionTable() const
395     {
396         return functionProtoTransitionTable_;
397     }
398 
399     void DumpAOTInfo() const DUMP_API_ATTR;
400 
401     JSTaggedValue ExecuteAot(size_t actualNumArgs, JSTaggedType *args, const JSTaggedType *prevFp,
402                              bool needPushArgv);
403     void LoadStubFile();
404 
GetHandleScopeStorageNext()405     JSTaggedType *GetHandleScopeStorageNext() const
406     {
407         return handleScopeStorageNext_;
408     }
409 
SetHandleScopeStorageNext(JSTaggedType * value)410     void SetHandleScopeStorageNext(JSTaggedType *value)
411     {
412         handleScopeStorageNext_ = value;
413     }
414 
GetHandleScopeStorageEnd()415     JSTaggedType *GetHandleScopeStorageEnd() const
416     {
417         return handleScopeStorageEnd_;
418     }
419 
SetHandleScopeStorageEnd(JSTaggedType * value)420     void SetHandleScopeStorageEnd(JSTaggedType *value)
421     {
422         handleScopeStorageEnd_ = value;
423     }
424 
GetCurrentHandleStorageIndex()425     int GetCurrentHandleStorageIndex() const
426     {
427         return currentHandleStorageIndex_;
428     }
429 
GetPrimitiveScopeStorageNext()430     JSTaggedType *GetPrimitiveScopeStorageNext() const
431     {
432         return primitiveScopeStorageNext_;
433     }
434 
SetPrimitiveScopeStorageNext(JSTaggedType * value)435     void SetPrimitiveScopeStorageNext(JSTaggedType *value)
436     {
437         primitiveScopeStorageNext_ = value;
438     }
439 
GetPrimitiveScopeStorageEnd()440     JSTaggedType *GetPrimitiveScopeStorageEnd() const
441     {
442         return primitiveScopeStorageEnd_;
443     }
444 
SetPrimitiveScopeStorageEnd(JSTaggedType * value)445     void SetPrimitiveScopeStorageEnd(JSTaggedType *value)
446     {
447         primitiveScopeStorageEnd_ = value;
448     }
449 
GetCurrentPrimitiveStorageIndex()450     int GetCurrentPrimitiveStorageIndex() const
451     {
452         return currentPrimitiveStorageIndex_;
453     }
454 
455     size_t IterateHandle(RootVisitor &visitor);
456     uintptr_t *ExpandHandleStorage();
457     void ShrinkHandleStorage(int prevIndex);
458     uintptr_t *ExpandPrimitiveStorage();
459     void ShrinkPrimitiveStorage(int prevIndex);
460 
GetPropertiesCache()461     PropertiesCache *GetPropertiesCache() const
462     {
463         return ecmaData_.propertiesCache_;
464     }
465 
GetLoadMegaICCache()466     MegaICCache *GetLoadMegaICCache() const
467     {
468         return ecmaData_.loadMegaICCache_;
469     }
470 
GetStoreMegaICCache()471     MegaICCache *GetStoreMegaICCache() const
472     {
473         return ecmaData_.storeMegaICCache_;
474     }
475 #if ECMASCRIPT_ENABLE_MEGA_PROFILER
GetMegaProbeCount()476     uint64_t GetMegaProbeCount() const
477     {
478         return ecmaData_.megaProbesCount_;
479     }
480 
GetMegaHitCount()481     uint64_t GetMegaHitCount() const
482     {
483         return ecmaData_.megaHitCount;
484     }
485 
GetMegaUpdateCount()486     uint64_t GetMegaUpdateCount() const
487     {
488         return ecmaData_.megaUpdateCount_;
489     }
490 
IncMegaUpdateCount()491     void IncMegaUpdateCount()
492     {
493         ecmaData_.megaUpdateCount_++;
494     }
495 
ClearMegaStat()496     void ClearMegaStat()
497     {
498         ecmaData_.megaHitCount = 0;
499         ecmaData_.megaProbesCount_ = 0;
500         ecmaData_.megaUpdateCount_ = 0;
501     }
PrintMegaICStat()502     void PrintMegaICStat()
503     {
504         const int precision = 2;
505         const double percent = 100.0;
506         LOG_ECMA(INFO)
507             << "------------------------------------------------------------"
508             << "---------------------------------------------------------";
509         LOG_ECMA(INFO) << "MegaUpdateCount: " << GetMegaUpdateCount();
510         LOG_ECMA(INFO) << "MegaHitCount: " << GetMegaHitCount();
511         LOG_ECMA(INFO) << "MegaProbeCount: " << GetMegaProbeCount();
512         LOG_ECMA(INFO) << "MegaHitRate: " << std::fixed
513                        << std::setprecision(precision)
514                        << (GetMegaProbeCount() > 0
515                                ? static_cast<double>(GetMegaHitCount()) /
516                                      GetMegaProbeCount() * percent
517                                : 0.0)
518                        << "%";
519         LOG_ECMA(INFO)
520             << "------------------------------------------------------------"
521             << "---------------------------------------------------------";
522         ClearMegaStat();
523     }
524 #endif
525     void ClearBufferData();
GlobalConstants()526     const GlobalEnvConstants *GlobalConstants() const
527     {
528         return &globalConst_;
529     }
530 
AddPatchModule(const CString & recordName,const JSHandle<JSTaggedValue> moduleRecord)531     void AddPatchModule(const CString &recordName, const JSHandle<JSTaggedValue> moduleRecord)
532     {
533         cachedPatchModules_.emplace(recordName, moduleRecord);
534     }
FindPatchModule(const CString & recordName)535     JSHandle<JSTaggedValue> FindPatchModule(const CString &recordName) const
536     {
537         auto iter = cachedPatchModules_.find(recordName);
538         if (iter != cachedPatchModules_.end()) {
539             return iter->second;
540         }
541         return JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Hole());
542     }
ClearPatchModules()543     void ClearPatchModules()
544     {
545         GlobalHandleCollection gloalHandleCollection(thread_);
546         for (auto &item : cachedPatchModules_) {
547             gloalHandleCollection.Dispose(item.second);
548         }
549         cachedPatchModules_.clear();
550     }
551 
GetStageOfHotReload()552     StageOfHotReload GetStageOfHotReload() const
553     {
554         return stageOfHotReload_;
555     }
SetStageOfHotReload(StageOfHotReload stageOfHotReload)556     void SetStageOfHotReload(StageOfHotReload stageOfHotReload)
557     {
558         stageOfHotReload_ = stageOfHotReload;
559     }
560 
GetStageOfColdReload()561     StageOfColdReload GetStageOfColdReload() const
562     {
563         return stageOfColdReload_;
564     }
SetStageOfColdReload(StageOfColdReload stageOfColdReload)565     void SetStageOfColdReload(StageOfColdReload stageOfColdReload)
566     {
567         stageOfColdReload_ = stageOfColdReload;
568     }
569 
570     bool JoinStackPushFastPath(JSHandle<JSTaggedValue> receiver);
571     bool JoinStackPush(JSHandle<JSTaggedValue> receiver);
572     void JoinStackPopFastPath(JSHandle<JSTaggedValue> receiver);
573     void JoinStackPop(JSHandle<JSTaggedValue> receiver);
574 
575     std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> CalCallSiteInfo(uintptr_t retAddr,
576                                                                                         bool isDeopt) const;
577 
578     void AddSustainingJSHandle(SustainingJSHandle*);
579     void RemoveSustainingJSHandle(SustainingJSHandle*);
580     void ClearKeptObjects();
581     void AddToKeptObjects(JSHandle<JSTaggedValue> value);
582 
ClearCachedConstantPool()583     void ClearCachedConstantPool()
584     {
585         cachedSharedConstpools_.clear();
586     }
587 
588 private:
589     void CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &thisArg,
590                       const JSPandaFile *jsPandaFile, std::string_view entryPoint);
591     JSTaggedValue InvokeEcmaAotEntrypoint(JSHandle<JSFunction> mainFunc, JSHandle<JSTaggedValue> &thisArg,
592                                           const JSPandaFile *jsPandaFile, std::string_view entryPoint,
593                                           CJSInfo *cjsInfo = nullptr);
594     Expected<JSTaggedValue, bool> InvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile, std::string_view entryPoint,
595                                                        const ExecuteTypes &executeType = ExecuteTypes::STATIC);
596     Expected<JSTaggedValue, bool> InvokeEcmaEntrypointForHotReload(
597         const JSPandaFile *jsPandaFile, std::string_view entryPoint, const ExecuteTypes &executeType);
598     Expected<JSTaggedValue, bool> CommonInvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile,
599         std::string_view entryPoint, JSHandle<JSFunction> &func, const ExecuteTypes &executeType);
600     bool LoadAOTFilesInternal(const std::string& aotFileName);
601     bool LoadAOTFiles(const std::string &aotFileName);
602 #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM)
603     bool LoadAOTFiles(const std::string &aotFileName,
604                       std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)> cb);
605 #endif
606     void RelocateConstantString(const JSPandaFile *jsPandaFile);
607     JSTaggedValue FindConstpoolFromContextCache(const JSPandaFile *jsPandaFile, int32_t index);
608 
609     void GrowUnsharedConstpoolArray(int32_t index);
610     void ResizeUnsharedConstpoolArray(int32_t oldCapacity, int32_t minCapacity);
ClearUnsharedConstpoolArray()611     void ClearUnsharedConstpoolArray()
612     {
613         if (unsharedConstpools_ != nullptr) {
614             delete[] unsharedConstpools_;
615             unsharedConstpools_ = nullptr;
616             thread_->SetUnsharedConstpools(reinterpret_cast<uintptr_t>(nullptr));
617             thread_->SetUnsharedConstpoolsArrayLen(0);
618         }
619     }
620 
GetUnsharedConstpoolsArrayLen()621     int32_t GetUnsharedConstpoolsArrayLen() const
622     {
623         return unsharedConstpoolsArrayLen_;
624     }
625 
SetUnsharedConstpoolsArrayLen(int32_t len)626     void SetUnsharedConstpoolsArrayLen(int32_t len)
627     {
628         unsharedConstpoolsArrayLen_ = len;
629     }
630 
631     NO_MOVE_SEMANTIC(EcmaContext);
632     NO_COPY_SEMANTIC(EcmaContext);
633     EcmaData ecmaData_;
634     JSThread *thread_{nullptr};
635     EcmaVM *vm_{nullptr};
636 
637     bool isUncaughtExceptionRegistered_ {false};
638     bool initialized_ {false};
639     std::atomic<bool> isProcessingPendingJob_ {false};
640     ObjectFactory *factory_ {nullptr};
641 
642     // VM execution states.
643     RegExpParserCache *regExpParserCache_ {nullptr};
644     JSTaggedValue numberToStringResultCache_ {JSTaggedValue::Hole()};
645     JSTaggedValue stringSplitResultCache_ {JSTaggedValue::Hole()};
646     JSTaggedValue stringToListResultCache_ {JSTaggedValue::Hole()};
647     JSTaggedValue globalEnv_ {JSTaggedValue::Hole()};
648     JSTaggedValue regexpCache_ {JSTaggedValue::Hole()};
649     JSTaggedValue regexpGlobal_ {JSTaggedValue::Hole()};
650     JSTaggedValue microJobQueue_ {JSTaggedValue::Hole()};
651 
652     CMap<const JSPandaFile *, CMap<int32_t, JSTaggedValue>> cachedSharedConstpools_ {};
653     JSTaggedValue* unsharedConstpools_ = nullptr;
654     int32_t unsharedConstpoolsArrayLen_ = UNSHARED_CONSTANTPOOL_COUNT;
655     static constexpr int32_t SHARED_CONSTPOOL_KEY_NOT_FOUND = INT32_MAX; // INT32_MAX :invalid value.
656 
657     // for HotReload of module.
658     CMap<CString, JSHandle<JSTaggedValue>> cachedPatchModules_ {};
659     StageOfHotReload stageOfHotReload_ = StageOfHotReload::INITIALIZE_STAGE_OF_HOTRELOAD;
660     StageOfColdReload stageOfColdReload_ = StageOfColdReload::NOT_COLD_RELOAD;
661 
662     // VM resources.
663     ModuleManager *moduleManager_ {nullptr};
664     kungfu::PGOTypeManager *ptManager_ {nullptr};
665     AOTFileManager *aotFileManager_ {nullptr};
666     AbcBufferCache *abcBufferCache_ {nullptr};
667 
668     // for recording the transition of function prototype
669     FunctionProtoTransitionTable *functionProtoTransitionTable_ {nullptr};
670 
671     // atomics
672     WaiterListNode waiterListNode_;
673 
674     // Registered Callbacks
675     PromiseRejectCallback promiseRejectCallback_ {nullptr};
676     HostPromiseRejectionTracker hostPromiseRejectionTracker_ {nullptr};
677     void* data_{nullptr};
678 
679     // opt code Profiler
680     OptCodeProfiler *optCodeProfiler_ {nullptr};
681 
682     // opt code loop hoist
683     TypedOpProfiler *typedOpProfiler_ {nullptr};
684 
685     ModuleLogger *moduleLogger_ {nullptr};
686 
687     // Handlescope
688     static const uint32_t NODE_BLOCK_SIZE_LOG2 = 10;
689     static const uint32_t NODE_BLOCK_SIZE = 1U << NODE_BLOCK_SIZE_LOG2;
690     static constexpr int32_t MIN_HANDLE_STORAGE_SIZE = 2;
691     JSTaggedType *handleScopeStorageNext_ {nullptr};
692     JSTaggedType *handleScopeStorageEnd_ {nullptr};
693     std::vector<std::array<JSTaggedType, NODE_BLOCK_SIZE> *> handleStorageNodes_ {};
694     int32_t currentHandleStorageIndex_ {-1};
695     // PrimitveScope
696     static constexpr int32_t MIN_PRIMITIVE_STORAGE_SIZE = 2;
697     JSTaggedType *primitiveScopeStorageNext_ {nullptr};
698     JSTaggedType *primitiveScopeStorageEnd_ {nullptr};
699     std::vector<std::array<JSTaggedType, NODE_BLOCK_SIZE> *> primitiveStorageNodes_ {};
700     int32_t currentPrimitiveStorageIndex_ {-1};
701 
702     GlobalEnvConstants globalConst_;
703     // Join Stack
704     static constexpr uint32_t MIN_JOIN_STACK_SIZE = 2;
705     CVector<JSTaggedValue> joinStack_ {JSTaggedValue::Hole(), JSTaggedValue::Hole()};
706 
707     // SustainingJSHandleList for jit compile hold ref
708     SustainingJSHandleList *sustainingJSHandleList_ {nullptr};
709 
710     friend class EcmaHandleScope;
711     friend class JSPandaFileExecutor;
712     friend class ObjectFactory;
713     friend class panda::JSNApi;
714     friend class AOTFileManager;
715 };
716 }  // namespace ecmascript
717 }  // namespace panda
718 #endif // ECMASCRIPT_ECMA_CONTEXT_H
719