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 32 namespace panda { 33 class JSNApi; 34 namespace panda_file { 35 class File; 36 } // namespace panda_file 37 38 namespace ecmascript { 39 class GlobalEnv; 40 class ObjectFactory; 41 class EcmaRuntimeStat; 42 class RegExpParserCache; 43 class JSPandaFileManager; 44 class JSPandaFile; 45 class ConstantPool; 46 class JSPromise; 47 class RegExpExecResultCache; 48 class EcmaHandleScope; 49 class GlobalIndexMap; 50 class SustainingJSHandleList; 51 class SustainingJSHandle; 52 enum class PromiseRejectionEvent : uint8_t; 53 enum class CompareStringsOption : uint8_t; 54 55 template<typename T> 56 class JSHandle; 57 class JSThread; 58 class JSFunction; 59 class JSPromise; 60 class JSTaggedValue; 61 class EcmaVM; 62 class ModuleManager; 63 class AOTFileManager; 64 class QuickFixManager; 65 class OptCodeProfiler; 66 class TypedOpProfiler; 67 class AbcBufferCache; 68 struct CJSInfo; 69 class FunctionProtoTransitionTable; 70 class ModuleLogger; 71 72 namespace job { 73 class MicroJobQueue; 74 } // namespace job 75 namespace tooling { 76 class JsDebuggerManager; 77 } // namespace tooling 78 namespace kungfu { 79 class PGOTypeManager; 80 } // namespace kungfu 81 82 enum 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 91 using HostPromiseRejectionTracker = void (*)(const EcmaVM* vm, 92 const JSHandle<JSPromise> promise, 93 const JSHandle<JSTaggedValue> reason, 94 PromiseRejectionEvent operation, 95 void* data); 96 using PromiseRejectCallback = void (*)(void* info); 97 #if defined(CROSS_PLATFORM) && defined(ANDROID_PLATFORM) 98 using JsAotReaderCallback = std::function<bool(std::string fileName, uint8_t **buff, size_t *buffSize)>; 99 #endif 100 class EcmaContext { 101 public: 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 GetEcmaVM()111 EcmaVM *GetEcmaVM() const 112 { 113 return vm_; 114 } 115 116 bool Initialize(); 117 IsExecutingPendingJob()118 bool IsExecutingPendingJob() const 119 { 120 return isProcessingPendingJob_.load(); 121 } 122 123 bool HasPendingJob(); 124 125 bool ExecutePromisePendingJob(); 126 ConstCast(const EcmaContext * context)127 static EcmaContext *ConstCast(const EcmaContext *context) 128 { 129 return const_cast<EcmaContext *>(context); 130 } 131 IsInitialized()132 bool IsInitialized() const 133 { 134 return initialized_; 135 } 136 GetModuleManager()137 ModuleManager *GetModuleManager() const 138 { 139 return moduleManager_; 140 } 141 GetAbcBufferCache()142 AbcBufferCache *GetAbcBufferCache() const 143 { 144 return abcBufferCache_; 145 } 146 GetPTManager()147 kungfu::PGOTypeManager *GetPTManager() const 148 { 149 return ptManager_; 150 } 151 GetJSThread()152 ARK_INLINE JSThread *GetJSThread() const 153 { 154 return thread_; 155 } GetPromiseRejectCallback()156 PromiseRejectCallback GetPromiseRejectCallback() const 157 { 158 return promiseRejectCallback_; 159 } 160 SetPromiseRejectCallback(PromiseRejectCallback cb)161 void SetPromiseRejectCallback(PromiseRejectCallback cb) 162 { 163 promiseRejectCallback_ = cb; 164 } 165 SetData(void * data)166 void SetData(void* data) 167 { 168 data_ = data; 169 } 170 PromiseRejectionTracker(const JSHandle<JSPromise> & promise,const JSHandle<JSTaggedValue> & reason,PromiseRejectionEvent operation)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 SetHostPromiseRejectionTracker(HostPromiseRejectionTracker cb)179 void SetHostPromiseRejectionTracker(HostPromiseRejectionTracker cb) 180 { 181 hostPromiseRejectionTracker_ = cb; 182 } 183 void SetupRegExpResultCache(); 184 void SetupNumberToStringResultCache(); 185 void SetupStringSplitResultCache(); 186 void SetupStringToListResultCache(); GetRegExpCache()187 JSHandle<JSTaggedValue> GetRegExpCache() const 188 { 189 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(®expCache_)); 190 } 191 GetRegExpParserCache()192 RegExpParserCache *GetRegExpParserCache() const 193 { 194 ASSERT(regExpParserCache_ != nullptr); 195 return regExpParserCache_; 196 } 197 SetRegExpCache(JSTaggedValue newCache)198 void SetRegExpCache(JSTaggedValue newCache) 199 { 200 regexpCache_ = newCache; 201 } GetExpCacheAddress()202 uintptr_t GetExpCacheAddress() 203 { 204 return reinterpret_cast<uintptr_t>(®expCache_); 205 } 206 207 void SetupRegExpGlobalResult(); 208 GetRegExpGlobalResult()209 JSHandle<JSTaggedValue> GetRegExpGlobalResult() const 210 { 211 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(®expGlobal_)); 212 } 213 SetRegExpGlobalResult(JSTaggedValue newResult)214 void SetRegExpGlobalResult(JSTaggedValue newResult) 215 { 216 regexpGlobal_ = newResult; 217 } 218 GetWaiterListNode()219 WaiterListNode *GetWaiterListNode() 220 { 221 return &waiterListNode_; 222 } 223 SetAllowAtomicWait(bool wait)224 void SetAllowAtomicWait(bool wait) 225 { 226 AllowAtomicWait_ = wait; 227 } 228 GetAllowAtomicWait()229 bool GetAllowAtomicWait() const 230 { 231 return AllowAtomicWait_; 232 } GetNumberToStringResultCache()233 JSHandle<JSTaggedValue> GetNumberToStringResultCache() const 234 { 235 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&numberToStringResultCache_)); 236 } 237 SetNumberToStringResultCache(JSTaggedValue newCache)238 void SetNumberToStringResultCache(JSTaggedValue newCache) 239 { 240 numberToStringResultCache_ = newCache; 241 } 242 GetStringSplitResultCache()243 JSHandle<JSTaggedValue> GetStringSplitResultCache() const 244 { 245 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&stringSplitResultCache_)); 246 } 247 GetStringToListResultCache()248 JSHandle<JSTaggedValue> GetStringToListResultCache() const 249 { 250 return JSHandle<JSTaggedValue>(reinterpret_cast<uintptr_t>(&stringToListResultCache_)); 251 } 252 SetStringSplitResultCache(JSTaggedValue newCache)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; GlobalEnvIsHole()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 GetOptCodeProfiler()311 OptCodeProfiler *GetOptCodeProfiler() const 312 { 313 return optCodeProfiler_; 314 } 315 GetTypdOpProfiler()316 TypedOpProfiler *GetTypdOpProfiler() const 317 { 318 return typedOpProfiler_; 319 } 320 GetModuleLogger()321 ModuleLogger *GetModuleLogger() const 322 { 323 return moduleLogger_; 324 } 325 SetModuleLogger(ModuleLogger * moduleLogger)326 void SetModuleLogger(ModuleLogger *moduleLogger) 327 { 328 moduleLogger_ = moduleLogger; 329 } 330 SetDefaultLocale(const std::string & locale)331 void SetDefaultLocale(const std::string& locale) 332 { 333 defaultLocale_ = locale; 334 } 335 GetDefaultLocale()336 const std::string& GetDefaultLocale() const 337 { 338 return defaultLocale_; 339 } 340 InitializeDefaultLocale()341 void InitializeDefaultLocale() 342 { 343 defaultLocale_ = ""; 344 } 345 ClearDefaultLocale()346 void ClearDefaultLocale() 347 { 348 defaultLocale_.clear(); 349 } 350 SetDefaultCompareStringsOption(const CompareStringsOption csOption)351 void SetDefaultCompareStringsOption(const CompareStringsOption csOption) 352 { 353 defaultComapreStringsOption_ = csOption; 354 } 355 GetDefaultCompareStringsOption()356 const std::optional<CompareStringsOption> GetDefaultCompareStringsOption() const 357 { 358 return defaultComapreStringsOption_; 359 } 360 InitializeDefaultCompareStringsOption()361 void InitializeDefaultCompareStringsOption() 362 { 363 defaultComapreStringsOption_ = std::nullopt; 364 } 365 ClearDefaultComapreStringsOption()366 void ClearDefaultComapreStringsOption() 367 { 368 defaultComapreStringsOption_ = std::nullopt; 369 } 370 GetFunctionProtoTransitionTable()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 GetIcuFormatterFromCache(IcuFormatterType type,std::string & locale)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 GetRuntimeStat()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 GetHandleScopeStorageNext()408 JSTaggedType *GetHandleScopeStorageNext() const 409 { 410 return handleScopeStorageNext_; 411 } 412 SetHandleScopeStorageNext(JSTaggedType * value)413 void SetHandleScopeStorageNext(JSTaggedType *value) 414 { 415 handleScopeStorageNext_ = value; 416 } 417 GetHandleScopeStorageEnd()418 JSTaggedType *GetHandleScopeStorageEnd() const 419 { 420 return handleScopeStorageEnd_; 421 } 422 SetHandleScopeStorageEnd(JSTaggedType * value)423 void SetHandleScopeStorageEnd(JSTaggedType *value) 424 { 425 handleScopeStorageEnd_ = value; 426 } 427 GetCurrentHandleStorageIndex()428 int GetCurrentHandleStorageIndex() const 429 { 430 return currentHandleStorageIndex_; 431 } 432 433 #ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK HandleScopeCountAdd()434 void HandleScopeCountAdd() 435 { 436 handleScopeCount_++; 437 } 438 HandleScopeCountDec()439 void HandleScopeCountDec() 440 { 441 handleScopeCount_--; 442 } 443 PrimitiveScopeCountAdd()444 void PrimitiveScopeCountAdd() 445 { 446 primitiveScopeCount_++; 447 } 448 PrimitiveScopeCountDec()449 void PrimitiveScopeCountDec() 450 { 451 primitiveScopeCount_--; 452 } 453 #endif 454 SetLastHandleScope(EcmaHandleScope * scope)455 void SetLastHandleScope(EcmaHandleScope *scope) 456 { 457 lastHandleScope_ = scope; 458 } 459 GetLastHandleScope()460 EcmaHandleScope *GetLastHandleScope() const 461 { 462 return lastHandleScope_; 463 } 464 GetPrimitiveScopeStorageNext()465 JSTaggedType *GetPrimitiveScopeStorageNext() const 466 { 467 return primitiveScopeStorageNext_; 468 } 469 SetPrimitiveScopeStorageNext(JSTaggedType * value)470 void SetPrimitiveScopeStorageNext(JSTaggedType *value) 471 { 472 primitiveScopeStorageNext_ = value; 473 } 474 GetPrimitiveScopeStorageEnd()475 JSTaggedType *GetPrimitiveScopeStorageEnd() const 476 { 477 return primitiveScopeStorageEnd_; 478 } 479 SetPrimitiveScopeStorageEnd(JSTaggedType * value)480 void SetPrimitiveScopeStorageEnd(JSTaggedType *value) 481 { 482 primitiveScopeStorageEnd_ = value; 483 } 484 GetCurrentPrimitiveStorageIndex()485 int GetCurrentPrimitiveStorageIndex() const 486 { 487 return currentPrimitiveStorageIndex_; 488 } 489 SetLastPrimitiveScope(EcmaHandleScope * scope)490 void SetLastPrimitiveScope(EcmaHandleScope *scope) 491 { 492 lastPrimitiveScope_ = scope; 493 } 494 GetLastPrimitiveScope()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 GetCurrentFrame()506 JSTaggedType *GetCurrentFrame() const 507 { 508 return currentFrame_; 509 } 510 GetLeaveFrame()511 JSTaggedType *GetLeaveFrame() const 512 { 513 return leaveFrame_; 514 } 515 GetLastFp()516 JSTaggedType *GetLastFp() const 517 { 518 return lastFp_; 519 } 520 SetFramePointers(JSTaggedType * currentFrame,JSTaggedType * leaveFrame,JSTaggedType * lastFp)521 void SetFramePointers(JSTaggedType *currentFrame, JSTaggedType *leaveFrame, JSTaggedType *lastFp) 522 { 523 currentFrame_ = currentFrame; 524 leaveFrame_ = leaveFrame; 525 lastFp_ = lastFp; 526 } SetFrameBase(JSTaggedType * frameBase)527 void SetFrameBase(JSTaggedType *frameBase) 528 { 529 frameBase_ = frameBase; 530 } GetFrameBase()531 JSTaggedType *GetFrameBase() const 532 { 533 return frameBase_; 534 } 535 SetStackStart(uint64_t stackStart)536 void SetStackStart(uint64_t stackStart) 537 { 538 stackStart_ = stackStart; 539 } GetStackStart()540 uint64_t GetStackStart() const 541 { 542 return stackStart_; 543 } SetStackLimit(uint64_t stackLimit)544 void SetStackLimit(uint64_t stackLimit) 545 { 546 stackLimit_ = stackLimit; 547 } GetStackLimit()548 uint64_t GetStackLimit() const 549 { 550 return stackLimit_; 551 } 552 GetPropertiesCache()553 PropertiesCache *GetPropertiesCache() const 554 { 555 return propertiesCache_; 556 } 557 void ClearBufferData(); GlobalConstants()558 const GlobalEnvConstants *GlobalConstants() const 559 { 560 return &globalConst_; 561 } 562 AddPatchModule(const CString & recordName,const JSHandle<JSTaggedValue> moduleRecord)563 void AddPatchModule(const CString &recordName, const JSHandle<JSTaggedValue> moduleRecord) 564 { 565 cachedPatchModules_.emplace(recordName, moduleRecord); 566 } FindPatchModule(const CString & recordName)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 } ClearPatchModules()575 void ClearPatchModules() 576 { 577 GlobalHandleCollection gloalHandleCollection(thread_); 578 for (auto &item : cachedPatchModules_) { 579 gloalHandleCollection.Dispose(item.second); 580 } 581 cachedPatchModules_.clear(); 582 } 583 GetStageOfHotReload()584 StageOfHotReload GetStageOfHotReload() const 585 { 586 return stageOfHotReload_; 587 } SetStageOfHotReload(StageOfHotReload stageOfHotReload)588 void SetStageOfHotReload(StageOfHotReload stageOfHotReload) 589 { 590 stageOfHotReload_ = stageOfHotReload; 591 } 592 GetStageOfColdReload()593 StageOfColdReload GetStageOfColdReload() const 594 { 595 return stageOfColdReload_; 596 } SetStageOfColdReload(StageOfColdReload stageOfColdReload)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 SetJsonStringifyCache(size_t index,CVector<std::pair<CString,int>> & value)607 void SetJsonStringifyCache(size_t index, CVector<std::pair<CString, int>> &value) 608 { 609 stringifyCache_[index] = value; 610 } 611 GetJsonStringifyCache(size_t index)612 CVector<std::pair<CString, int>> GetJsonStringifyCache(size_t index) 613 { 614 return stringifyCache_[index]; 615 } 616 IsAotEntry()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); HasKeptObjects()629 inline bool HasKeptObjects() const 630 { 631 return hasKeptObjects_; 632 } 633 ClearCachedConstantPool()634 void ClearCachedConstantPool() 635 { 636 cachedSharedConstpools_.clear(); 637 } 638 639 private: 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 CheckUnsharedConstpoolArrayLimit(int32_t index)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) localeIcuFormatter738 : 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