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/config.h" 21#include "ecmascript/common.h" 22#include "ecmascript/js_handle.h" 23#include "ecmascript/js_tagged_value.h" 24#include "ecmascript/mem/c_containers.h" 25#include "ecmascript/mem/visitor.h" 26#include "ecmascript/patch/patch_loader.h" 27#include "ecmascript/stackmap/ark_stackmap.h" 28#include "ecmascript/waiter_list.h" 29#include "global_handle_collection.h" 30#include "libpandafile/file.h" 31 32namespace panda { 33class JSNApi; 34namespace panda_file { 35class File; 36} // namespace panda_file 37 38namespace ecmascript { 39class GlobalEnv; 40class ObjectFactory; 41class EcmaRuntimeStat; 42class RegExpParserCache; 43class JSPandaFileManager; 44class JSPandaFile; 45class ConstantPool; 46class JSPromise; 47class RegExpExecResultCache; 48class EcmaHandleScope; 49class GlobalIndexMap; 50class SustainingJSHandleList; 51class SustainingJSHandle; 52enum class PromiseRejectionEvent : uint8_t; 53enum class CompareStringsOption : uint8_t; 54 55template<typename T> 56class JSHandle; 57class JSThread; 58class JSFunction; 59class JSPromise; 60class JSTaggedValue; 61class EcmaVM; 62class ModuleManager; 63class AOTFileManager; 64class QuickFixManager; 65class OptCodeProfiler; 66class TypedOpProfiler; 67class AbcBufferCache; 68struct CJSInfo; 69class FunctionProtoTransitionTable; 70class ModuleLogger; 71 72namespace job { 73class MicroJobQueue; 74} // namespace job 75namespace tooling { 76class JsDebuggerManager; 77} // namespace tooling 78namespace kungfu { 79class PGOTypeManager; 80} // namespace kungfu 81 82enum class IcuFormatterType { 83 SIMPLE_DATE_FORMAT_DEFAULT, 84 SIMPLE_DATE_FORMAT_DATE, 85 SIMPLE_DATE_FORMAT_TIME, 86 NUMBER_FORMATTER, 87 COLLATOR, 88 ICU_FORMATTER_TYPE_COUNT 89}; 90 91using HostPromiseRejectionTracker = void (*)(const EcmaVM* vm, 92 const JSHandle<JSPromise> promise, 93 const JSHandle<JSTaggedValue> reason, 94 PromiseRejectionEvent operation, 95 void* data); 96using PromiseRejectCallback = void (*)(void* info); 97#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) 98using JsAotReaderCallback = std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)>; 99#endif 100class EcmaContext { 101public: 102 static EcmaContext *CreateAndInitialize(JSThread *thread); 103 static void CheckAndDestroy(JSThread *thread, EcmaContext *context); 104 105 static EcmaContext *Create(JSThread *thread); 106 static bool Destroy(EcmaContext *context); 107 108 EcmaContext(JSThread *thread); 109 ~EcmaContext(); 110 111 EcmaVM *GetEcmaVM() const 112 { 113 return vm_; 114 } 115 116 bool Initialize(); 117 118 bool IsExecutingPendingJob() const 119 { 120 return isProcessingPendingJob_.load(); 121 } 122 123 bool HasPendingJob(); 124 125 bool ExecutePromisePendingJob(); 126 127 static EcmaContext *ConstCast(const EcmaContext *context) 128 { 129 return const_cast<EcmaContext *>(context); 130 } 131 132 bool IsInitialized() const 133 { 134 return initialized_; 135 } 136 137 ModuleManager *GetModuleManager() const 138 { 139 return moduleManager_; 140 } 141 142 AbcBufferCache *GetAbcBufferCache() const 143 { 144 return abcBufferCache_; 145 } 146 147 kungfu::PGOTypeManager *GetPTManager() const 148 { 149 return ptManager_; 150 } 151 152 ARK_INLINE JSThread *GetJSThread() const 153 { 154 return thread_; 155 } 156 PromiseRejectCallback GetPromiseRejectCallback() const 157 { 158 return promiseRejectCallback_; 159 } 160 161 void SetPromiseRejectCallback(PromiseRejectCallback cb) 162 { 163 promiseRejectCallback_ = cb; 164 } 165 166 void SetData(void* data) 167 { 168 data_ = data; 169 } 170 171 void PromiseRejectionTracker(const JSHandle<JSPromise> &promise, 172 const JSHandle<JSTaggedValue> &reason, PromiseRejectionEvent operation) 173 { 174 if (hostPromiseRejectionTracker_ != nullptr) { 175 hostPromiseRejectionTracker_(vm_, promise, reason, operation, data_); 176 } 177 } 178 179 void SetHostPromiseRejectionTracker(HostPromiseRejectionTracker cb) 180 { 181 hostPromiseRejectionTracker_ = cb; 182 } 183 void SetupRegExpResultCache(); 184 void SetupNumberToStringResultCache(); 185 void SetupStringSplitResultCache(); 186 void SetupStringToListResultCache(); 187 JSHandle<JSTaggedValue> GetRegExpCache() const 188 { 189 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(®expCache_)); 190 } 191 192 RegExpParserCache *GetRegExpParserCache() const 193 { 194 ASSERT(regExpParserCache_ != nullptr); 195 return regExpParserCache_; 196 } 197 198 void SetRegExpCache(JSTaggedValue newCache) 199 { 200 regexpCache_ = newCache; 201 } 202 uintptr_t GetExpCacheAddress() 203 { 204 return reinterpret_cast<uintptr_t>(®expCache_); 205 } 206 207 void SetupRegExpGlobalResult(); 208 209 JSHandle<JSTaggedValue> GetRegExpGlobalResult() const 210 { 211 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(®expGlobal_)); 212 } 213 214 void SetRegExpGlobalResult(JSTaggedValue newResult) 215 { 216 regexpGlobal_ = newResult; 217 } 218 219 WaiterListNode *GetWaiterListNode() 220 { 221 return &waiterListNode_; 222 } 223 224 void SetAllowAtomicWait(bool wait) 225 { 226 AllowAtomicWait_ = wait; 227 } 228 229 bool GetAllowAtomicWait() const 230 { 231 return AllowAtomicWait_; 232 } 233 JSHandle<JSTaggedValue> GetNumberToStringResultCache() const 234 { 235 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&numberToStringResultCache_)); 236 } 237 238 void SetNumberToStringResultCache(JSTaggedValue newCache) 239 { 240 numberToStringResultCache_ = newCache; 241 } 242 243 JSHandle<JSTaggedValue> GetStringSplitResultCache() const 244 { 245 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&stringSplitResultCache_)); 246 } 247 248 JSHandle<JSTaggedValue> GetStringToListResultCache() const 249 { 250 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&stringToListResultCache_)); 251 } 252 253 void SetStringSplitResultCache(JSTaggedValue newCache) 254 { 255 stringSplitResultCache_ = newCache; 256 } 257 JSHandle<ecmascript::JSTaggedValue> GetAndClearEcmaUncaughtException() const; 258 JSHandle<ecmascript::JSTaggedValue> GetEcmaUncaughtException() const; 259 void EnableUserUncaughtErrorHandler(); 260 261 JSHandle<ConstantPool> AddOrUpdateConstpool(const JSPandaFile *jsPandaFile, 262 JSHandle<ConstantPool> constpool, 263 int32_t index = 0); 264 void AddContextConstpoolCache(const JSPandaFile *jsPandaFile, 265 JSHandle<ConstantPool> constpool, 266 int32_t index); 267 268 void UpdateConstpoolWhenDeserialAI(const std::string& fileName, 269 JSHandle<ConstantPool> aiCP, 270 int32_t index = 0); 271 272 bool HasCachedConstpool(const JSPandaFile *jsPandaFile) const; 273 274 void SetUnsharedConstpool(JSHandle<ConstantPool> sharedConstpool, JSTaggedValue unsharedConstpool); 275 void SetUnsharedConstpool(int32_t constpoolIndex, JSTaggedValue unsharedConstpool); 276 277 JSTaggedValue PUBLIC_API FindConstpool(const JSPandaFile *jsPandaFile, int32_t index); 278 // For new version instruction. 279 JSTaggedValue PUBLIC_API FindConstpool(const JSPandaFile *jsPandaFile, panda_file::File::EntityId id); 280 JSTaggedValue PUBLIC_API FindOrCreateUnsharedConstpool(JSTaggedValue sharedConstpool); 281 JSTaggedValue PUBLIC_API FindUnsharedConstpool(JSTaggedValue sharedConstpool); 282 void PUBLIC_API LoadProtoTransitionTable(JSTaggedValue constpool); 283 void PUBLIC_API ResetProtoTransitionTableOnConstpool(JSTaggedValue constpool); 284 JSTaggedValue FindCachedConstpoolAndLoadAiIfNeeded(const JSPandaFile *jsPandaFile, int32_t index); 285 void EraseUnusedConstpool(const JSPandaFile *jsPandaFile, int32_t index, int32_t constpoolIndex); 286 std::optional<std::reference_wrapper<CMap<int32_t, JSTaggedValue>>> FindConstpools( 287 const JSPandaFile *jsPandaFile); 288 289 JSHandle<ConstantPool> PUBLIC_API FindOrCreateConstPool(const JSPandaFile *jsPandaFile, 290 panda_file::File::EntityId id); 291 void CreateAllConstpool(const JSPandaFile *jsPandaFile); 292 293 void HandleUncaughtException(JSTaggedValue exception); 294 void HandleUncaughtException(); 295 JSHandle<GlobalEnv> GetGlobalEnv() const; 296 bool GlobalEnvIsHole() 297 { 298 return globalEnv_.IsHole(); 299 } 300 301 JSHandle<job::MicroJobQueue> GetMicroJobQueue() const; 302 303 static void PrintJSErrorInfo(JSThread *thread, const JSHandle<JSTaggedValue> &exceptionInfo); 304 void Iterate(const RootVisitor &v, const RootRangeVisitor &rv); 305 static void MountContext(JSThread *thread); 306 static void UnmountContext(JSThread *thread); 307 void SetMicroJobQueue(job::MicroJobQueue *queue); 308 void SetGlobalEnv(GlobalEnv *global); 309 void PrintOptStat(); 310 311 OptCodeProfiler *GetOptCodeProfiler() const 312 { 313 return optCodeProfiler_; 314 } 315 316 TypedOpProfiler *GetTypdOpProfiler() const 317 { 318 return typedOpProfiler_; 319 } 320 321 ModuleLogger *GetModuleLogger() const 322 { 323 return moduleLogger_; 324 } 325 326 void SetModuleLogger(ModuleLogger *moduleLogger) 327 { 328 moduleLogger_ = moduleLogger; 329 } 330 331 void SetDefaultLocale(const std::string& locale) 332 { 333 defaultLocale_ = locale; 334 } 335 336 const std::string& GetDefaultLocale() const 337 { 338 return defaultLocale_; 339 } 340 341 void InitializeDefaultLocale() 342 { 343 defaultLocale_ = ""; 344 } 345 346 void ClearDefaultLocale() 347 { 348 defaultLocale_.clear(); 349 } 350 351 void SetDefaultCompareStringsOption(const CompareStringsOption csOption) 352 { 353 defaultComapreStringsOption_ = csOption; 354 } 355 356 const std::optional<CompareStringsOption> GetDefaultCompareStringsOption() const 357 { 358 return defaultComapreStringsOption_; 359 } 360 361 void InitializeDefaultCompareStringsOption() 362 { 363 defaultComapreStringsOption_ = std::nullopt; 364 } 365 366 void ClearDefaultComapreStringsOption() 367 { 368 defaultComapreStringsOption_ = std::nullopt; 369 } 370 371 FunctionProtoTransitionTable *GetFunctionProtoTransitionTable() const 372 { 373 return functionProtoTransitionTable_; 374 } 375 376 // For icu objects cache 377 void SetIcuFormatterToCache(IcuFormatterType type, const std::string &locale, void *icuObj, 378 NativePointerCallback deleteEntry = nullptr) 379 { 380 EcmaContext::IcuFormatter icuFormatter = IcuFormatter(locale, icuObj, deleteEntry); 381 icuObjCache_[static_cast<int>(type)] = icuFormatter; 382 } 383 384 ARK_INLINE void *GetIcuFormatterFromCache(IcuFormatterType type, std::string &locale) 385 { 386 auto &icuFormatter = icuObjCache_[static_cast<int>(type)]; 387 if (icuFormatter.locale == locale) { 388 return icuFormatter.icuObj; 389 } 390 return nullptr; 391 } 392 393 void ClearIcuCache(JSThread *thread); 394 395 EcmaRuntimeStat *GetRuntimeStat() const 396 { 397 return runtimeStat_; 398 } 399 400 void SetRuntimeStatEnable(bool flag); 401 void InitializeEcmaScriptRunStat(); 402 void DumpAOTInfo() const DUMP_API_ATTR; 403 404 JSTaggedValue ExecuteAot(size_t actualNumArgs, JSTaggedType *args, const JSTaggedType *prevFp, 405 bool needPushArgv); 406 void LoadStubFile(); 407 408 JSTaggedType *GetHandleScopeStorageNext() const 409 { 410 return handleScopeStorageNext_; 411 } 412 413 void SetHandleScopeStorageNext(JSTaggedType *value) 414 { 415 handleScopeStorageNext_ = value; 416 } 417 418 JSTaggedType *GetHandleScopeStorageEnd() const 419 { 420 return handleScopeStorageEnd_; 421 } 422 423 void SetHandleScopeStorageEnd(JSTaggedType *value) 424 { 425 handleScopeStorageEnd_ = value; 426 } 427 428 int GetCurrentHandleStorageIndex() const 429 { 430 return currentHandleStorageIndex_; 431 } 432 433#ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK 434 void HandleScopeCountAdd() 435 { 436 handleScopeCount_++; 437 } 438 439 void HandleScopeCountDec() 440 { 441 handleScopeCount_--; 442 } 443 444 void PrimitiveScopeCountAdd() 445 { 446 primitiveScopeCount_++; 447 } 448 449 void PrimitiveScopeCountDec() 450 { 451 primitiveScopeCount_--; 452 } 453#endif 454 455 void SetLastHandleScope(EcmaHandleScope *scope) 456 { 457 lastHandleScope_ = scope; 458 } 459 460 EcmaHandleScope *GetLastHandleScope() const 461 { 462 return lastHandleScope_; 463 } 464 465 JSTaggedType *GetPrimitiveScopeStorageNext() const 466 { 467 return primitiveScopeStorageNext_; 468 } 469 470 void SetPrimitiveScopeStorageNext(JSTaggedType *value) 471 { 472 primitiveScopeStorageNext_ = value; 473 } 474 475 JSTaggedType *GetPrimitiveScopeStorageEnd() const 476 { 477 return primitiveScopeStorageEnd_; 478 } 479 480 void SetPrimitiveScopeStorageEnd(JSTaggedType *value) 481 { 482 primitiveScopeStorageEnd_ = value; 483 } 484 485 int GetCurrentPrimitiveStorageIndex() const 486 { 487 return currentPrimitiveStorageIndex_; 488 } 489 490 void SetLastPrimitiveScope(EcmaHandleScope *scope) 491 { 492 lastPrimitiveScope_ = scope; 493 } 494 495 EcmaHandleScope *GetLastPrimitiveScope() const 496 { 497 return lastPrimitiveScope_; 498 } 499 500 size_t IterateHandle(const RootRangeVisitor &rangeVisitor); 501 uintptr_t *ExpandHandleStorage(); 502 void ShrinkHandleStorage(int prevIndex); 503 uintptr_t *ExpandPrimitiveStorage(); 504 void ShrinkPrimitiveStorage(int prevIndex); 505 506 JSTaggedType *GetCurrentFrame() const 507 { 508 return currentFrame_; 509 } 510 511 JSTaggedType *GetLeaveFrame() const 512 { 513 return leaveFrame_; 514 } 515 516 JSTaggedType *GetLastFp() const 517 { 518 return lastFp_; 519 } 520 521 void SetFramePointers(JSTaggedType *currentFrame, JSTaggedType *leaveFrame, JSTaggedType *lastFp) 522 { 523 currentFrame_ = currentFrame; 524 leaveFrame_ = leaveFrame; 525 lastFp_ = lastFp; 526 } 527 void SetFrameBase(JSTaggedType *frameBase) 528 { 529 frameBase_ = frameBase; 530 } 531 JSTaggedType *GetFrameBase() const 532 { 533 return frameBase_; 534 } 535 536 void SetStackStart(uint64_t stackStart) 537 { 538 stackStart_ = stackStart; 539 } 540 uint64_t GetStackStart() const 541 { 542 return stackStart_; 543 } 544 void SetStackLimit(uint64_t stackLimit) 545 { 546 stackLimit_ = stackLimit; 547 } 548 uint64_t GetStackLimit() const 549 { 550 return stackLimit_; 551 } 552 553 PropertiesCache *GetPropertiesCache() const 554 { 555 return propertiesCache_; 556 } 557 void ClearBufferData(); 558 const GlobalEnvConstants *GlobalConstants() const 559 { 560 return &globalConst_; 561 } 562 563 void AddPatchModule(const CString &recordName, const JSHandle<JSTaggedValue> moduleRecord) 564 { 565 cachedPatchModules_.emplace(recordName, moduleRecord); 566 } 567 JSHandle<JSTaggedValue> FindPatchModule(const CString &recordName) const 568 { 569 auto iter = cachedPatchModules_.find(recordName); 570 if (iter != cachedPatchModules_.end()) { 571 return iter->second; 572 } 573 return JSHandle<JSTaggedValue>(thread_, JSTaggedValue::Hole()); 574 } 575 void ClearPatchModules() 576 { 577 GlobalHandleCollection gloalHandleCollection(thread_); 578 for (auto &item : cachedPatchModules_) { 579 gloalHandleCollection.Dispose(item.second); 580 } 581 cachedPatchModules_.clear(); 582 } 583 584 StageOfHotReload GetStageOfHotReload() const 585 { 586 return stageOfHotReload_; 587 } 588 void SetStageOfHotReload(StageOfHotReload stageOfHotReload) 589 { 590 stageOfHotReload_ = stageOfHotReload; 591 } 592 593 StageOfColdReload GetStageOfColdReload() const 594 { 595 return stageOfColdReload_; 596 } 597 void SetStageOfColdReload(StageOfColdReload stageOfColdReload) 598 { 599 stageOfColdReload_ = stageOfColdReload; 600 } 601 602 bool JoinStackPushFastPath(JSHandle<JSTaggedValue> receiver); 603 bool JoinStackPush(JSHandle<JSTaggedValue> receiver); 604 void JoinStackPopFastPath(JSHandle<JSTaggedValue> receiver); 605 void JoinStackPop(JSHandle<JSTaggedValue> receiver); 606 607 void SetJsonStringifyCache(size_t index, CVector<std::pair<CString, int>> &value) 608 { 609 stringifyCache_[index] = value; 610 } 611 612 CVector<std::pair<CString, int>> GetJsonStringifyCache(size_t index) 613 { 614 return stringifyCache_[index]; 615 } 616 617 bool IsAotEntry() 618 { 619 return isAotEntry_; 620 } 621 622 std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> CalCallSiteInfo(uintptr_t retAddr, 623 bool isDeopt) const; 624 625 void AddSustainingJSHandle(SustainingJSHandle*); 626 void RemoveSustainingJSHandle(SustainingJSHandle*); 627 void ClearKeptObjects(); 628 void AddToKeptObjects(JSHandle<JSTaggedValue> value); 629 inline bool HasKeptObjects() const 630 { 631 return hasKeptObjects_; 632 } 633 634 void ClearCachedConstantPool() 635 { 636 cachedSharedConstpools_.clear(); 637 } 638 639private: 640 void CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &thisArg, 641 const JSPandaFile *jsPandaFile, std::string_view entryPoint); 642 JSTaggedValue InvokeEcmaAotEntrypoint(JSHandle<JSFunction> mainFunc, JSHandle<JSTaggedValue> &thisArg, 643 const JSPandaFile *jsPandaFile, std::string_view entryPoint, 644 CJSInfo *cjsInfo = nullptr); 645 Expected<JSTaggedValue, bool> InvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile, std::string_view entryPoint, 646 bool executeFromJob = false); 647 Expected<JSTaggedValue, bool> InvokeEcmaEntrypointForHotReload( 648 const JSPandaFile *jsPandaFile, std::string_view entryPoint, bool executeFromJob); 649 Expected<JSTaggedValue, bool> CommonInvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile, 650 std::string_view entryPoint, JSHandle<JSFunction> &func, bool executeFromJob); 651 bool LoadAOTFilesInternal(const std::string& aotFileName); 652 bool LoadAOTFiles(const std::string &aotFileName); 653#if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) 654 bool LoadAOTFiles(const std::string &aotFileName, 655 std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)> cb); 656#endif 657 void RelocateConstantString(const JSPandaFile *jsPandaFile); 658 JSTaggedValue FindConstpoolFromContextCache(const JSPandaFile *jsPandaFile, int32_t index); 659 660 void CheckUnsharedConstpoolArrayLimit(int32_t index) 661 { 662 if (index >= UNSHARED_CONSTANTPOOL_COUNT) { 663 LOG_ECMA(FATAL) << "the unshared constpool array need to expanding capacity, index :" << index; 664 UNREACHABLE(); 665 } 666 } 667 668 NO_MOVE_SEMANTIC(EcmaContext); 669 NO_COPY_SEMANTIC(EcmaContext); 670 671 PropertiesCache *propertiesCache_ {nullptr}; 672 JSThread *thread_ {nullptr}; 673 EcmaVM *vm_ {nullptr}; 674 675 bool isUncaughtExceptionRegistered_ {false}; 676 bool initialized_ {false}; 677 std::atomic<bool> isProcessingPendingJob_ {false}; 678 ObjectFactory *factory_ {nullptr}; 679 680 // VM execution states. 681 RegExpParserCache *regExpParserCache_ {nullptr}; 682 JSTaggedValue numberToStringResultCache_ {JSTaggedValue::Hole()}; 683 JSTaggedValue stringSplitResultCache_ {JSTaggedValue::Hole()}; 684 JSTaggedValue stringToListResultCache_ {JSTaggedValue::Hole()}; 685 JSTaggedValue globalEnv_ {JSTaggedValue::Hole()}; 686 JSTaggedValue pointerToIndexDictionary_ {JSTaggedValue::Hole()}; 687 JSTaggedValue regexpCache_ {JSTaggedValue::Hole()}; 688 JSTaggedValue regexpGlobal_ {JSTaggedValue::Hole()}; 689 JSTaggedValue microJobQueue_ {JSTaggedValue::Hole()}; 690 EcmaRuntimeStat *runtimeStat_ {nullptr}; 691 692 CMap<const JSPandaFile *, CMap<int32_t, JSTaggedValue>> cachedSharedConstpools_ {}; 693 std::array<JSTaggedValue, UNSHARED_CONSTANTPOOL_COUNT> unsharedConstpools_ {}; 694 static constexpr int32_t SHARED_CONSTPOOL_KEY_NOT_FOUND = INT32_MAX; // INT32_MAX :invalid value. 695 696 // for HotReload of module. 697 CMap<CString, JSHandle<JSTaggedValue>> cachedPatchModules_ {}; 698 StageOfHotReload stageOfHotReload_ = StageOfHotReload::INITIALIZE_STAGE_OF_HOTRELOAD; 699 StageOfColdReload stageOfColdReload_ = StageOfColdReload::NOT_COLD_RELOAD; 700 701 // VM resources. 702 ModuleManager *moduleManager_ {nullptr}; 703 kungfu::PGOTypeManager *ptManager_ {nullptr}; 704 AOTFileManager *aotFileManager_ {nullptr}; 705 AbcBufferCache *abcBufferCache_ {nullptr}; 706 707 // for recording the transition of function prototype 708 FunctionProtoTransitionTable *functionProtoTransitionTable_ {nullptr}; 709 710 // atomics 711 bool AllowAtomicWait_ {true}; 712 WaiterListNode waiterListNode_; 713 714 // Registered Callbacks 715 PromiseRejectCallback promiseRejectCallback_ {nullptr}; 716 HostPromiseRejectionTracker hostPromiseRejectionTracker_ {nullptr}; 717 void* data_{nullptr}; 718 719 // opt code Profiler 720 OptCodeProfiler *optCodeProfiler_ {nullptr}; 721 722 // opt code loop hoist 723 TypedOpProfiler *typedOpProfiler_ {nullptr}; 724 725 ModuleLogger *moduleLogger_ {nullptr}; 726 727 std::string defaultLocale_; 728 std::optional<CompareStringsOption> defaultComapreStringsOption_; 729 730 // For icu objects cache 731 struct IcuFormatter { 732 std::string locale; 733 void *icuObj {nullptr}; 734 NativePointerCallback deleteEntry {nullptr}; 735 736 IcuFormatter() = default; 737 IcuFormatter(const std::string &locale, void *icuObj, NativePointerCallback deleteEntry = nullptr) 738 : locale(locale), icuObj(icuObj), deleteEntry(deleteEntry) {} 739 }; 740 IcuFormatter icuObjCache_[static_cast<uint32_t>(IcuFormatterType::ICU_FORMATTER_TYPE_COUNT)]; 741 // Handlescope 742 static const uint32_t NODE_BLOCK_SIZE_LOG2 = 10; 743 static const uint32_t NODE_BLOCK_SIZE = 1U << NODE_BLOCK_SIZE_LOG2; 744 static constexpr int32_t MIN_HANDLE_STORAGE_SIZE = 2; 745 JSTaggedType *handleScopeStorageNext_ {nullptr}; 746 JSTaggedType *handleScopeStorageEnd_ {nullptr}; 747 std::vector<std::array<JSTaggedType, NODE_BLOCK_SIZE> *> handleStorageNodes_ {}; 748 int32_t currentHandleStorageIndex_ {-1}; 749#ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK 750 int32_t handleScopeCount_ {0}; 751 int32_t primitiveScopeCount_ {0}; 752#endif 753 EcmaHandleScope *lastHandleScope_ {nullptr}; 754 // PrimitveScope 755 static constexpr int32_t MIN_PRIMITIVE_STORAGE_SIZE = 2; 756 JSTaggedType *primitiveScopeStorageNext_ {nullptr}; 757 JSTaggedType *primitiveScopeStorageEnd_ {nullptr}; 758 std::vector<std::array<JSTaggedType, NODE_BLOCK_SIZE> *> primitiveStorageNodes_ {}; 759 int32_t currentPrimitiveStorageIndex_ {-1}; 760 EcmaHandleScope *lastPrimitiveScope_ {nullptr}; 761 762 // Frame pointer 763 JSTaggedType *currentFrame_ {nullptr}; 764 JSTaggedType *leaveFrame_ {nullptr}; 765 JSTaggedType *lastFp_ {nullptr}; 766 JSTaggedType *frameBase_ {nullptr}; 767 uint64_t stackStart_ {0}; 768 uint64_t stackLimit_ {0}; 769 GlobalEnvConstants globalConst_; 770 // Join Stack 771 static constexpr uint32_t MIN_JOIN_STACK_SIZE = 2; 772 CVector<JSTaggedValue> joinStack_ {JSTaggedValue::Hole(), JSTaggedValue::Hole()}; 773 // json stringify cache 774 static constexpr uint32_t STRINGIFY_CACHE_SIZE = 64; 775 std::array<CVector<std::pair<CString, int>>, STRINGIFY_CACHE_SIZE> stringifyCache_ {}; 776 bool isAotEntry_ { false }; 777 778 // SustainingJSHandleList for jit compile hold ref 779 SustainingJSHandleList *sustainingJSHandleList_ {nullptr}; 780 781 bool hasKeptObjects_ {false}; 782 783 friend class EcmaHandleScope; 784 friend class JSPandaFileExecutor; 785 friend class ObjectFactory; 786 friend class panda::JSNApi; 787 friend class AOTFileManager; 788 friend class GlobalIndexMap; 789}; 790} // namespace ecmascript 791} // namespace panda 792#endif // ECMASCRIPT_ECMA_CONTEXT_H 793