• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <optional>
19 #include "ecmascript/base/config.h"
20 #include "ecmascript/common.h"
21 #include "ecmascript/dfx/vmstat/opt_code_profiler.h"
22 #include "ecmascript/frames.h"
23 #include "ecmascript/js_handle.h"
24 #include "ecmascript/js_tagged_value.h"
25 #include "ecmascript/mem/c_containers.h"
26 #include "ecmascript/mem/visitor.h"
27 #include "ecmascript/patch/patch_loader.h"
28 #include "ecmascript/regexp/regexp_parser_cache.h"
29 #include "ecmascript/waiter_list.h"
30 #include "global_handle_collection.h"
31 #include "libpandafile/file.h"
32 
33 namespace panda {
34 class JSNApi;
35 namespace panda_file {
36 class File;
37 }  // namespace panda_file
38 
39 namespace ecmascript {
40 class GlobalEnv;
41 class ObjectFactory;
42 class EcmaRuntimeStat;
43 class RegExpParserCache;
44 class JSPandaFileManager;
45 class JSPandaFile;
46 class ConstantPool;
47 class JSPromise;
48 class RegExpExecResultCache;
49 class EcmaHandleScope;
50 class GlobalIndexMap;
51 enum class PromiseRejectionEvent : uint8_t;
52 
53 template<typename T>
54 class JSHandle;
55 class JSThread;
56 class JSFunction;
57 class JSPromise;
58 class JSTaggedValue;
59 class EcmaVM;
60 class ModuleManager;
61 class TSManager;
62 class AOTFileManager;
63 class QuickFixManager;
64 class OptCodeProfiler;
65 struct CJSInfo;
66 
67 namespace job {
68 class MicroJobQueue;
69 }  // namespace job
70 namespace tooling {
71 class JsDebuggerManager;
72 }  // namespace tooling
73 namespace kungfu {
74 class PGOTypeManager;
75 } // namespace kungfu
76 
77 enum class IcuFormatterType {
78     SIMPLE_DATE_FORMAT_DEFAULT,
79     SIMPLE_DATE_FORMAT_DATE,
80     SIMPLE_DATE_FORMAT_TIME,
81     NUMBER_FORMATTER,
82     COLLATOR,
83     ICU_FORMATTER_TYPE_COUNT
84 };
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 using IcuDeleteEntry = void(*)(void *pointer, void *data);
93 class EcmaContext {
94 public:
95     static EcmaContext *CreateAndInitialize(JSThread *thread);
96     static void CheckAndDestroy(JSThread *thread, EcmaContext *context);
97 
98     static EcmaContext *Create(JSThread *thread);
99     static bool Destroy(EcmaContext *context);
100 
101     EcmaContext(JSThread *thread);
102     ~EcmaContext();
103 
GetEcmaVM()104     EcmaVM *GetEcmaVM() const
105     {
106         return vm_;
107     }
108 
109     bool Initialize();
110 
IsExecutingPendingJob()111     bool IsExecutingPendingJob() const
112     {
113         return isProcessingPendingJob_.load();
114     }
115 
116     bool HasPendingJob();
117 
118     bool ExecutePromisePendingJob();
119 
ConstCast(const EcmaContext * context)120     static EcmaContext *ConstCast(const EcmaContext *context)
121     {
122         return const_cast<EcmaContext *>(context);
123     }
124 
IsInitialized()125     bool IsInitialized() const
126     {
127         return initialized_;
128     }
129 
GetModuleManager()130     ModuleManager *GetModuleManager() const
131     {
132         return moduleManager_;
133     }
134 
GetTSManager()135     TSManager *GetTSManager() const
136     {
137         return tsManager_;
138     }
139 
GetPTManager()140     kungfu::PGOTypeManager *GetPTManager() const
141     {
142         return ptManager_;
143     }
144 
145     void SetTSManager(TSManager *set);
146 
GetJSThread()147     ARK_INLINE JSThread *GetJSThread() const
148     {
149         return thread_;
150     }
GetPromiseRejectCallback()151     PromiseRejectCallback GetPromiseRejectCallback() const
152     {
153         return promiseRejectCallback_;
154     }
155 
SetPromiseRejectCallback(PromiseRejectCallback cb)156     void SetPromiseRejectCallback(PromiseRejectCallback cb)
157     {
158         promiseRejectCallback_ = cb;
159     }
160 
SetData(void * data)161     void SetData(void* data)
162     {
163         data_ = data;
164     }
165 
PromiseRejectionTracker(const JSHandle<JSPromise> & promise,const JSHandle<JSTaggedValue> & reason,PromiseRejectionEvent operation)166     void PromiseRejectionTracker(const JSHandle<JSPromise> &promise,
167                                  const JSHandle<JSTaggedValue> &reason, PromiseRejectionEvent operation)
168     {
169         if (hostPromiseRejectionTracker_ != nullptr) {
170             hostPromiseRejectionTracker_(vm_, promise, reason, operation, data_);
171         }
172     }
173 
SetHostPromiseRejectionTracker(HostPromiseRejectionTracker cb)174     void SetHostPromiseRejectionTracker(HostPromiseRejectionTracker cb)
175     {
176         hostPromiseRejectionTracker_ = cb;
177     }
178     void SetupRegExpResultCache();
179     void SetupNumberToStringResultCache();
180     void SetupStringSplitResultCache();
181     void SetupStringToListResultCache();
GetRegExpCache()182     JSHandle<JSTaggedValue> GetRegExpCache() const
183     {
184         return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&regexpCache_));
185     }
186 
GetRegExpParserCache()187     RegExpParserCache *GetRegExpParserCache() const
188     {
189         ASSERT(regExpParserCache_ != nullptr);
190         return regExpParserCache_;
191     }
192 
SetRegExpCache(JSTaggedValue newCache)193     void SetRegExpCache(JSTaggedValue newCache)
194     {
195         regexpCache_ = newCache;
196     }
GetExpCacheAddress()197     uintptr_t GetExpCacheAddress()
198     {
199         return reinterpret_cast<uintptr_t>(&regexpCache_);
200     }
201 
202     void SetupRegExpGlobalResult();
203 
GetRegExpGlobalResult()204     JSHandle<JSTaggedValue> GetRegExpGlobalResult() const
205     {
206         return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&regexpGlobal_));
207     }
208 
SetRegExpGlobalResult(JSTaggedValue newResult)209     void SetRegExpGlobalResult(JSTaggedValue newResult)
210     {
211         regexpGlobal_ = newResult;
212     }
213 
GetWaiterListNode()214     WaiterListNode *GetWaiterListNode()
215     {
216         return &waiterListNode_;
217     }
218 
SetAllowAtomicWait(bool wait)219     void SetAllowAtomicWait(bool wait)
220     {
221         AllowAtomicWait_ = wait;
222     }
223 
GetAllowAtomicWait()224     bool GetAllowAtomicWait() const
225     {
226         return AllowAtomicWait_;
227     }
GetNumberToStringResultCache()228     JSHandle<JSTaggedValue> GetNumberToStringResultCache() const
229     {
230         return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&numberToStringResultCache_));
231     }
232 
SetNumberToStringResultCache(JSTaggedValue newCache)233     void SetNumberToStringResultCache(JSTaggedValue newCache)
234     {
235         numberToStringResultCache_ = newCache;
236     }
237 
GetStringSplitResultCache()238     JSHandle<JSTaggedValue> GetStringSplitResultCache() const
239     {
240         return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&stringSplitResultCache_));
241     }
242 
GetStringToListResultCache()243     JSHandle<JSTaggedValue> GetStringToListResultCache() const
244     {
245         return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&stringToListResultCache_));
246     }
247 
SetStringSplitResultCache(JSTaggedValue newCache)248     void SetStringSplitResultCache(JSTaggedValue newCache)
249     {
250         stringSplitResultCache_ = newCache;
251     }
252     JSHandle<ecmascript::JSTaggedValue> GetAndClearEcmaUncaughtException() const;
253     JSHandle<ecmascript::JSTaggedValue> GetEcmaUncaughtException() const;
254     void EnableUserUncaughtErrorHandler();
255 
256     void AddConstpool(const JSPandaFile *jsPandaFile, JSTaggedValue constpool, int32_t index = 0);
257 
258     bool HasCachedConstpool(const JSPandaFile *jsPandaFile) const;
259 
260     JSTaggedValue FindConstpool(const JSPandaFile *jsPandaFile, int32_t index);
261     // For new version instruction.
262     JSTaggedValue FindConstpool(const JSPandaFile *jsPandaFile, panda_file::File::EntityId id);
263     JSTaggedValue FindConstpoolWithAOT(const JSPandaFile *jsPandaFile, int32_t index);
264     std::optional<std::reference_wrapper<CMap<int32_t, JSTaggedValue>>> FindConstpools(
265         const JSPandaFile *jsPandaFile);
266 
267     JSHandle<ConstantPool> PUBLIC_API FindOrCreateConstPool(const JSPandaFile *jsPandaFile,
268                                                             panda_file::File::EntityId id);
269     void CreateAllConstpool(const JSPandaFile *jsPandaFile);
270 
271     void HandleUncaughtException(JSTaggedValue exception);
272     void ProcessNativeDelete(const WeakRootVisitor &visitor);
273     void ProcessReferences(const WeakRootVisitor &visitor);
274     JSHandle<GlobalEnv> GetGlobalEnv() const;
GlobalEnvIsHole()275     bool GlobalEnvIsHole()
276     {
277         return globalEnv_.IsHole();
278     }
279 
280     JSHandle<job::MicroJobQueue> GetMicroJobQueue() const;
281 
282     static void PrintJSErrorInfo(JSThread *thread, const JSHandle<JSTaggedValue> &exceptionInfo);
283     void Iterate(const RootVisitor &v, const RootRangeVisitor &rv);
284     static void MountContext(JSThread *thread);
285     static void UnmountContext(JSThread *thread);
286     void SetMicroJobQueue(job::MicroJobQueue *queue);
287     void SetGlobalEnv(GlobalEnv *global);
288     void PrintOptStat();
289 
GetOptCodeProfiler()290     OptCodeProfiler *GetOptCodeProfiler() const
291     {
292         return optCodeProfiler_;
293     }
294 
GetTypdOpProfiler()295     TypedOpProfiler *GetTypdOpProfiler() const
296     {
297         return typedOpProfiler_;
298     }
299 
300     // For icu objects cache
301     void SetIcuFormatterToCache(IcuFormatterType type, const std::string &locale, void *icuObj,
302                                 IcuDeleteEntry deleteEntry = nullptr)
303     {
304         EcmaContext::IcuFormatter icuFormatter = IcuFormatter(locale, icuObj, deleteEntry);
305         icuObjCache_[static_cast<int>(type)] = icuFormatter;
306     }
307 
GetIcuFormatterFromCache(IcuFormatterType type,std::string & locale)308     ARK_INLINE void *GetIcuFormatterFromCache(IcuFormatterType type, std::string &locale)
309     {
310         auto &icuFormatter = icuObjCache_[static_cast<int>(type)];
311         if (icuFormatter.locale == locale) {
312             return icuFormatter.icuObj;
313         }
314         return nullptr;
315     }
316 
ClearIcuCache()317     void ClearIcuCache()
318     {
319         for (uint32_t i = 0; i < static_cast<uint32_t>(IcuFormatterType::ICU_FORMATTER_TYPE_COUNT); i++) {
320             auto &icuFormatter = icuObjCache_[i];
321             IcuDeleteEntry deleteEntry = icuFormatter.deleteEntry;
322             if (deleteEntry != nullptr) {
323                 deleteEntry(icuFormatter.icuObj, vm_);
324             }
325             icuFormatter = EcmaContext::IcuFormatter{};
326         }
327     }
328 
GetAOTFileManager()329     AOTFileManager *GetAOTFileManager() const
330     {
331         return aotFileManager_;
332     }
333 
GetRuntimeStat()334     EcmaRuntimeStat *GetRuntimeStat() const
335     {
336         return runtimeStat_;
337     }
338 
339     void SetRuntimeStatEnable(bool flag);
340     void InitializeEcmaScriptRunStat();
341     void DumpAOTInfo() const DUMP_API_ATTR;
342 
343     JSTaggedValue ExecuteAot(size_t actualNumArgs, JSTaggedType *args, const JSTaggedType *prevFp,
344                              bool needPushUndefined);
345     void LoadStubFile();
346 
GetHandleScopeStorageNext()347     JSTaggedType *GetHandleScopeStorageNext() const
348     {
349         return handleScopeStorageNext_;
350     }
351 
SetHandleScopeStorageNext(JSTaggedType * value)352     void SetHandleScopeStorageNext(JSTaggedType *value)
353     {
354         handleScopeStorageNext_ = value;
355     }
356 
GetHandleScopeStorageEnd()357     JSTaggedType *GetHandleScopeStorageEnd() const
358     {
359         return handleScopeStorageEnd_;
360     }
361 
SetHandleScopeStorageEnd(JSTaggedType * value)362     void SetHandleScopeStorageEnd(JSTaggedType *value)
363     {
364         handleScopeStorageEnd_ = value;
365     }
366 
GetCurrentHandleStorageIndex()367     int GetCurrentHandleStorageIndex() const
368     {
369         return currentHandleStorageIndex_;
370     }
371 
HandleScopeCountAdd()372     void HandleScopeCountAdd()
373     {
374         handleScopeCount_++;
375     }
376 
HandleScopeCountDec()377     void HandleScopeCountDec()
378     {
379         handleScopeCount_--;
380     }
381 
SetLastHandleScope(EcmaHandleScope * scope)382     void SetLastHandleScope(EcmaHandleScope *scope)
383     {
384         lastHandleScope_ = scope;
385     }
386 
GetLastHandleScope()387     EcmaHandleScope *GetLastHandleScope() const
388     {
389         return lastHandleScope_;
390     }
391 
392     size_t IterateHandle(const RootRangeVisitor &rangeVisitor);
393     uintptr_t *ExpandHandleStorage();
394     void ShrinkHandleStorage(int prevIndex);
395 
GetCurrentFrame()396     JSTaggedType *GetCurrentFrame() const
397     {
398         return currentFrame_;
399     }
400 
GetLeaveFrame()401     JSTaggedType *GetLeaveFrame() const
402     {
403         return leaveFrame_;
404     }
405 
GetLastFp()406     JSTaggedType *GetLastFp() const
407     {
408         return lastFp_;
409     }
410 
SetFramePointers(JSTaggedType * currentFrame,JSTaggedType * leaveFrame,JSTaggedType * lastFp)411     void SetFramePointers(JSTaggedType *currentFrame, JSTaggedType *leaveFrame, JSTaggedType *lastFp)
412     {
413         currentFrame_ = currentFrame;
414         leaveFrame_ = leaveFrame;
415         lastFp_ = lastFp;
416     }
SetFrameBase(JSTaggedType * frameBase)417     void SetFrameBase(JSTaggedType *frameBase)
418     {
419         frameBase_ = frameBase;
420     }
GetFrameBase()421     JSTaggedType *GetFrameBase() const
422     {
423         return frameBase_;
424     }
425 
SetStackStart(uint64_t stackStart)426     void SetStackStart(uint64_t stackStart)
427     {
428         stackStart_ = stackStart;
429     }
GetStackStart()430     uint64_t GetStackStart() const
431     {
432         return stackStart_;
433     }
SetStackLimit(uint64_t stackLimit)434     void SetStackLimit(uint64_t stackLimit)
435     {
436         stackLimit_ = stackLimit;
437     }
GetStackLimit()438     uint64_t GetStackLimit() const
439     {
440         return stackLimit_;
441     }
442 
GetPropertiesCache()443     PropertiesCache *GetPropertiesCache() const
444     {
445         return propertiesCache_;
446     }
447     void ClearBufferData();
GlobalConstants()448     const GlobalEnvConstants *GlobalConstants() const
449     {
450         return &globalConst_;
451     }
452 
AddPatchModule(const CString & recordName,const JSHandle<JSTaggedValue> moduleRecord)453     void AddPatchModule(const CString &recordName, const JSHandle<JSTaggedValue> moduleRecord)
454     {
455         cachedPatchModules_.emplace(recordName, moduleRecord);
456     }
FindPatchModule(const CString & recordName)457     JSHandle<JSTaggedValue> FindPatchModule(const CString &recordName) const
458     {
459         auto iter = cachedPatchModules_.find(recordName);
460         if (iter != cachedPatchModules_.end()) {
461             return iter->second;
462         }
463         return JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Hole());
464     }
ClearPatchModules()465     void ClearPatchModules()
466     {
467         GlobalHandleCollection gloalHandleCollection(thread_);
468         for (auto &item : cachedPatchModules_) {
469             gloalHandleCollection.Dispose(item.second);
470         }
471         cachedPatchModules_.clear();
472     }
473 
GetStageOfHotReload()474     StageOfHotReload GetStageOfHotReload() const
475     {
476         return stageOfHotReload_;
477     }
SetStageOfHotReload(StageOfHotReload stageOfHotReload)478     void SetStageOfHotReload(StageOfHotReload stageOfHotReload)
479     {
480         stageOfHotReload_ = stageOfHotReload;
481     }
482 
483     bool JoinStackPushFastPath(JSHandle<JSTaggedValue> receiver);
484     bool JoinStackPush(JSHandle<JSTaggedValue> receiver);
485     void JoinStackPopFastPath(JSHandle<JSTaggedValue> receiver);
486     void JoinStackPop(JSHandle<JSTaggedValue> receiver);
487 
SetJsonStringifyCache(size_t index,CVector<std::pair<CString,int>> & value)488     void SetJsonStringifyCache(size_t index, CVector<std::pair<CString, int>> &value)
489     {
490         stringifyCache_[index] = value;
491     }
492 
GetJsonStringifyCache(size_t index)493     CVector<std::pair<CString, int>> GetJsonStringifyCache(size_t index)
494     {
495         return stringifyCache_[index];
496     }
497 
IsAotEntry()498     bool IsAotEntry()
499     {
500         return isAotEntry_;
501     }
502 
503     std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> CalCallSiteInfo(uintptr_t retAddr) const;
504 private:
505     void CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &thisArg,
506                       const JSPandaFile *jsPandaFile, std::string_view entryPoint);
507     JSTaggedValue InvokeEcmaAotEntrypoint(JSHandle<JSFunction> mainFunc, JSHandle<JSTaggedValue> &thisArg,
508                                           const JSPandaFile *jsPandaFile, std::string_view entryPoint,
509                                           CJSInfo *cjsInfo = nullptr);
510     Expected<JSTaggedValue, bool> InvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile, std::string_view entryPoint,
511                                                        bool excuteFromJob = false);
512     Expected<JSTaggedValue, bool> InvokeEcmaEntrypointForHotReload(
513         const JSPandaFile *jsPandaFile, std::string_view entryPoint, bool excuteFromJob);
514     Expected<JSTaggedValue, bool> CommonInvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile,
515         std::string_view entryPoint, JSHandle<JSFunction> &func);
516     bool LoadAOTFiles(const std::string &aotFileName);
517     void RelocateConstantString(const JSPandaFile *jsPandaFile);
518     NO_MOVE_SEMANTIC(EcmaContext);
519     NO_COPY_SEMANTIC(EcmaContext);
520 
521     PropertiesCache *propertiesCache_ {nullptr};
522     JSThread *thread_ {nullptr};
523     EcmaVM *vm_ {nullptr};
524 
525     bool isUncaughtExceptionRegistered_ {false};
526     bool initialized_ {false};
527     std::atomic<bool> isProcessingPendingJob_ {false};
528     ObjectFactory *factory_ {nullptr};
529 
530     // VM execution states.
531     RegExpParserCache *regExpParserCache_ {nullptr};
532     JSTaggedValue numberToStringResultCache_ {JSTaggedValue::Hole()};
533     JSTaggedValue stringSplitResultCache_ {JSTaggedValue::Hole()};
534     JSTaggedValue stringToListResultCache_ {JSTaggedValue::Hole()};
535     JSTaggedValue globalEnv_ {JSTaggedValue::Hole()};
536     JSTaggedValue pointerToIndexDictionary_ {JSTaggedValue::Hole()};
537     JSTaggedValue regexpCache_ {JSTaggedValue::Hole()};
538     JSTaggedValue regexpGlobal_ {JSTaggedValue::Hole()};
539     JSTaggedValue microJobQueue_ {JSTaggedValue::Hole()};
540     EcmaRuntimeStat *runtimeStat_ {nullptr};
541 
542     CMap<const JSPandaFile *, CMap<int32_t, JSTaggedValue>> cachedConstpools_ {};
543 
544     // for HotReload of module.
545     CMap<CString, JSHandle<JSTaggedValue>> cachedPatchModules_ {};
546     StageOfHotReload stageOfHotReload_ = StageOfHotReload::INITIALIZE_STAGE_OF_HOTRELOAD;
547 
548     // VM resources.
549     ModuleManager *moduleManager_ {nullptr};
550     TSManager *tsManager_ {nullptr};
551     kungfu::PGOTypeManager *ptManager_ {nullptr};
552     AOTFileManager *aotFileManager_ {nullptr};
553 
554     // atomics
555     bool AllowAtomicWait_ {true};
556     WaiterListNode waiterListNode_;
557 
558     // Registered Callbacks
559     PromiseRejectCallback promiseRejectCallback_ {nullptr};
560     HostPromiseRejectionTracker hostPromiseRejectionTracker_ {nullptr};
561     void* data_{nullptr};
562 
563     // opt code Profiler
564     OptCodeProfiler *optCodeProfiler_ {nullptr};
565 
566     // opt code loop hoist
567     TypedOpProfiler *typedOpProfiler_ {nullptr};
568 
569     // For icu objects cache
570     struct IcuFormatter {
571         std::string locale;
572         void *icuObj {nullptr};
573         IcuDeleteEntry deleteEntry {nullptr};
574 
575         IcuFormatter() = default;
576         IcuFormatter(const std::string &locale, void *icuObj, IcuDeleteEntry deleteEntry = nullptr)
localeIcuFormatter577             : locale(locale), icuObj(icuObj), deleteEntry(deleteEntry) {}
578     };
579     IcuFormatter icuObjCache_[static_cast<uint32_t>(IcuFormatterType::ICU_FORMATTER_TYPE_COUNT)];
580     // Handlescope
581     static const uint32_t NODE_BLOCK_SIZE_LOG2 = 10;
582     static const uint32_t NODE_BLOCK_SIZE = 1U << NODE_BLOCK_SIZE_LOG2;
583     static constexpr int32_t MIN_HANDLE_STORAGE_SIZE = 2;
584     JSTaggedType *handleScopeStorageNext_ {nullptr};
585     JSTaggedType *handleScopeStorageEnd_ {nullptr};
586     std::vector<std::array<JSTaggedType, NODE_BLOCK_SIZE> *> handleStorageNodes_ {};
587     int32_t currentHandleStorageIndex_ {-1};
588     int32_t handleScopeCount_ {0};
589     EcmaHandleScope *lastHandleScope_ {nullptr};
590     // Frame pointer
591     JSTaggedType *currentFrame_ {nullptr};
592     JSTaggedType *leaveFrame_ {nullptr};
593     JSTaggedType *lastFp_ {nullptr};
594     JSTaggedType *frameBase_ {nullptr};
595     uint64_t stackStart_ {0};
596     uint64_t stackLimit_ {0};
597     GlobalEnvConstants globalConst_;
598     // Join Stack
599     static constexpr uint32_t MIN_JOIN_STACK_SIZE = 2;
600     CVector<JSTaggedValue> joinStack_ {JSTaggedValue::Hole(), JSTaggedValue::Hole()};
601     // json stringify cache
602     static constexpr uint32_t STRINGIFY_CACHE_SIZE = 64;
603     std::array<CVector<std::pair<CString, int>>, STRINGIFY_CACHE_SIZE> stringifyCache_ {};
604     bool isAotEntry_ { false };
605 
606     friend class EcmaHandleScope;
607     friend class JSPandaFileExecutor;
608     friend class ObjectFactory;
609     friend class panda::JSNApi;
610     friend class AOTFileManager;
611     friend class GlobalIndexMap;
612 };
613 }  // namespace ecmascript
614 }  // namespace panda
615 #endif // ECMASCRIPT_ECMA_CONTEXT_H
616