ScriptContext.h 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. #ifdef ENABLE_SCRIPT_PROFILING
  7. #include "activprof.h"
  8. #endif
  9. #if DBG || ENABLE_REGEX_CONFIG_OPTIONS || defined(PROFILE_STRINGS)
  10. #define NEED_MISC_ALLOCATOR
  11. #endif
  12. #define BuiltInFunctionsScriptId 0
  13. using namespace PlatformAgnostic;
  14. class NativeCodeGenerator;
  15. class BackgroundParser;
  16. struct IActiveScriptDirect;
  17. #ifdef ENABLE_BASIC_TELEMETRY
  18. class ScriptContextTelemetry;
  19. #endif
  20. namespace Js
  21. {
  22. class ScriptContext;
  23. class ScriptEditQuery;
  24. class MutationBreakpoint;
  25. class StringProfiler;
  26. class DebugContext;
  27. struct HaltCallback;
  28. struct DebuggerOptionsCallback;
  29. class ModuleRecordBase;
  30. }
  31. // Created for every source buffer passed by host.
  32. // This structure has all the details.
  33. class SRCINFO
  34. {
  35. // We currently don't free SRCINFO object so we don't want to add extra variables here.
  36. // In future, when we do make it freeable and will be able to allocate more than one per Module,
  37. // we can move variables m_isGlobalFunc and m_isEval from FunctionBody.cpp here.
  38. public:
  39. SourceContextInfo * sourceContextInfo;
  40. ULONG dlnHost; // Line number passed to ParseScriptText
  41. ULONG ulColumnHost; // Column number on the line where the parse script text started
  42. ULONG lnMinHost; // Line offset of first host-supplied line
  43. ULONG ichMinHost; // Range of host supplied characters
  44. ULONG ichLimHost;
  45. ULONG ulCharOffset; // Char offset of the source text relative to the document. (Populated using IActiveScriptContext)
  46. Js::ModuleID moduleID;
  47. ULONG grfsi;
  48. static SRCINFO* Copy(Recycler* recycler, const SRCINFO* srcInfo)
  49. {
  50. SRCINFO* copySrcInfo = RecyclerNew(recycler, SRCINFO, *srcInfo);
  51. return copySrcInfo;
  52. }
  53. };
  54. struct CustomExternalObjectOperations
  55. {
  56. size_t offsetOfOperationsUsage;
  57. DWORD operationFlagEquals;
  58. DWORD operationFlagStrictEquals;
  59. };
  60. enum ExternalJitData
  61. {
  62. ExternalJitData_CustomExternalObjectOperations
  63. };
  64. enum LoadScriptFlag
  65. {
  66. LoadScriptFlag_None = 0x0,
  67. LoadScriptFlag_Expression = 0x1, // the script returns a value.
  68. LoadScriptFlag_disableDeferredParse = 0x2, // do not defer-parse the code.
  69. LoadScriptFlag_isByteCodeBufferForLibrary = 0x4, // for bytecode buffer
  70. LoadScriptFlag_disableAsmJs = 0x8, // disable parse as asmjs. The code is not conform to asmjs requirement.
  71. LoadScriptFlag_Module = 0x10, // input script is module code.
  72. LoadScriptFlag_isFunction = 0x20, // input script is in a function scope, not global code.
  73. LoadScriptFlag_Utf8Source = 0x40, // input buffer is utf8 encoded.
  74. LoadScriptFlag_LibraryCode = 0x80 // for debugger, indicating 'not my code'
  75. };
  76. class HostScriptContext
  77. {
  78. public:
  79. HostScriptContext(Js::ScriptContext* inScriptContext) { this->scriptContext = inScriptContext; }
  80. virtual void Delete() = 0;
  81. virtual HRESULT GetPreviousHostScriptContext(__deref_out HostScriptContext** ppUnkCaller) = 0;
  82. virtual HRESULT PushHostScriptContext() = 0;
  83. virtual void PopHostScriptContext() = 0;
  84. virtual HRESULT SetCaller(IUnknown *punkNew, IUnknown **ppunkPrev) = 0;
  85. virtual HRESULT GetDispatchExCaller(__deref_out void** dispatchExCaller) = 0;
  86. virtual void ReleaseDispatchExCaller(__in void* dispatchExCaler) = 0;
  87. virtual Js::ModuleRoot * GetModuleRoot(int moduleID) = 0;
  88. virtual HRESULT CheckCrossDomainScriptContext(__in Js::ScriptContext* scriptContext) = 0;
  89. virtual HRESULT GetHostContextUrl(__in DWORD_PTR hostSourceContext, __out BSTR& pUrl) = 0;
  90. virtual BOOL HasCaller() = 0;
  91. virtual void CleanDynamicCodeCache() = 0;
  92. virtual HRESULT VerifyDOMSecurity(Js::ScriptContext* targetContext, Js::Var obj) = 0;
  93. virtual HRESULT CheckEvalRestriction() = 0;
  94. virtual HRESULT HostExceptionFromHRESULT(HRESULT hr, Js::Var* outError) = 0;
  95. virtual HRESULT GetExternalJitData(ExternalJitData id, void *data) = 0;
  96. virtual HRESULT SetDispatchInvoke(Js::JavascriptMethod dispatchInvoke) = 0;
  97. virtual HRESULT ArrayBufferFromExternalObject(__in Js::RecyclableObject *obj,
  98. __out Js::ArrayBuffer **ppArrayBuffer) = 0;
  99. virtual Js::JavascriptError* CreateWinRTError(IErrorInfo* perrinfo, Js::RestrictedErrorStrings * proerrstr) = 0;
  100. virtual HRESULT EnqueuePromiseTask(Js::Var varTask) = 0;
  101. virtual HRESULT FetchImportedModule(Js::ModuleRecordBase* referencingModule, LPCOLESTR specifier, Js::ModuleRecordBase** dependentModuleRecord) = 0;
  102. virtual HRESULT NotifyHostAboutModuleReady(Js::ModuleRecordBase* referencingModule, Js::Var exceptionVar) = 0;
  103. Js::ScriptContext* GetScriptContext() { return scriptContext; }
  104. virtual bool SetCrossSiteForFunctionType(Js::JavascriptFunction * function) = 0;
  105. #if DBG_DUMP || defined(PROFILE_EXEC) || defined(PROFILE_MEM)
  106. virtual void EnsureParentInfo(Js::ScriptContext* scriptContext = NULL) = 0;
  107. #endif
  108. #if DBG
  109. virtual bool IsHostCrossSiteThunk(Js::JavascriptMethod address) = 0;
  110. #endif
  111. private:
  112. Js::ScriptContext* scriptContext;
  113. };
  114. #if ENABLE_TTD
  115. //A class that we use to pass in a functor from the host when we need to inform it about something we are doing
  116. class HostScriptContextCallbackFunctor
  117. {
  118. public:
  119. void* HostData;
  120. void(*pfOnScriptLoadCallback)(void* hostData, Js::JavascriptFunction* scriptFunction, Js::Utf8SourceInfo* utf8SourceInfo, CompileScriptException* compileException);
  121. HostScriptContextCallbackFunctor()
  122. : HostData(nullptr), pfOnScriptLoadCallback(nullptr)
  123. {
  124. ;
  125. }
  126. HostScriptContextCallbackFunctor(void* callbackData, void(*pfcallbackOnScriptLoad)(void* hostData, Js::JavascriptFunction* scriptFunction, Js::Utf8SourceInfo* utf8SourceInfo, CompileScriptException* compileException))
  127. : HostData(callbackData), pfOnScriptLoadCallback(pfcallbackOnScriptLoad)
  128. {
  129. ;
  130. }
  131. };
  132. #endif
  133. namespace Js
  134. {
  135. #pragma pack(push, 1)
  136. struct StackFrameInfo
  137. {
  138. StackFrameInfo() { }
  139. StackFrameInfo(DWORD_PTR _scriptContextID
  140. , UINT32 _sourceLocationLineNumber
  141. , UINT32 _sourceLocationColumnNumber
  142. , UINT32 _methodIDOrNameIndex
  143. , UINT8 _isFrameIndex)
  144. : scriptContextID(_scriptContextID)
  145. , sourceLocationLineNumber(_sourceLocationLineNumber)
  146. , sourceLocationColumnNumber(_sourceLocationColumnNumber)
  147. , methodIDOrNameIndex(_methodIDOrNameIndex)
  148. , isFrameIndex(_isFrameIndex)
  149. { }
  150. DWORD_PTR scriptContextID;
  151. UINT32 sourceLocationLineNumber;
  152. UINT32 sourceLocationColumnNumber;
  153. UINT32 methodIDOrNameIndex;
  154. UINT8 isFrameIndex;
  155. };
  156. #pragma pack(pop)
  157. #ifdef ENABLE_PROJECTION
  158. class ProjectionConfiguration
  159. {
  160. public:
  161. ProjectionConfiguration() : targetVersion(0)
  162. {
  163. }
  164. DWORD GetTargetVersion() const { return this->targetVersion; }
  165. void SetTargetVersion(DWORD version) { this->targetVersion = version; }
  166. bool IsTargetWindows8() const { return this->targetVersion == NTDDI_WIN8; }
  167. bool IsTargetWindowsBlueOrLater() const { return this->targetVersion >= NTDDI_WINBLUE; }
  168. private:
  169. DWORD targetVersion;
  170. };
  171. #endif // ENABLE_PROJECTION
  172. class ScriptConfiguration
  173. {
  174. public:
  175. ScriptConfiguration(const ThreadConfiguration * const threadConfig, const bool isOptimizedForManyInstances) :
  176. #ifdef ENABLE_PROJECTION
  177. HostType(Configuration::Global.flags.HostType),
  178. WinRTConstructorAllowed(Configuration::Global.flags.WinRTConstructorAllowed),
  179. #endif
  180. NoNative(Configuration::Global.flags.NoNative),
  181. isOptimizedForManyInstances(isOptimizedForManyInstances),
  182. threadConfig(threadConfig)
  183. {
  184. }
  185. // Version
  186. bool SupportsES3() const { return true; }
  187. bool SupportsES3Extensions() const {
  188. #ifdef ENABLE_PROJECTION
  189. return HostType != HostTypeApplication;
  190. #else
  191. return true;
  192. #endif
  193. }
  194. #define FORWARD_THREAD_CONFIG(flag) inline bool flag() const { return threadConfig->flag(); }
  195. #define FLAG(threadFlag, globalFlag) FORWARD_THREAD_CONFIG(threadFlag)
  196. #define FLAG_RELEASE(threadFlag, globalFlag) FORWARD_THREAD_CONFIG(threadFlag)
  197. #include "../Base/ThreadConfigFlagsList.h"
  198. #undef FLAG_RELEASE
  199. #undef FLAG
  200. #undef FORWARD_THREAD_CONFIG
  201. bool SupportsCollectGarbage() const { return true; }
  202. void ForceNoNative() { this->NoNative = true; }
  203. void ForceNative() { this->NoNative = false; }
  204. bool IsNoNative() const { return this->NoNative; }
  205. void SetCanOptimizeGlobalLookupFlag(BOOL f){ this->fCanOptimizeGlobalLookup = f;}
  206. BOOL CanOptimizeGlobalLookup() const { return this->fCanOptimizeGlobalLookup;}
  207. bool IsOptimizedForManyInstances() const { return isOptimizedForManyInstances; }
  208. void CopyFrom(ScriptConfiguration& other)
  209. {
  210. this->NoNative = other.NoNative;
  211. this->fCanOptimizeGlobalLookup = other.fCanOptimizeGlobalLookup;
  212. #ifdef ENABLE_PROJECTION
  213. this->HostType = other.HostType;
  214. this->WinRTConstructorAllowed = other.WinRTConstructorAllowed;
  215. this->projectionConfiguration = other.projectionConfiguration;
  216. #endif
  217. }
  218. #ifdef ENABLE_PROJECTION
  219. Number GetHostType() const // Returns one of enum HostType values (see ConfigFlagsTable.h).
  220. {
  221. AssertMsg(this->HostType >= HostTypeMin && this->HostType <= HostTypeMax, "HostType value is out of valid range.");
  222. return this->HostType;
  223. }
  224. ProjectionConfiguration const * GetProjectionConfig() const
  225. {
  226. return &projectionConfiguration;
  227. }
  228. void SetHostType(int32 hostType) { this->HostType = hostType; }
  229. void SetWinRTConstructorAllowed(bool allowed) { this->WinRTConstructorAllowed = allowed; }
  230. void SetProjectionTargetVersion(DWORD version)
  231. {
  232. projectionConfiguration.SetTargetVersion(version);
  233. }
  234. bool IsWinRTEnabled() const { return (GetHostType() == Js::HostTypeApplication) || (GetHostType() == Js::HostTypeWebview); }
  235. bool IsWinRTConstructorAllowed() const { return (GetHostType() != Js::HostTypeWebview) || this->WinRTConstructorAllowed; }
  236. #endif
  237. private:
  238. // Per script configurations
  239. bool NoNative;
  240. BOOL fCanOptimizeGlobalLookup;
  241. const bool isOptimizedForManyInstances;
  242. const ThreadConfiguration * const threadConfig;
  243. #ifdef ENABLE_PROJECTION
  244. Number HostType; // One of enum HostType values (see ConfigFlagsTable.h).
  245. bool WinRTConstructorAllowed; // whether allow constructor in webview host type. Also note that this is not a security feature.
  246. ProjectionConfiguration projectionConfiguration;
  247. #endif
  248. };
  249. struct ScriptEntryExitRecord
  250. {
  251. bool hasCaller : 1;
  252. bool hasReentered : 1;
  253. #if DBG_DUMP
  254. bool isCallRoot : 1;
  255. #endif
  256. #if DBG || defined(PROFILE_EXEC)
  257. bool leaveForHost : 1;
  258. #endif
  259. #if DBG
  260. bool leaveForAsyncHostOperation : 1;
  261. #endif
  262. #ifdef CHECK_STACKWALK_EXCEPTION
  263. bool ignoreStackWalkException: 1;
  264. #endif
  265. Js::ImplicitCallFlags savedImplicitCallFlags;
  266. void * returnAddrOfScriptEntryFunction;
  267. void * frameIdOfScriptExitFunction; // the frameAddres in x86, the return address in amd64/arm_soc
  268. ScriptContext * scriptContext;
  269. struct ScriptEntryExitRecord * next;
  270. #if defined(_M_IX86) && defined(DBG)
  271. void * scriptEntryFS0;
  272. #endif
  273. #ifdef EXCEPTION_CHECK
  274. ExceptionType handledExceptionType;
  275. #endif
  276. };
  277. static const unsigned int EvalMRUSize = 15;
  278. typedef JsUtil::BaseDictionary<DWORD_PTR, SourceContextInfo *, Recycler, PowerOf2SizePolicy> SourceContextInfoMap;
  279. typedef JsUtil::BaseDictionary<uint, SourceContextInfo *, Recycler, PowerOf2SizePolicy> DynamicSourceContextInfoMap;
  280. typedef JsUtil::BaseDictionary<EvalMapString, ScriptFunction*, RecyclerNonLeafAllocator, PrimeSizePolicy> SecondLevelEvalCache;
  281. typedef TwoLevelHashRecord<FastEvalMapString, ScriptFunction*, SecondLevelEvalCache, EvalMapString> EvalMapRecord;
  282. typedef JsUtil::Cache<FastEvalMapString, EvalMapRecord*, RecyclerNonLeafAllocator, PrimeSizePolicy, JsUtil::MRURetentionPolicy<FastEvalMapString, EvalMRUSize>, FastEvalMapStringComparer> EvalCacheTopLevelDictionary;
  283. typedef JsUtil::Cache<EvalMapString, ParseableFunctionInfo*, RecyclerNonLeafAllocator, PrimeSizePolicy, JsUtil::MRURetentionPolicy<EvalMapString, EvalMRUSize>> NewFunctionCache;
  284. typedef JsUtil::BaseDictionary<ParseableFunctionInfo*, ParseableFunctionInfo*, Recycler, PrimeSizePolicy, RecyclerPointerComparer> ParseableFunctionInfoMap;
  285. // This is the dictionary used by script context to cache the eval.
  286. typedef TwoLevelHashDictionary<FastEvalMapString, ScriptFunction*, EvalMapRecord, EvalCacheTopLevelDictionary, EvalMapString> EvalCacheDictionary;
  287. struct PropertyStringMap
  288. {
  289. PropertyString* strLen2[80];
  290. inline static uint PStrMapIndex(char16 ch)
  291. {
  292. Assert(ch >= '0' && ch <= 'z');
  293. return ch - '0';
  294. }
  295. };
  296. // valid if object!= NULL
  297. struct EnumeratedObjectCache {
  298. static const int kMaxCachedPropStrings=16;
  299. DynamicObject* object;
  300. DynamicType* type;
  301. PropertyString* propertyStrings[kMaxCachedPropStrings];
  302. int validPropStrings;
  303. };
  304. typedef JsUtil::BaseDictionary<JavascriptMethod, JavascriptFunction*, Recycler, PowerOf2SizePolicy> BuiltInLibraryFunctionMap;
  305. // this is allocated in GC directly to avoid force pinning the object, it is linked from JavascriptLibrary such that it has
  306. // the same lifetime as JavascriptLibrary, and it can be collected without ScriptContext Close.
  307. // Allocate it as Finalizable such that it will be still available during JavascriptLibrary Dispose time
  308. class Cache : public FinalizableObject
  309. {
  310. public:
  311. virtual void Finalize(bool isShutdown) override {}
  312. virtual void Dispose(bool isShutdown) override {}
  313. virtual void Mark(Recycler *recycler) override { AssertMsg(false, "Mark called on object that isn't TrackableObject"); }
  314. JavascriptString * lastNumberToStringRadix10String;
  315. EnumeratedObjectCache enumObjCache;
  316. JavascriptString * lastUtcTimeFromStrString;
  317. EvalCacheDictionary* evalCacheDictionary;
  318. EvalCacheDictionary* indirectEvalCacheDictionary;
  319. NewFunctionCache* newFunctionCache;
  320. RegexPatternMruMap *dynamicRegexMap;
  321. SourceContextInfoMap* sourceContextInfoMap; // maps host provided context cookie to the URL of the script buffer passed.
  322. DynamicSourceContextInfoMap* dynamicSourceContextInfoMap;
  323. SourceContextInfo* noContextSourceContextInfo;
  324. SRCINFO* noContextGlobalSourceInfo;
  325. SRCINFO const ** moduleSrcInfo;
  326. BuiltInLibraryFunctionMap* builtInLibraryFunctions;
  327. };
  328. class ScriptContext : public ScriptContextBase, public ScriptContextInfo
  329. {
  330. friend class LowererMD;
  331. friend class RemoteScriptContext;
  332. friend class GlobalObject; // InitializeCache
  333. friend class SourceTextModuleRecord; // for module bytecode gen.
  334. public:
  335. static DWORD GetThreadContextOffset() { return offsetof(ScriptContext, threadContext); }
  336. static DWORD GetOptimizationOverridesOffset() { return offsetof(ScriptContext, optimizationOverrides); }
  337. static DWORD GetRecyclerOffset() { return offsetof(ScriptContext, recycler); }
  338. static DWORD GetNumberAllocatorOffset() { return offsetof(ScriptContext, numberAllocator); }
  339. static DWORD GetAsmIntDbValOffset() { return offsetof(ScriptContext, retAsmIntDbVal); }
  340. ScriptContext *next;
  341. ScriptContext *prev;
  342. double retAsmIntDbVal; // stores the double & float result for Asm interpreter
  343. AsmJsSIMDValue retAsmSimdVal; // stores raw simd result for Asm interpreter
  344. static DWORD GetAsmSimdValOffset() { return offsetof(ScriptContext, retAsmSimdVal); }
  345. ScriptContextOptimizationOverrideInfo optimizationOverrides;
  346. Js::JavascriptMethod CurrentThunk;
  347. Js::JavascriptMethod CurrentCrossSiteThunk;
  348. Js::JavascriptMethod DeferredParsingThunk;
  349. Js::JavascriptMethod DeferredDeserializationThunk;
  350. Js::JavascriptMethod DispatchDefaultInvoke;
  351. Js::JavascriptMethod DispatchProfileInvoke;
  352. #ifdef ENABLE_SCRIPT_DEBUGGING
  353. typedef HRESULT (*GetDocumentContextFunction)(
  354. ScriptContext *pContext,
  355. Js::FunctionBody *pFunctionBody,
  356. IDebugDocumentContext **ppDebugDocumentContext);
  357. GetDocumentContextFunction GetDocumentContext;
  358. #endif // ENABLE_SCRIPT_DEBUGGING
  359. #ifdef ENABLE_SCRIPT_PROFILING
  360. typedef HRESULT (*CleanupDocumentContextFunction)(ScriptContext *pContext);
  361. CleanupDocumentContextFunction CleanupDocumentContext;
  362. #endif
  363. const ScriptContextBase* GetScriptContextBase() const { return static_cast<const ScriptContextBase*>(this); }
  364. bool DoUndeferGlobalFunctions() const;
  365. bool IsUndeclBlockVar(Var var) const { return this->javascriptLibrary->IsUndeclBlockVar(var); }
  366. void TrackPid(const PropertyRecord* propertyRecord);
  367. void TrackPid(PropertyId propertyId);
  368. bool IsTrackedPropertyId(Js::PropertyId propertyId);
  369. void InvalidateHostObjects()
  370. {
  371. AssertMsg(!isClosed, "Host Object invalidation should occur before the engine is fully closed. Figure our how isClosed got set beforehand.");
  372. isInvalidatedForHostObjects = true;
  373. }
  374. bool IsInvalidatedForHostObjects()
  375. {
  376. return isInvalidatedForHostObjects;
  377. }
  378. #if ENABLE_NATIVE_CODEGEN
  379. void InitializeRemoteScriptContext();
  380. #endif
  381. #ifdef ENABLE_JS_ETW
  382. void EmitStackTraceEvent(__in UINT64 operationID, __in USHORT maxFrameCount, bool emitV2AsyncStackEvent);
  383. #endif
  384. void SetIsDiagnosticsScriptContext(bool set) { this->isDiagnosticsScriptContext = set; }
  385. bool IsDiagnosticsScriptContext() const { return this->isDiagnosticsScriptContext; }
  386. bool IsScriptContextInNonDebugMode() const;
  387. bool IsScriptContextInDebugMode() const;
  388. bool IsScriptContextInSourceRundownOrDebugMode() const;
  389. bool IsRunningScript() const { return this->threadContext->GetScriptEntryExit() != nullptr; }
  390. typedef JsUtil::List<RecyclerWeakReference<Utf8SourceInfo>*, Recycler, false, Js::WeakRefFreeListedRemovePolicy> CalleeSourceList;
  391. RecyclerRootPtr<CalleeSourceList> calleeUtf8SourceInfoList;
  392. void AddCalleeSourceInfoToList(Utf8SourceInfo* sourceInfo);
  393. bool HaveCalleeSources() { return calleeUtf8SourceInfoList && !calleeUtf8SourceInfoList->Empty(); }
  394. template<class TMapFunction>
  395. void MapCalleeSources(TMapFunction map)
  396. {
  397. if (this->HaveCalleeSources())
  398. {
  399. calleeUtf8SourceInfoList->Map([&](uint i, RecyclerWeakReference<Js::Utf8SourceInfo>* sourceInfoWeakRef)
  400. {
  401. if (calleeUtf8SourceInfoList->IsItemValid(i))
  402. {
  403. Js::Utf8SourceInfo* sourceInfo = sourceInfoWeakRef->Get();
  404. map(sourceInfo);
  405. }
  406. });
  407. }
  408. if (calleeUtf8SourceInfoList)
  409. {
  410. calleeUtf8SourceInfoList.Unroot(this->GetRecycler());
  411. }
  412. }
  413. #ifdef ASMJS_PLAT
  414. inline AsmJsCodeGenerator* GetAsmJsCodeGenerator() const{return asmJsCodeGenerator;}
  415. AsmJsCodeGenerator* InitAsmJsCodeGenerator();
  416. #endif
  417. bool IsExceptionWrapperForBuiltInsEnabled();
  418. static bool IsExceptionWrapperForBuiltInsEnabled(ScriptContext* scriptContext);
  419. static bool IsExceptionWrapperForHelpersEnabled(ScriptContext* scriptContext);
  420. #ifdef ENABLE_SCRIPT_PROFILING
  421. bool IsEnumerateNonUserFunctionsOnly() const { return m_enumerateNonUserFunctionsOnly; }
  422. bool IsTraceDomCall() const { return !!m_fTraceDomCall; }
  423. #endif
  424. InlineCache * GetValueOfInlineCache() const { return valueOfInlineCache;}
  425. InlineCache * GetToStringInlineCache() const { return toStringInlineCache; }
  426. FunctionBody * GetFakeGlobalFuncForUndefer() const { return fakeGlobalFuncForUndefer; }
  427. void SetFakeGlobalFuncForUndefer(FunctionBody * func) { fakeGlobalFuncForUndefer.Root(func, GetRecycler()); }
  428. private:
  429. PropertyStringMap* propertyStrings[80];
  430. JavascriptFunction* GenerateRootFunction(ParseNodePtr parseTree, uint sourceIndex, Parser* parser, uint32 grfscr, CompileScriptException * pse, const char16 *rootDisplayName);
  431. typedef void (*EventHandler)(ScriptContext *);
  432. ScriptContext ** registeredPrototypeChainEnsuredToHaveOnlyWritableDataPropertiesScriptContext;
  433. ArenaAllocator generalAllocator;
  434. #ifdef ENABLE_BASIC_TELEMETRY
  435. ArenaAllocator telemetryAllocator;
  436. #endif
  437. ArenaAllocator dynamicProfileInfoAllocator;
  438. InlineCacheAllocator inlineCacheAllocator;
  439. CacheAllocator isInstInlineCacheAllocator;
  440. CacheAllocator forInCacheAllocator;
  441. ArenaAllocator* interpreterArena;
  442. ArenaAllocator* guestArena;
  443. ArenaAllocator* diagnosticArena;
  444. intptr_t m_remoteScriptContextAddr;
  445. bool startupComplete; // Indicates if the heuristic startup phase for this script context is complete
  446. bool isInvalidatedForHostObjects; // Indicates that we've invalidate all objects in the host so stop calling them.
  447. bool isEnumeratingRecyclerObjects; // Indicates this scriptContext is enumerating recycler objects. Used by recycler enumerating callbacks to filter out other unrelated scriptContexts.
  448. bool m_enumerateNonUserFunctionsOnly; // Indicates that recycler enumeration callback will consider only non-user functions (which are built-ins, external, winrt etc).
  449. ThreadContext* threadContext;
  450. TypeId directHostTypeId;
  451. InlineCache * valueOfInlineCache;
  452. InlineCache * toStringInlineCache;
  453. typedef JsUtil::BaseHashSet<Js::PropertyId, ArenaAllocator> PropIdSetForConstProp;
  454. PropIdSetForConstProp * intConstPropsOnGlobalObject;
  455. PropIdSetForConstProp * intConstPropsOnGlobalUserObject;
  456. void * firstInterpreterFrameReturnAddress;
  457. #ifdef SEPARATE_ARENA
  458. ArenaAllocator sourceCodeAllocator;
  459. ArenaAllocator regexAllocator;
  460. #endif
  461. #ifdef NEED_MISC_ALLOCATOR
  462. ArenaAllocator miscAllocator;
  463. #endif
  464. #if DBG
  465. JsUtil::BaseHashSet<void *, ArenaAllocator> bindRef;
  466. int m_iProfileSession;
  467. #endif
  468. #ifdef PROFILE_EXEC
  469. ScriptContextProfiler * profiler;
  470. bool isProfilerCreated;
  471. bool disableProfiler;
  472. bool ensureParentInfo;
  473. Profiler * CreateProfiler();
  474. #endif
  475. #ifdef PROFILE_MEM
  476. bool profileMemoryDump;
  477. #endif
  478. #ifdef PROFILE_STRINGS
  479. StringProfiler* stringProfiler;
  480. #endif
  481. RecyclerRootPtr<FunctionBody> fakeGlobalFuncForUndefer;
  482. public:
  483. #ifdef PROFILE_TYPES
  484. int convertNullToSimpleCount;
  485. int convertNullToSimpleDictionaryCount;
  486. int convertNullToDictionaryCount;
  487. int convertDeferredToDictionaryCount;
  488. int convertDeferredToSimpleDictionaryCount;
  489. int convertSimpleToDictionaryCount;
  490. int convertSimpleToSimpleDictionaryCount;
  491. int convertPathToDictionaryCount1;
  492. int convertPathToDictionaryCount2;
  493. int convertPathToDictionaryCount3;
  494. int convertPathToDictionaryCount4;
  495. int convertPathToSimpleDictionaryCount;
  496. int convertSimplePathToPathCount;
  497. int convertSimpleDictionaryToDictionaryCount;
  498. int convertSimpleSharedDictionaryToNonSharedCount;
  499. int convertSimpleSharedToNonSharedCount;
  500. int simplePathTypeHandlerCount;
  501. int pathTypeHandlerCount;
  502. int promoteCount;
  503. int cacheCount;
  504. int branchCount;
  505. int maxPathLength;
  506. int typeCount[TypeIds_Limit];
  507. int instanceCount[TypeIds_Limit];
  508. #endif
  509. #ifdef PROFILE_BAILOUT_RECORD_MEMORY
  510. __int64 bailOutRecordBytes;
  511. __int64 bailOutOffsetBytes;
  512. __int64 codeSize;
  513. #endif
  514. #ifdef PROFILE_OBJECT_LITERALS
  515. int objectLiteralInstanceCount;
  516. int objectLiteralPathCount;
  517. int objectLiteralCount[TypePath::MaxPathTypeHandlerLength];
  518. int objectLiteralSimpleDictionaryCount;
  519. uint32 objectLiteralMaxLength;
  520. int objectLiteralPromoteCount;
  521. int objectLiteralCacheCount;
  522. int objectLiteralBranchCount;
  523. #endif
  524. #if DBG_DUMP
  525. uint byteCodeDataSize;
  526. uint byteCodeAuxiliaryDataSize;
  527. uint byteCodeAuxiliaryContextDataSize;
  528. uint byteCodeHistogram[static_cast<uint>(OpCode::ByteCodeLast)];
  529. uint32 forinCache;
  530. uint32 forinNoCache;
  531. #endif
  532. #ifdef BGJIT_STATS
  533. uint interpretedCount;
  534. uint funcJITCount;
  535. uint loopJITCount;
  536. uint bytecodeJITCount;
  537. uint interpretedCallsHighPri;
  538. uint maxFuncInterpret;
  539. uint jitCodeUsed;
  540. uint funcJitCodeUsed;
  541. uint speculativeJitCount;
  542. #endif
  543. #ifdef REJIT_STATS
  544. // Used to store bailout stats
  545. typedef JsUtil::BaseDictionary<uint, uint, ArenaAllocator> BailoutStatsMap;
  546. struct RejitStats
  547. {
  548. uint *m_rejitReasonCounts;
  549. BailoutStatsMap* m_bailoutReasonCounts;
  550. uint m_totalRejits;
  551. uint m_totalBailouts;
  552. RejitStats(ScriptContext *scriptContext) : m_totalRejits(0), m_totalBailouts(0)
  553. {
  554. m_rejitReasonCounts = AnewArrayZ(scriptContext->GeneralAllocator(), uint, NumRejitReasons);
  555. m_bailoutReasonCounts = Anew(scriptContext->GeneralAllocator(), BailoutStatsMap, scriptContext->GeneralAllocator());
  556. }
  557. };
  558. void LogDataForFunctionBody(Js::FunctionBody *body, uint idx, bool isRejit);
  559. void LogRejit(Js::FunctionBody *body, uint reason);
  560. void LogBailout(Js::FunctionBody *body, uint kind);
  561. // Used to centrally collect stats for all function bodies.
  562. typedef JsUtil::WeaklyReferencedKeyDictionary<const Js::FunctionBody, RejitStats*> RejitStatsMap;
  563. RejitStatsMap* rejitStatsMap;
  564. BailoutStatsMap *bailoutReasonCounts;
  565. uint *rejitReasonCounts;
  566. #endif
  567. #ifdef ENABLE_BASIC_TELEMETRY
  568. private:
  569. ScriptContextTelemetry* telemetry;
  570. public:
  571. ScriptContextTelemetry& GetTelemetry();
  572. bool HasTelemetry();
  573. #endif
  574. #ifdef INLINE_CACHE_STATS
  575. // Used to store inline cache stats
  576. struct CacheData
  577. {
  578. uint hits;
  579. uint misses;
  580. uint collisions;
  581. bool isGetCache;
  582. Js::PropertyId propertyId;
  583. CacheData() : hits(0), misses(0), collisions(0), isGetCache(false), propertyId(Js::PropertyIds::_none) { }
  584. };
  585. // This is a strongly referenced dictionary, since we want to know hit rates for dead caches.
  586. typedef JsUtil::BaseDictionary<const Js::PolymorphicInlineCache*, CacheData*, Recycler> CacheDataMap;
  587. CacheDataMap *cacheDataMap;
  588. void LogCacheUsage(Js::PolymorphicInlineCache *cache, bool isGet, Js::PropertyId propertyId, bool hit, bool collision);
  589. #endif
  590. #ifdef FIELD_ACCESS_STATS
  591. typedef SList<FieldAccessStatsPtr, Recycler> FieldAccessStatsList;
  592. struct FieldAccessStatsEntry
  593. {
  594. RecyclerWeakReference<FunctionBody>* functionBodyWeakRef;
  595. FieldAccessStatsList stats;
  596. FieldAccessStatsEntry(RecyclerWeakReference<FunctionBody>* functionBodyWeakRef, Recycler* recycler)
  597. : functionBodyWeakRef(functionBodyWeakRef), stats(recycler) {}
  598. };
  599. typedef JsUtil::BaseDictionary<uint, FieldAccessStatsEntry*, Recycler> FieldAccessStatsByFunctionNumberMap;
  600. FieldAccessStatsByFunctionNumberMap* fieldAccessStatsByFunctionNumber;
  601. void RecordFieldAccessStats(FunctionBody* functionBody, FieldAccessStatsPtr fieldAccessStats);
  602. #endif
  603. #ifdef MISSING_PROPERTY_STATS
  604. int missingPropertyMisses;
  605. int missingPropertyHits;
  606. int missingPropertyCacheAttempts;
  607. void RecordMissingPropertyMiss();
  608. void RecordMissingPropertyHit();
  609. void RecordMissingPropertyCacheAttempt();
  610. #endif
  611. bool IsIntConstPropertyOnGlobalObject(Js::PropertyId propId);
  612. void TrackIntConstPropertyOnGlobalObject(Js::PropertyId propId);
  613. bool IsIntConstPropertyOnGlobalUserObject(Js::PropertyId propertyId);
  614. void TrackIntConstPropertyOnGlobalUserObject(Js::PropertyId propertyId);
  615. private:
  616. //
  617. // Regex globals
  618. //
  619. #if ENABLE_REGEX_CONFIG_OPTIONS
  620. UnifiedRegex::DebugWriter* regexDebugWriter;
  621. UnifiedRegex::RegexStatsDatabase* regexStatsDatabase;
  622. #endif
  623. UnifiedRegex::TrigramAlphabet* trigramAlphabet;
  624. UnifiedRegex::RegexStacks *regexStacks;
  625. JsUtil::Stack<Var>* operationStack;
  626. Recycler* recycler;
  627. RecyclerJavascriptNumberAllocator numberAllocator;
  628. ScriptConfiguration config;
  629. CharClassifier *charClassifier;
  630. // DisableJIT-TODO: Switch this to Dynamic thunk ifdef instead
  631. #if ENABLE_NATIVE_CODEGEN
  632. #if DYNAMIC_INTERPRETER_THUNK
  633. InterpreterThunkEmitter* interpreterThunkEmitter;
  634. #endif
  635. BackgroundParser *backgroundParser;
  636. #ifdef ASMJS_PLAT
  637. InterpreterThunkEmitter* asmJsInterpreterThunkEmitter;
  638. AsmJsCodeGenerator* asmJsCodeGenerator;
  639. typedef JsUtil::BaseDictionary<void *, SList<AsmJsScriptFunction *>*, ArenaAllocator> AsmFunctionMap;
  640. AsmFunctionMap* asmJsEnvironmentMap;
  641. ArenaAllocator* debugTransitionAlloc;
  642. #endif
  643. NativeCodeGenerator* nativeCodeGen;
  644. #endif
  645. DateTime::DaylightTimeHelper daylightTimeHelper;
  646. DateTime::Utility dateTimeUtility;
  647. public:
  648. inline const WCHAR *const GetStandardName(size_t *nameLength, DateTime::YMD *ymd = NULL)
  649. {
  650. return dateTimeUtility.GetStandardName(nameLength, ymd);
  651. }
  652. inline const WCHAR *const GetDaylightName(size_t *nameLength, DateTime::YMD *ymd = NULL)
  653. {
  654. return dateTimeUtility.GetDaylightName(nameLength, ymd);
  655. }
  656. private:
  657. HostScriptContext * hostScriptContext;
  658. HaltCallback* scriptEngineHaltCallback;
  659. EventHandler scriptStartEventHandler;
  660. EventHandler scriptEndEventHandler;
  661. #ifdef FAULT_INJECTION
  662. EventHandler disposeScriptByFaultInjectionEventHandler;
  663. #endif
  664. JsUtil::BaseDictionary<uint, JavascriptString *, ArenaAllocator> integerStringMap;
  665. double lastNumberToStringRadix10;
  666. double lastUtcTimeFromStr;
  667. #if ENABLE_PROFILE_INFO
  668. bool referencesSharedDynamicSourceContextInfo;
  669. #endif
  670. // We could delay the actual close after callRootLevel is 0.
  671. // this is to indicate the actual close is called once only.
  672. bool isScriptContextActuallyClosed;
  673. bool isFinalized;
  674. #if DBG
  675. bool isInitialized;
  676. bool isCloningGlobal;
  677. #endif
  678. bool fastDOMenabled;
  679. bool hasUsedInlineCache;
  680. bool hasProtoOrStoreFieldInlineCache;
  681. bool hasIsInstInlineCache;
  682. bool deferredBody;
  683. bool isPerformingNonreentrantWork;
  684. bool isDiagnosticsScriptContext; // mentions that current script context belongs to the diagnostics OM.
  685. size_t sourceSize;
  686. void CleanSourceListInternal(bool calledDuringMark);
  687. typedef JsUtil::List<RecyclerWeakReference<Utf8SourceInfo>*, Recycler, false, Js::FreeListedRemovePolicy> SourceList;
  688. RecyclerRootPtr<SourceList> sourceList;
  689. #ifdef ENABLE_SCRIPT_PROFILING
  690. IActiveScriptProfilerHeapEnum* heapEnum;
  691. // Profiler Probes
  692. // In future these can be list of callbacks ?
  693. // Profiler Callback information
  694. IActiveScriptProfilerCallback *m_pProfileCallback;
  695. BOOL m_fTraceFunctionCall;
  696. BOOL m_fTraceNativeFunctionCall;
  697. DWORD m_dwEventMask;
  698. IActiveScriptProfilerCallback2 *m_pProfileCallback2;
  699. BOOL m_fTraceDomCall;
  700. BOOL m_inProfileCallback;
  701. #endif // ENABLE_SCRIPT_PROFILING
  702. #if ENABLE_PROFILE_INFO
  703. #if DBG_DUMP || defined(DYNAMIC_PROFILE_STORAGE) || defined(RUNTIME_DATA_COLLECTION)
  704. RecyclerRootPtr<SListBase<DynamicProfileInfo *>> profileInfoList;
  705. #endif
  706. #endif
  707. // List of weak reference dictionaries. We'll walk through them
  708. // and clean them up post-collection
  709. // IWeakReferenceDictionary objects are added to this list by calling
  710. // RegisterWeakReferenceDictionary. If you use JsUtil::WeakReferenceDictionary,
  711. // which also exposes the IWeakReferenceDictionary interface, it'll
  712. // automatically register the dictionary on the script context
  713. SListBase<JsUtil::IWeakReferenceDictionary*> weakReferenceDictionaryList;
  714. bool isWeakReferenceDictionaryListCleared;
  715. typedef void(*RaiseMessageToDebuggerFunctionType)(ScriptContext *, DEBUG_EVENT_INFO_TYPE, LPCWSTR, LPCWSTR);
  716. RaiseMessageToDebuggerFunctionType raiseMessageToDebuggerFunctionType;
  717. typedef void(*TransitionToDebugModeIfFirstSourceFn)(ScriptContext *, Utf8SourceInfo *);
  718. TransitionToDebugModeIfFirstSourceFn transitionToDebugModeIfFirstSourceFn;
  719. ScriptContext(ThreadContext* threadContext);
  720. void InitializeAllocations();
  721. void InitializePreGlobal();
  722. void InitializePostGlobal();
  723. void InitializeCache();
  724. // Source Info
  725. void EnsureSourceContextInfoMap();
  726. void EnsureDynamicSourceContextInfoMap();
  727. uint moduleSrcInfoCount;
  728. #ifdef RUNTIME_DATA_COLLECTION
  729. time_t createTime;
  730. #endif
  731. char16 const * url;
  732. void PrintStats();
  733. BOOL LeaveScriptStartCore(void * frameAddress, bool leaveForHost);
  734. void InternalClose();
  735. DebugContext* debugContext;
  736. CriticalSection debugContextCloseCS;
  737. public:
  738. static const int kArrayMatchCh=72;
  739. static const int kMaxArrayMatchIndex=8192;
  740. short arrayMatchItems[kArrayMatchCh];
  741. bool arrayMatchInit;
  742. #ifdef LEAK_REPORT
  743. LeakReport::UrlRecord * urlRecord;
  744. bool isRootTrackerScriptContext;
  745. #endif
  746. DateTime::DaylightTimeHelper *GetDaylightTimeHelper() { return &daylightTimeHelper; }
  747. DateTime::Utility *GetDateUtility() { return &dateTimeUtility; }
  748. virtual bool IsClosed() const override { return isClosed; }
  749. void SetIsClosed();
  750. bool IsFinalized() const { return isFinalized; }
  751. void SetIsFinalized() { isFinalized = true; }
  752. bool IsActuallyClosed() const { return isScriptContextActuallyClosed; }
  753. #if ENABLE_NATIVE_CODEGEN
  754. bool IsClosedNativeCodeGenerator() const
  755. {
  756. return !nativeCodeGen || ::IsClosedNativeCodeGenerator(nativeCodeGen);
  757. }
  758. #endif
  759. void SetHasUsedInlineCache(bool value) { hasUsedInlineCache = value; }
  760. void SetDirectHostTypeId(TypeId typeId) {directHostTypeId = typeId; }
  761. TypeId GetDirectHostTypeId() const { return directHostTypeId; }
  762. intptr_t GetRemoteScriptAddr(bool allowInitialize = true)
  763. {
  764. #if ENABLE_OOP_NATIVE_CODEGEN
  765. if (!m_remoteScriptContextAddr && allowInitialize)
  766. {
  767. InitializeRemoteScriptContext();
  768. }
  769. #endif
  770. return m_remoteScriptContextAddr;
  771. }
  772. char16 const * GetUrl() const { return url; }
  773. void SetUrl(BSTR bstr);
  774. #ifdef RUNTIME_DATA_COLLECTION
  775. time_t GetCreateTime() const { return createTime; }
  776. uint GetAllocId() const { return allocId; }
  777. #endif
  778. void InitializeArrayMatch()
  779. {
  780. if (!arrayMatchInit)
  781. {
  782. for (int i=0;i<kArrayMatchCh;i++)
  783. {
  784. arrayMatchItems[i]= -1;
  785. }
  786. arrayMatchInit=true;
  787. }
  788. }
  789. #ifdef HEAP_ENUMERATION_VALIDATION
  790. bool IsInitialized() { return this->isInitialized; }
  791. #endif
  792. DebugContext* GetDebugContext() const { return this->debugContext; }
  793. CriticalSection* GetDebugContextCloseCS() { return &debugContextCloseCS; }
  794. uint callCount;
  795. // Guest arena allocated cache holding references that need to be pinned.
  796. Cache* cache;
  797. // if the current context is for webworker
  798. DWORD webWorkerId;
  799. static ScriptContext * New(ThreadContext * threadContext);
  800. static void Delete(ScriptContext* scriptContext);
  801. ~ScriptContext();
  802. #ifdef PROFILE_TYPES
  803. void ProfileTypes();
  804. #endif
  805. #ifdef PROFILE_OBJECT_LITERALS
  806. void ProfileObjectLiteral();
  807. #endif
  808. //
  809. // Regex helpers
  810. //
  811. #if ENABLE_REGEX_CONFIG_OPTIONS
  812. UnifiedRegex::RegexStatsDatabase* GetRegexStatsDatabase();
  813. UnifiedRegex::DebugWriter* GetRegexDebugWriter();
  814. #endif
  815. RegexPatternMruMap* GetDynamicRegexMap() const;
  816. UnifiedRegex::TrigramAlphabet* GetTrigramAlphabet() { return trigramAlphabet; }
  817. void SetTrigramAlphabet(UnifiedRegex::TrigramAlphabet * trigramAlphabet);
  818. UnifiedRegex::RegexStacks *RegexStacks();
  819. UnifiedRegex::RegexStacks *AllocRegexStacks();
  820. UnifiedRegex::RegexStacks *SaveRegexStacks();
  821. void RestoreRegexStacks(UnifiedRegex::RegexStacks *const contStack);
  822. void InitializeGlobalObject();
  823. bool IsIntlEnabled();
  824. JavascriptLibrary* GetLibrary() const { return javascriptLibrary; }
  825. const JavascriptLibraryBase* GetLibraryBase() const { return javascriptLibrary->GetLibraryBase(); }
  826. #if DBG
  827. BOOL IsCloningGlobal() const { return isCloningGlobal;}
  828. #endif
  829. void PushObject(Var object);
  830. Var PopObject();
  831. BOOL CheckObject(Var object);
  832. inline bool IsHeapEnumInProgress() { return GetRecycler()->IsHeapEnumInProgress(); }
  833. bool IsInterpreted() { return config.IsNoNative(); }
  834. void ForceNoNative() { config.ForceNoNative(); }
  835. void ForceNative() { config.ForceNative(); }
  836. ScriptConfiguration const * GetConfig(void) const { return &config; }
  837. CharClassifier const * GetCharClassifier(void) const;
  838. ThreadContext * GetThreadContext() const { return threadContext; }
  839. static const int MaxEvalSourceSize = 400;
  840. bool IsInEvalMap(FastEvalMapString const& key, BOOL isIndirect, ScriptFunction **ppFuncScript);
  841. void AddToEvalMap(FastEvalMapString const& key, BOOL isIndirect, ScriptFunction *pFuncScript);
  842. template <typename TCacheType>
  843. void CleanDynamicFunctionCache(TCacheType* cacheType);
  844. void CleanEvalMapCache(Js::EvalCacheTopLevelDictionary * cacheType);
  845. template <class TDelegate>
  846. void MapFunction(TDelegate mapper);
  847. template <class TDelegate>
  848. FunctionBody* FindFunction(TDelegate predicate);
  849. inline bool EnableEvalMapCleanup() { return CONFIG_FLAG(EnableEvalMapCleanup); };
  850. uint GetNextSourceContextId();
  851. bool IsInNewFunctionMap(EvalMapString const& key, ParseableFunctionInfo **ppFuncBody);
  852. void AddToNewFunctionMap(EvalMapString const& key, ParseableFunctionInfo *pFuncBody);
  853. SourceContextInfo * GetSourceContextInfo(DWORD_PTR hostSourceContext, IActiveScriptDataCache* profileDataCache);
  854. SourceContextInfo * GetSourceContextInfo(uint hash);
  855. SourceContextInfo * CreateSourceContextInfo(uint hash, DWORD_PTR hostSourceContext);
  856. SourceContextInfo * CreateSourceContextInfo(DWORD_PTR hostSourceContext, char16 const * url, size_t len,
  857. IActiveScriptDataCache* profileDataCache, char16 const * sourceMapUrl = nullptr, size_t sourceMapUrlLen = 0);
  858. #if defined(LEAK_REPORT) || defined(CHECK_MEMORY_LEAK)
  859. void ClearSourceContextInfoMaps()
  860. {
  861. if (this->cache != nullptr)
  862. {
  863. this->cache->sourceContextInfoMap = nullptr;
  864. this->cache->dynamicSourceContextInfoMap = nullptr;
  865. #if ENABLE_PROFILE_INFO
  866. this->referencesSharedDynamicSourceContextInfo = false;
  867. #endif
  868. }
  869. }
  870. #endif
  871. #if ENABLE_PROFILE_INFO
  872. #if DBG_DUMP || defined(DYNAMIC_PROFILE_STORAGE) || defined(RUNTIME_DATA_COLLECTION)
  873. void ClearDynamicProfileList()
  874. {
  875. if (profileInfoList)
  876. {
  877. profileInfoList->Reset();
  878. profileInfoList.Unroot(this->recycler);
  879. }
  880. }
  881. SListBase<DynamicProfileInfo *> * GetProfileInfoList() { return profileInfoList; }
  882. #endif
  883. #endif
  884. SRCINFO const * GetModuleSrcInfo(Js::ModuleID moduleID);
  885. SourceContextInfoMap* GetSourceContextInfoMap()
  886. {
  887. return (this->cache ? this->cache->sourceContextInfoMap : nullptr);
  888. }
  889. DynamicSourceContextInfoMap* GetDynamicSourceContextInfoMap()
  890. {
  891. return (this->cache ? this->cache->dynamicSourceContextInfoMap : nullptr);
  892. }
  893. #if ENABLE_TTD
  894. //The host callback functor info
  895. HostScriptContextCallbackFunctor TTDHostCallbackFunctor;
  896. //The TTDMode for this script context (the same as the Mode for the thread context but we put it here for fast lookup when identity tagging)
  897. TTD::TTDMode TTDMode;
  898. //The LogTag for this script context (the same as the tag for the global object but we put it here for fast lookup)
  899. TTD_LOG_PTR_ID ScriptContextLogTag;
  900. //Keep track of the number of re-entrant calls currently pending (i.e., if we make an external call it may call back into Chakra)
  901. int32 TTDRootNestingCount;
  902. //Info about the core image for the context
  903. TTD::RuntimeContextInfo* TTDWellKnownInfo;
  904. //Additional runtime context that we only care about if TTD is running (or will be running)
  905. TTD::ScriptContextTTD* TTDContextInfo;
  906. ////
  907. //Use this to check specifically if we are in record AND this code is being run on behalf of the user application
  908. bool ShouldPerformRecordAction() const
  909. {
  910. //return true if RecordEnabled and ~ExcludedExecution
  911. return (this->TTDMode & TTD::TTDMode::TTDShouldRecordActionMask) == TTD::TTDMode::RecordEnabled;
  912. }
  913. //Use this to check specifically if we are in debugging mode AND this code is being run on behalf of the user application
  914. bool ShouldPerformDebugAction() const
  915. {
  916. #if ENABLE_TTD_DEBUGGING
  917. //return true if DebuggingEnabled and ~ExcludedExecution
  918. return (this->TTDMode & TTD::TTDMode::TTDShouldDebugActionMask) == TTD::TTDMode::DebuggingEnabled;
  919. #else
  920. return false;
  921. #endif
  922. }
  923. //Use this to check if the TTD has been set into record/replay mode (although we still need to check if we should do any record ro replay)
  924. bool IsTTDActive() const
  925. {
  926. return (this->TTDMode & TTD::TTDMode::TTDActive) != TTD::TTDMode::Invalid;
  927. }
  928. //Use this to check if the TTD has been detached (e.g., has traced a context execution and has now been detached)
  929. bool IsTTDDetached() const
  930. {
  931. return (this->TTDMode & TTD::TTDMode::Detached) != TTD::TTDMode::Invalid;
  932. }
  933. //
  934. //TODO: there is a memory leak associated with this we need to relax later
  935. //
  936. //A special record check because we want to pin weak references even if we aren't actively logging (but are planning to do so in the future)
  937. bool ShouldPerformWeakRefPinAction() const
  938. {
  939. bool modeIsPending = (this->TTDMode & TTD::TTDMode::Pending) == TTD::TTDMode::Pending;
  940. bool modeIsRecord = (this->TTDMode & TTD::TTDMode::RecordEnabled) == TTD::TTDMode::RecordEnabled;
  941. bool modeIsDebugging = (this->TTDMode & TTD::TTDMode::DebuggingEnabled) == TTD::TTDMode::DebuggingEnabled;
  942. bool inDebugableCode = (this->TTDMode & TTD::TTDMode::ExcludedExecution) == TTD::TTDMode::Invalid;
  943. return ((modeIsPending | modeIsRecord | modeIsDebugging) & inDebugableCode);
  944. }
  945. //A special record check because we want to record code load even if we aren't actively logging (but are planning to do so in the future)
  946. bool ShouldPerformRecordTopLevelFunction() const
  947. {
  948. bool modeIsPending = (this->TTDMode & TTD::TTDMode::Pending) == TTD::TTDMode::Pending;
  949. bool modeIsRecord = (this->TTDMode & TTD::TTDMode::RecordEnabled) == TTD::TTDMode::RecordEnabled;
  950. bool inDebugableCode = (this->TTDMode & TTD::TTDMode::ExcludedExecution) == TTD::TTDMode::Invalid;
  951. return ((modeIsPending | modeIsRecord) & inDebugableCode);
  952. }
  953. //A special record check because we want to record root add/remove ref even if we aren't actively logging (but are planning to do so in the future)
  954. bool ShouldPerformRootAddOrRemoveRefAction() const
  955. {
  956. bool modeIsPending = (this->TTDMode & TTD::TTDMode::Pending) == TTD::TTDMode::Pending;
  957. bool modeIsRecord = (this->TTDMode & TTD::TTDMode::RecordEnabled) == TTD::TTDMode::RecordEnabled;
  958. bool inDebugableCode = (this->TTDMode & TTD::TTDMode::ExcludedExecution) == TTD::TTDMode::Invalid;
  959. return ((modeIsPending | modeIsRecord) & inDebugableCode);
  960. }
  961. //A special record check because we want to take action on async buffer registration and completion even if we have not started actively logging (but are planning to do so in the future)
  962. bool ShouldPerformAsyncBufferModAction() const
  963. {
  964. bool modeIsPending = (this->TTDMode & TTD::TTDMode::Pending) == TTD::TTDMode::Pending;
  965. bool modeIsRecord = (this->TTDMode & TTD::TTDMode::RecordEnabled) == TTD::TTDMode::RecordEnabled;
  966. bool inDebugableCode = (this->TTDMode & TTD::TTDMode::ExcludedExecution) == TTD::TTDMode::Invalid;
  967. return ((modeIsPending | modeIsRecord) & inDebugableCode);
  968. }
  969. //A special check for to see if we want to push the supression flag for getter exection
  970. bool ShouldDoGetterInvocationSupression() const
  971. {
  972. #if !ENABLE_TTD_DEBUGGING
  973. return false;
  974. #else
  975. return (this->TTDMode & TTD::TTDMode::DebuggingEnabled) == TTD::TTDMode::DebuggingEnabled;
  976. #endif
  977. }
  978. //A special check to see if we are debugging and want to suppress the execution of getters when displaying values in the debugger
  979. bool ShouldSuppressGetterInvocationForDebuggerEvaluation() const
  980. {
  981. #if !ENABLE_TTD_DEBUGGING
  982. return false;
  983. #else
  984. return (this->TTDMode & TTD::TTDMode::TTDShouldSupressGetterActionMask) == TTD::TTDMode::TTDShouldSupressGetterActionMask;
  985. #endif
  986. }
  987. //A special check to see if we are in the process of a time-travel move and do not want to stop at any breakpoints
  988. bool ShouldSuppressBreakpointsForTimeTravelMove() const
  989. {
  990. #if !ENABLE_TTD_DEBUGGING
  991. return false;
  992. #else
  993. return (this->TTDMode & TTD::TTDMode::DebuggerSuppressBreakpoints) == TTD::TTDMode::DebuggerSuppressBreakpoints;
  994. #endif
  995. }
  996. //A special check to see if we are in the process of a time-travel move and do not want to stop at any breakpoints
  997. bool ShouldRecordBreakpointsDuringTimeTravelScan() const
  998. {
  999. #if !ENABLE_TTD_DEBUGGING
  1000. return false;
  1001. #else
  1002. return (this->TTDMode & TTD::TTDMode::DebuggerLogBreakpoints) == TTD::TTDMode::DebuggerLogBreakpoints;
  1003. #endif
  1004. }
  1005. //
  1006. //TODO: this is currently called explicitly -- we need to fix up the core image computation and this will be eliminated then
  1007. //
  1008. //Initialize the core object image for TTD
  1009. void InitializeCoreImage_TTD();
  1010. //Initialize debug script generation and no-native as needed for replay/debug at script context initialization
  1011. void InitializeRecordingActionsAsNeeded_TTD();
  1012. void InitializeDebuggingActionsAsNeeded_TTD();
  1013. #endif
  1014. void SetFirstInterpreterFrameReturnAddress(void * returnAddress) { firstInterpreterFrameReturnAddress = returnAddress;}
  1015. void *GetFirstInterpreterFrameReturnAddress() { return firstInterpreterFrameReturnAddress;}
  1016. void CleanupWeakReferenceDictionaries();
  1017. void Initialize();
  1018. bool Close(bool inDestructor);
  1019. void MarkForClose();
  1020. #ifdef ENABLE_PROJECTION
  1021. void SetHostType(int32 hostType) { config.SetHostType(hostType); }
  1022. void SetWinRTConstructorAllowed(bool allowed) { config.SetWinRTConstructorAllowed(allowed); }
  1023. void SetProjectionTargetVersion(DWORD version) { config.SetProjectionTargetVersion(version); }
  1024. #endif
  1025. void SetCanOptimizeGlobalLookupFlag(BOOL f){ config.SetCanOptimizeGlobalLookupFlag(f);}
  1026. BOOL CanOptimizeGlobalLookup(){ return config.CanOptimizeGlobalLookup();}
  1027. bool IsFastDOMEnabled() { return fastDOMenabled; }
  1028. void SetFastDOMenabled();
  1029. BOOL VerifyAlive(BOOL isJSFunction = FALSE, ScriptContext* requestScriptContext = nullptr);
  1030. void VerifyAliveWithHostContext(BOOL isJSFunction, HostScriptContext* requestHostScriptContext);
  1031. void AddFunctionBodyToPropIdMap(FunctionBody* body);
  1032. void BindReference(void* addr);
  1033. void InitPropertyStringMap(int i);
  1034. PropertyString* AddPropertyString2(const Js::PropertyRecord* propertyRecord);
  1035. PropertyString* CachePropertyString2(const Js::PropertyRecord* propertyRecord);
  1036. PropertyString* GetPropertyString2(char16 ch1, char16 ch2);
  1037. void FindPropertyRecord(__in LPCWSTR pszPropertyName, __in int propertyNameLength, PropertyRecord const** propertyRecord);
  1038. JsUtil::List<const RecyclerWeakReference<Js::PropertyRecord const>*>* FindPropertyIdNoCase(__in LPCWSTR pszPropertyName, __in int propertyNameLength);
  1039. void FindPropertyRecord(JavascriptString* pstName, PropertyRecord const** propertyRecord);
  1040. PropertyRecord const * GetPropertyName(PropertyId propertyId);
  1041. PropertyRecord const * GetPropertyNameLocked(PropertyId propertyId);
  1042. void GetOrAddPropertyRecord(JsUtil::CharacterBuffer<WCHAR> const& propName, PropertyRecord const** propertyRecord);
  1043. template <size_t N> void GetOrAddPropertyRecord(const char16(&propertyName)[N], PropertyRecord const** propertyRecord)
  1044. {
  1045. GetOrAddPropertyRecord(propertyName, N - 1, propertyRecord);
  1046. }
  1047. PropertyId GetOrAddPropertyIdTracked(JsUtil::CharacterBuffer<WCHAR> const& propName);
  1048. template <size_t N> PropertyId GetOrAddPropertyIdTracked(const char16(&propertyName)[N])
  1049. {
  1050. return GetOrAddPropertyIdTracked(propertyName, N - 1);
  1051. }
  1052. PropertyId GetOrAddPropertyIdTracked(__in_ecount(propertyNameLength) LPCWSTR pszPropertyName, __in int propertyNameLength);
  1053. void GetOrAddPropertyRecord(__in_ecount(propertyNameLength) LPCWSTR pszPropertyName, __in int propertyNameLength, PropertyRecord const** propertyRecord);
  1054. BOOL IsNumericPropertyId(PropertyId propertyId, uint32* value);
  1055. void RegisterWeakReferenceDictionary(JsUtil::IWeakReferenceDictionary* weakReferenceDictionary);
  1056. void ResetWeakReferenceDictionaryList() { weakReferenceDictionaryList.Reset(); }
  1057. BOOL ReserveStaticTypeIds(__in int first, __in int last);
  1058. TypeId ReserveTypeIds(int count);
  1059. TypeId CreateTypeId();
  1060. WellKnownHostType GetWellKnownHostType(Js::TypeId typeId) { return threadContext->GetWellKnownHostType(typeId); }
  1061. void SetWellKnownHostTypeId(WellKnownHostType wellKnownType, Js::TypeId typeId) { threadContext->SetWellKnownHostTypeId(wellKnownType, typeId); }
  1062. ParseNodePtr ParseScript(Parser* parser, const byte* script, size_t cb, SRCINFO const * pSrcInfo,
  1063. CompileScriptException * pse, Utf8SourceInfo** ppSourceInfo, const char16 *rootDisplayName, LoadScriptFlag loadScriptFlag, uint* sourceIndex);
  1064. JavascriptFunction* LoadScript(const byte* script, size_t cb, SRCINFO const * pSrcInfo,
  1065. CompileScriptException * pse, Utf8SourceInfo** ppSourceInfo, const char16 *rootDisplayName, LoadScriptFlag loadScriptFlag);
  1066. ArenaAllocator* GeneralAllocator() { return &generalAllocator; }
  1067. #ifdef ENABLE_BASIC_TELEMETRY
  1068. ArenaAllocator* TelemetryAllocator() { return &telemetryAllocator; }
  1069. #endif
  1070. #ifdef SEPARATE_ARENA
  1071. ArenaAllocator* SourceCodeAllocator() { return &sourceCodeAllocator; }
  1072. ArenaAllocator* RegexAllocator() { return &regexAllocator; }
  1073. #else
  1074. ArenaAllocator* SourceCodeAllocator() { return &generalAllocator; }
  1075. ArenaAllocator* RegexAllocator() { return &generalAllocator; }
  1076. #endif
  1077. #ifdef NEED_MISC_ALLOCATOR
  1078. ArenaAllocator* MiscAllocator() { return &miscAllocator; }
  1079. #endif
  1080. InlineCacheAllocator* GetInlineCacheAllocator() { return &inlineCacheAllocator; }
  1081. CacheAllocator* GetIsInstInlineCacheAllocator() { return &isInstInlineCacheAllocator; }
  1082. CacheAllocator * ForInCacheAllocator() { return &forInCacheAllocator; }
  1083. ArenaAllocator* DynamicProfileInfoAllocator() { return &dynamicProfileInfoAllocator; }
  1084. ArenaAllocator* AllocatorForDiagnostics();
  1085. Js::TempArenaAllocatorObject* GetTemporaryAllocator(LPCWSTR name);
  1086. void ReleaseTemporaryAllocator(Js::TempArenaAllocatorObject* tempAllocator);
  1087. Js::TempGuestArenaAllocatorObject* GetTemporaryGuestAllocator(LPCWSTR name);
  1088. void ReleaseTemporaryGuestAllocator(Js::TempGuestArenaAllocatorObject* tempAllocator);
  1089. bool EnsureInterpreterArena(ArenaAllocator **);
  1090. void ReleaseInterpreterArena();
  1091. ArenaAllocator* GetGuestArena() const
  1092. {
  1093. return guestArena;
  1094. }
  1095. void ReleaseGuestArena();
  1096. Recycler* GetRecycler() const { return recycler; }
  1097. RecyclerJavascriptNumberAllocator * GetNumberAllocator() { return &numberAllocator; }
  1098. #if ENABLE_NATIVE_CODEGEN
  1099. NativeCodeGenerator * GetNativeCodeGenerator() const { return nativeCodeGen; }
  1100. #endif
  1101. #if ENABLE_BACKGROUND_PARSING
  1102. BackgroundParser * GetBackgroundParser() const { return backgroundParser; }
  1103. #endif
  1104. void OnScriptStart(bool isRoot, bool isScript);
  1105. void OnScriptEnd(bool isRoot, bool isForcedEnd);
  1106. template <bool stackProbe, bool leaveForHost>
  1107. bool LeaveScriptStart(void * frameAddress);
  1108. template <bool leaveForHost>
  1109. void LeaveScriptEnd(void * frameAddress);
  1110. HostScriptContext * GetHostScriptContext() const { return hostScriptContext; }
  1111. void SetHostScriptContext(HostScriptContext * hostScriptContext);
  1112. void SetScriptEngineHaltCallback(HaltCallback* scriptEngine);
  1113. void ClearHostScriptContext();
  1114. IActiveScriptProfilerHeapEnum* GetHeapEnum();
  1115. void SetHeapEnum(IActiveScriptProfilerHeapEnum* newHeapEnum);
  1116. void ClearHeapEnum();
  1117. void SetScriptStartEventHandler(EventHandler eventHandler);
  1118. void SetScriptEndEventHandler(EventHandler eventHandler);
  1119. #ifdef FAULT_INJECTION
  1120. void DisposeScriptContextByFaultInjection();
  1121. void SetDisposeDisposeByFaultInjectionEventHandler(EventHandler eventHandler);
  1122. #endif
  1123. EnumeratedObjectCache* GetEnumeratedObjectCache() { return &(cache->enumObjCache); }
  1124. PropertyString* TryGetPropertyString(PropertyId propertyId);
  1125. PropertyString* GetPropertyString(PropertyId propertyId);
  1126. void InvalidatePropertyStringCache(PropertyId propertyId, Type* type);
  1127. JavascriptString* GetIntegerString(Var aValue);
  1128. JavascriptString* GetIntegerString(int value);
  1129. JavascriptString* GetIntegerString(uint value);
  1130. void CheckEvalRestriction();
  1131. RecyclableObject* GetMissingPropertyResult();
  1132. RecyclableObject* GetMissingItemResult();
  1133. bool HasRecordedException() const { return threadContext->GetRecordedException() != nullptr; }
  1134. Js::JavascriptExceptionObject * GetAndClearRecordedException(bool *considerPassingToDebugger = nullptr);
  1135. void RecordException(Js::JavascriptExceptionObject * exceptionObject, bool propagateToDebugger = false);
  1136. __declspec(noreturn) void RethrowRecordedException(JavascriptExceptionObject::HostWrapperCreateFuncType hostWrapperCreateFunc);
  1137. #if ENABLE_NATIVE_CODEGEN
  1138. BOOL IsNativeAddress(void * codeAddr);
  1139. #endif
  1140. uint SaveSourceCopy(Utf8SourceInfo* sourceInfo, int cchLength, bool isCesu8);
  1141. bool SaveSourceCopy(Utf8SourceInfo* const sourceInfo, int cchLength, bool isCesu8, uint * index);
  1142. uint SaveSourceNoCopy(Utf8SourceInfo* sourceInfo, int cchLength, bool isCesu8);
  1143. void CloneSources(ScriptContext* sourceContext);
  1144. Utf8SourceInfo* GetSource(uint sourceIndex);
  1145. uint SourceCount() const { return (uint)sourceList->Count(); }
  1146. void CleanSourceList() { CleanSourceListInternal(false); }
  1147. SourceList* GetSourceList() const { return sourceList; }
  1148. bool IsItemValidInSourceList(int index);
  1149. template <typename TFunction>
  1150. void MapScript(TFunction mapper)
  1151. {
  1152. this->sourceList->Map([mapper] (int, RecyclerWeakReference<Utf8SourceInfo>* sourceInfoWeakReference)
  1153. {
  1154. Utf8SourceInfo* strongRef = sourceInfoWeakReference->Get();
  1155. if (strongRef)
  1156. {
  1157. mapper(strongRef);
  1158. }
  1159. });
  1160. }
  1161. #ifdef CHECK_STACKWALK_EXCEPTION
  1162. void SetIgnoreStackWalkException() {threadContext->GetScriptEntryExit()->ignoreStackWalkException = true; }
  1163. #endif
  1164. // For debugging scenarios where execution will go to debugging manager and come back to engine again, enforce the current EER to have
  1165. // 'hasCaller' property set, which will enable the stack walking across frames.
  1166. // Do not call this directly, look for ENFORCE_ENTRYEXITRECORD_HASCALLER macro.
  1167. void EnforceEERHasCaller() { threadContext->GetScriptEntryExit()->hasCaller = true; }
  1168. void SetRaiseMessageToDebuggerFunction(RaiseMessageToDebuggerFunctionType function)
  1169. {
  1170. raiseMessageToDebuggerFunctionType = function;
  1171. }
  1172. void RaiseMessageToDebugger(DEBUG_EVENT_INFO_TYPE messageType, LPCWSTR message, LPCWSTR url)
  1173. {
  1174. if (raiseMessageToDebuggerFunctionType != nullptr)
  1175. {
  1176. raiseMessageToDebuggerFunctionType(this, messageType, message, url);
  1177. }
  1178. }
  1179. void SetTransitionToDebugModeIfFirstSourceFn(TransitionToDebugModeIfFirstSourceFn function)
  1180. {
  1181. transitionToDebugModeIfFirstSourceFn = function;
  1182. }
  1183. void TransitionToDebugModeIfFirstSource(Utf8SourceInfo *sourceInfo)
  1184. {
  1185. if (transitionToDebugModeIfFirstSourceFn != nullptr)
  1186. {
  1187. transitionToDebugModeIfFirstSourceFn(this, sourceInfo);
  1188. }
  1189. }
  1190. void AddSourceSize(size_t sourceSize)
  1191. {
  1192. this->sourceSize += sourceSize;
  1193. this->threadContext->AddSourceSize(sourceSize);
  1194. }
  1195. size_t GetSourceSize()
  1196. {
  1197. return this->sourceSize;
  1198. }
  1199. BOOL SetDeferredBody(BOOL set)
  1200. {
  1201. bool old = this->deferredBody;
  1202. this->deferredBody = !!set;
  1203. return old;
  1204. }
  1205. BOOL GetDeferredBody(void) const
  1206. {
  1207. return this->deferredBody;
  1208. }
  1209. public:
  1210. void FreeFunctionEntryPoint(Js::JavascriptMethod method);
  1211. private:
  1212. uint CloneSource(Utf8SourceInfo* info);
  1213. public:
  1214. void RegisterProtoInlineCache(InlineCache *pCache, PropertyId propId);
  1215. void InvalidateProtoCaches(const PropertyId propertyId);
  1216. void InvalidateAllProtoCaches();
  1217. void RegisterStoreFieldInlineCache(InlineCache *pCache, PropertyId propId);
  1218. void InvalidateStoreFieldCaches(const PropertyId propertyId);
  1219. void InvalidateAllStoreFieldCaches();
  1220. void RegisterIsInstInlineCache(Js::IsInstInlineCache * cache, Js::Var function);
  1221. #if DBG
  1222. bool IsIsInstInlineCacheRegistered(Js::IsInstInlineCache * cache, Js::Var function);
  1223. #endif
  1224. void ClearInlineCaches();
  1225. void ClearIsInstInlineCaches();
  1226. void ClearForInCaches();
  1227. #ifdef PERSISTENT_INLINE_CACHES
  1228. void ClearInlineCachesWithDeadWeakRefs();
  1229. #endif
  1230. void ClearScriptContextCaches();
  1231. #if ENABLE_NATIVE_CODEGEN
  1232. void RegisterConstructorCache(Js::PropertyId propertyId, Js::ConstructorCache* cache);
  1233. #endif
  1234. public:
  1235. void RegisterPrototypeChainEnsuredToHaveOnlyWritableDataPropertiesScriptContext();
  1236. private:
  1237. void DoRegisterPrototypeChainEnsuredToHaveOnlyWritableDataPropertiesScriptContext();
  1238. public:
  1239. void ClearPrototypeChainEnsuredToHaveOnlyWritableDataPropertiesCaches();
  1240. public:
  1241. JavascriptString * GetLastNumberToStringRadix10(double value);
  1242. void SetLastNumberToStringRadix10(double value, JavascriptString * str);
  1243. bool GetLastUtcTimeFromStr(JavascriptString * str, double& dbl);
  1244. void SetLastUtcTimeFromStr(JavascriptString * str, double value);
  1245. bool IsNoContextSourceContextInfo(SourceContextInfo *sourceContextInfo) const
  1246. {
  1247. return sourceContextInfo == cache->noContextSourceContextInfo;
  1248. }
  1249. BOOL IsProfiling()
  1250. {
  1251. #ifdef ENABLE_SCRIPT_PROFILING
  1252. return (m_pProfileCallback != nullptr);
  1253. #else
  1254. return FALSE;
  1255. #endif
  1256. }
  1257. BOOL IsInProfileCallback()
  1258. {
  1259. #ifdef ENABLE_SCRIPT_PROFILING
  1260. return m_inProfileCallback;
  1261. #else
  1262. return FALSE;
  1263. #endif
  1264. }
  1265. #if DBG
  1266. SourceContextInfo const * GetNoContextSourceContextInfo() const { return cache->noContextSourceContextInfo; }
  1267. #ifdef ENABLE_SCRIPT_PROFILING
  1268. int GetProfileSession()
  1269. {
  1270. AssertMsg(m_pProfileCallback != nullptr, "Asking for profile session when we aren't in one.");
  1271. return m_iProfileSession;
  1272. }
  1273. void StartNewProfileSession()
  1274. {
  1275. AssertMsg(m_pProfileCallback != nullptr, "New Session when the profiler isn't set to any callback.");
  1276. m_iProfileSession++;
  1277. }
  1278. void StopProfileSession()
  1279. {
  1280. AssertMsg(m_pProfileCallback == nullptr, "How to stop when there is still the callback out there");
  1281. }
  1282. #endif // ENABLE_SCRIPT_PROFILING
  1283. bool hadProfiled;
  1284. bool HadProfiled() const { return hadProfiled; }
  1285. #endif
  1286. SRCINFO *AddHostSrcInfo(SRCINFO const *pSrcInfo);
  1287. inline void CoreSetProfileEventMask(DWORD dwEventMask);
  1288. typedef HRESULT (*RegisterExternalLibraryType)(Js::ScriptContext *pScriptContext);
  1289. #ifdef ENABLE_SCRIPT_PROFILING
  1290. HRESULT RegisterProfileProbe(IActiveScriptProfilerCallback *pProfileCallback, DWORD dwEventMask, DWORD dwContext, RegisterExternalLibraryType RegisterExternalLibrary, JavascriptMethod dispatchInvoke);
  1291. #endif
  1292. HRESULT SetProfileEventMask(DWORD dwEventMask);
  1293. HRESULT DeRegisterProfileProbe(HRESULT hrReason, JavascriptMethod dispatchInvoke);
  1294. HRESULT RegisterScript(Js::FunctionProxy *pFunctionBody, BOOL fRegisterScript = TRUE);
  1295. // Register static and dynamic scripts
  1296. HRESULT RegisterAllScripts();
  1297. // Iterate through utf8sourceinfo and clear debug document if they are there.
  1298. void EnsureClearDebugDocument();
  1299. // To be called directly only when the thread context is shutting down
  1300. void ShutdownClearSourceLists();
  1301. HRESULT RegisterLibraryFunction(const char16 *pwszObjectName, const char16 *pwszFunctionName, Js::PropertyId functionPropertyId, JavascriptMethod entryPoint);
  1302. HRESULT RegisterBuiltinFunctions(RegisterExternalLibraryType RegisterExternalLibrary);
  1303. void RegisterDebugThunk(bool calledDuringAttach = true);
  1304. void UnRegisterDebugThunk();
  1305. void UpdateRecyclerFunctionEntryPointsForDebugger();
  1306. void SetFunctionInRecyclerToProfileMode(bool enumerateNonUserFunctionsOnly = false);
  1307. #ifdef ENABLE_SCRIPT_PROFILING
  1308. static void SetEntryPointToProfileThunk(JavascriptFunction* function);
  1309. static void RestoreEntryPointFromProfileThunk(JavascriptFunction* function);
  1310. #endif
  1311. static void RecyclerEnumClassEnumeratorCallback(void *address, size_t size);
  1312. static void RecyclerFunctionCallbackForDebugger(void *address, size_t size);
  1313. static ushort ProcessNameAndGetLength(Js::StringBuilder<ArenaAllocator>* nameBuffer, const WCHAR* name);
  1314. #ifdef ASMJS_PLAT
  1315. void TransitionEnvironmentForDebugger(ScriptFunction * scriptFunction);
  1316. #endif
  1317. #if ENABLE_NATIVE_CODEGEN
  1318. HRESULT RecreateNativeCodeGenerator();
  1319. #endif
  1320. HRESULT OnDebuggerAttached();
  1321. HRESULT OnDebuggerDetached();
  1322. HRESULT OnDebuggerAttachedDetached(bool attach);
  1323. void InitializeDebugging();
  1324. bool IsForceNoNative();
  1325. bool IsEnumeratingRecyclerObjects() const { return isEnumeratingRecyclerObjects; }
  1326. private:
  1327. class AutoEnumeratingRecyclerObjects
  1328. {
  1329. public:
  1330. AutoEnumeratingRecyclerObjects(ScriptContext* scriptContext):
  1331. m_scriptContext(scriptContext)
  1332. {
  1333. Assert(!m_scriptContext->IsEnumeratingRecyclerObjects());
  1334. m_scriptContext->isEnumeratingRecyclerObjects = true;
  1335. }
  1336. ~AutoEnumeratingRecyclerObjects()
  1337. {
  1338. Assert(m_scriptContext->IsEnumeratingRecyclerObjects());
  1339. m_scriptContext->isEnumeratingRecyclerObjects = false;
  1340. }
  1341. private:
  1342. ScriptContext* m_scriptContext;
  1343. };
  1344. #ifdef EDIT_AND_CONTINUE
  1345. private:
  1346. ScriptEditQuery* activeScriptEditQuery;
  1347. void BeginScriptEditEnumFunctions(ScriptEditQuery* scriptEditQuery) { Assert(!activeScriptEditQuery); activeScriptEditQuery = scriptEditQuery; }
  1348. void EndScriptEditEnumFunctions() { Assert(activeScriptEditQuery); activeScriptEditQuery = nullptr; }
  1349. public:
  1350. ScriptEditQuery* GetActiveScriptEditQuery() const { return activeScriptEditQuery; }
  1351. class AutoScriptEditEnumFunctions
  1352. {
  1353. public:
  1354. AutoScriptEditEnumFunctions(ScriptContext* scriptContext, ScriptEditQuery* scriptEditQuery) : m_scriptContext(scriptContext)
  1355. {
  1356. scriptContext->BeginScriptEditEnumFunctions(scriptEditQuery);
  1357. }
  1358. ~AutoScriptEditEnumFunctions() { m_scriptContext->EndScriptEditEnumFunctions(); }
  1359. private:
  1360. ScriptContext* m_scriptContext;
  1361. };
  1362. #endif
  1363. private:
  1364. typedef JsUtil::BaseDictionary<JavascriptMethod, Js::PropertyId, ArenaAllocator, PrimeSizePolicy> BuiltinFunctionIdDictionary;
  1365. BuiltinFunctionIdDictionary *m_pBuiltinFunctionIdMap;
  1366. Js::PropertyId GetFunctionNumber(JavascriptMethod entryPoint);
  1367. static const char16* CopyString(const char16* str, size_t charCount, ArenaAllocator* alloc);
  1368. static charcount_t AppendWithEscapeCharacters(Js::StringBuilder<ArenaAllocator>* stringBuilder, const WCHAR* sourceString, charcount_t sourceStringLen, WCHAR escapeChar, WCHAR charToEscape);
  1369. public:
  1370. #if DYNAMIC_INTERPRETER_THUNK
  1371. JavascriptMethod GetNextDynamicAsmJsInterpreterThunk(PVOID* ppDynamicInterpreterThunk);
  1372. JavascriptMethod GetNextDynamicInterpreterThunk(PVOID* ppDynamicInterpreterThunk);
  1373. #if DBG
  1374. BOOL IsDynamicInterpreterThunk(JavascriptMethod address);
  1375. #endif
  1376. void ReleaseDynamicInterpreterThunk(BYTE* address, bool addtoFreeList);
  1377. void ReleaseDynamicAsmJsInterpreterThunk(BYTE* address, bool addtoFreeList);
  1378. #endif
  1379. static Var DebugProfileProbeThunk(RecyclableObject* function, CallInfo callInfo, ...);
  1380. static JavascriptMethod ProfileModeDeferredParse(ScriptFunction **function);
  1381. static Var ProfileModeDeferredParsingThunk(RecyclableObject* function, CallInfo callInfo, ...);
  1382. // Thunks for deferred deserialization of function bodies from the byte code cache
  1383. static JavascriptMethod ProfileModeDeferredDeserialize(ScriptFunction* function);
  1384. static Var ProfileModeDeferredDeserializeThunk(RecyclableObject* function, CallInfo callInfo, ...);
  1385. #ifdef ENABLE_SCRIPT_PROFILING
  1386. void SetProfileMode(BOOL fSet);
  1387. static JavascriptMethod GetProfileModeThunk(JavascriptMethod entryPoint);
  1388. static Var ProfileModeThunk_DebugModeWrapper(JavascriptFunction* function, ScriptContext* scriptContext, JavascriptMethod entryPoint, Arguments& args);
  1389. BOOL GetProfileInfo(
  1390. JavascriptFunction* function,
  1391. PROFILER_TOKEN &scriptId,
  1392. PROFILER_TOKEN &functionId);
  1393. HRESULT OnScriptCompiled(PROFILER_TOKEN scriptId, PROFILER_SCRIPT_TYPE type, IUnknown *pIDebugDocumentContext);
  1394. HRESULT OnFunctionCompiled(
  1395. PROFILER_TOKEN functionId,
  1396. PROFILER_TOKEN scriptId,
  1397. const WCHAR *pwszFunctionName,
  1398. const WCHAR *pwszFunctionNameHint,
  1399. IUnknown *pIDebugDocumentContext);
  1400. HRESULT OnFunctionEnter(PROFILER_TOKEN scriptId, PROFILER_TOKEN functionId);
  1401. HRESULT OnFunctionExit(PROFILER_TOKEN scriptId, PROFILER_TOKEN functionId);
  1402. static HRESULT FunctionExitSenderThunk(PROFILER_TOKEN functionId, PROFILER_TOKEN scriptId, ScriptContext *pScriptContext);
  1403. static HRESULT FunctionExitByNameSenderThunk(const char16 *pwszFunctionName, ScriptContext *pScriptContext);
  1404. #endif // ENABLE_SCRIPT_PROFILING
  1405. bool SetDispatchProfile(bool fSet, JavascriptMethod dispatchInvoke);
  1406. HRESULT OnDispatchFunctionEnter(const WCHAR *pwszFunctionName);
  1407. HRESULT OnDispatchFunctionExit(const WCHAR *pwszFunctionName);
  1408. void OnStartupComplete();
  1409. void SaveStartupProfileAndRelease(bool isSaveOnClose = false);
  1410. #if ENABLE_PROFILE_INFO
  1411. void AddDynamicProfileInfo(FunctionBody * functionBody, WriteBarrierPtr<DynamicProfileInfo>* dynamicProfileInfo);
  1412. #endif
  1413. #if DBG || defined(RUNTIME_DATA_COLLECTION)
  1414. uint allocId;
  1415. #endif
  1416. #ifdef PROFILE_EXEC
  1417. void DisableProfiler();
  1418. void SetRecyclerProfiler();
  1419. void SetProfilerFromScriptContext(ScriptContext * scriptContext);
  1420. void ProfileBegin(Js::Phase);
  1421. void ProfileEnd(Js::Phase);
  1422. void ProfileSuspend(Js::Phase, Js::Profiler::SuspendRecord * suspendRecord);
  1423. void ProfileResume(Js::Profiler::SuspendRecord * suspendRecord);
  1424. void ProfilePrint();
  1425. bool IsProfilerCreated() const { return isProfilerCreated; }
  1426. #endif
  1427. #ifdef PROFILE_MEM
  1428. void DisableProfileMemoryDumpOnDelete() { profileMemoryDump = false; }
  1429. #endif
  1430. #ifdef PROFILE_STRINGS
  1431. StringProfiler * GetStringProfiler(); // May be null if string profiling not enabled
  1432. #endif
  1433. public:
  1434. virtual intptr_t GetNullAddr() const override;
  1435. virtual intptr_t GetUndefinedAddr() const override;
  1436. virtual intptr_t GetTrueAddr() const override;
  1437. virtual intptr_t GetFalseAddr() const override;
  1438. virtual intptr_t GetUndeclBlockVarAddr() const override;
  1439. virtual intptr_t GetEmptyStringAddr() const override;
  1440. virtual intptr_t GetNegativeZeroAddr() const override;
  1441. virtual intptr_t GetNumberTypeStaticAddr() const override;
  1442. virtual intptr_t GetStringTypeStaticAddr() const override;
  1443. virtual intptr_t GetObjectTypeAddr() const override;
  1444. virtual intptr_t GetObjectHeaderInlinedTypeAddr() const override;
  1445. virtual intptr_t GetRegexTypeAddr() const override;
  1446. virtual intptr_t GetArrayTypeAddr() const override;
  1447. virtual intptr_t GetNativeIntArrayTypeAddr() const override;
  1448. virtual intptr_t GetNativeFloatArrayTypeAddr() const override;
  1449. virtual intptr_t GetArrayConstructorAddr() const override;
  1450. virtual intptr_t GetCharStringCacheAddr() const override;
  1451. virtual intptr_t GetSideEffectsAddr() const override;
  1452. virtual intptr_t GetArraySetElementFastPathVtableAddr() const override;
  1453. virtual intptr_t GetIntArraySetElementFastPathVtableAddr() const override;
  1454. virtual intptr_t GetFloatArraySetElementFastPathVtableAddr() const override;
  1455. virtual intptr_t GetLibraryAddr() const override;
  1456. virtual intptr_t GetGlobalObjectAddr() const override;
  1457. virtual intptr_t GetGlobalObjectThisAddr() const override;
  1458. virtual intptr_t GetNumberAllocatorAddr() const override;
  1459. virtual intptr_t GetRecyclerAddr() const override;
  1460. virtual bool GetRecyclerAllowNativeCodeBumpAllocation() const override;
  1461. virtual bool IsSIMDEnabled() const override;
  1462. virtual bool IsPRNGSeeded() const override;
  1463. virtual intptr_t GetBuiltinFunctionsBaseAddr() const override;
  1464. #if ENABLE_NATIVE_CODEGEN
  1465. virtual void AddToDOMFastPathHelperMap(intptr_t funcInfoAddr, IR::JnHelperMethod helper) override;
  1466. virtual IR::JnHelperMethod GetDOMFastPathHelper(intptr_t funcInfoAddr) override;
  1467. #endif
  1468. virtual intptr_t GetAddr() const override;
  1469. virtual intptr_t GetVTableAddress(VTableValue vtableType) const override;
  1470. virtual bool IsRecyclerVerifyEnabled() const override;
  1471. virtual uint GetRecyclerVerifyPad() const override;
  1472. virtual Js::Var* GetModuleExportSlotArrayAddress(uint moduleIndex, uint slotIndex) override;
  1473. Js::SourceTextModuleRecord* GetModuleRecord(uint moduleId) const
  1474. {
  1475. return javascriptLibrary->GetModuleRecord(moduleId);
  1476. }
  1477. void SetBuiltInLibraryFunction(JavascriptMethod entryPoint, JavascriptFunction* function);
  1478. JavascriptFunction* GetBuiltInLibraryFunction(JavascriptMethod entryPoint);
  1479. private:
  1480. BuiltInLibraryFunctionMap* builtInLibraryFunctions;
  1481. #if ENABLE_NATIVE_CODEGEN
  1482. JITDOMFastPathHelperMap * m_domFastPathHelperMap;
  1483. #endif
  1484. #ifdef RECYCLER_PERF_COUNTERS
  1485. size_t bindReferenceCount;
  1486. #endif
  1487. ScriptContext * nextPendingClose;
  1488. public:
  1489. void SetNextPendingClose(ScriptContext * nextPendingClose);
  1490. inline ScriptContext * GetNextPendingClose() const { return nextPendingClose; }
  1491. #ifdef ENABLE_MUTATION_BREAKPOINT
  1492. // Keep track of all breakpoints in order to properly clean up on debugger detach
  1493. bool HasMutationBreakpoints();
  1494. void InsertMutationBreakpoint(Js::MutationBreakpoint *mutationBreakpoint);
  1495. #endif
  1496. };
  1497. class AutoDynamicCodeReference
  1498. {
  1499. public:
  1500. AutoDynamicCodeReference(ScriptContext* scriptContext):
  1501. m_scriptContext(scriptContext)
  1502. {
  1503. scriptContext->GetLibrary()->BeginDynamicFunctionReferences();
  1504. }
  1505. ~AutoDynamicCodeReference()
  1506. {
  1507. m_scriptContext->GetLibrary()->EndDynamicFunctionReferences();
  1508. }
  1509. private:
  1510. ScriptContext* m_scriptContext;
  1511. };
  1512. template <typename TCacheType>
  1513. void ScriptContext::CleanDynamicFunctionCache(TCacheType* cacheType)
  1514. {
  1515. // Remove eval map functions that haven't been recently used
  1516. // TODO: Metric based on allocation size too? So don't clean if there hasn't been much allocated?
  1517. cacheType->Clean([this](const typename TCacheType::KeyType& key, typename TCacheType::ValueType value) {
  1518. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  1519. if (CONFIG_FLAG(DumpEvalStringOnRemoval))
  1520. {
  1521. Output::Print(_u("EvalMap: Removing Dynamic Function String from dynamic function cache: %s\n"), key.str.GetBuffer()); Output::Flush();
  1522. }
  1523. #endif
  1524. });
  1525. }
  1526. template <class TDelegate>
  1527. void ScriptContext::MapFunction(TDelegate mapper)
  1528. {
  1529. if (this->sourceList)
  1530. {
  1531. this->sourceList->Map([&mapper](int, RecyclerWeakReference<Js::Utf8SourceInfo>* sourceInfo)
  1532. {
  1533. Utf8SourceInfo* sourceInfoStrongRef = sourceInfo->Get();
  1534. if (sourceInfoStrongRef)
  1535. {
  1536. sourceInfoStrongRef->MapFunction(mapper);
  1537. }
  1538. });
  1539. }
  1540. }
  1541. template <class TDelegate>
  1542. FunctionBody* ScriptContext::FindFunction(TDelegate predicate)
  1543. {
  1544. FunctionBody* functionBody = nullptr;
  1545. this->sourceList->MapUntil([&functionBody, &predicate](int, RecyclerWeakReference<Js::Utf8SourceInfo>* sourceInfo) -> bool
  1546. {
  1547. Utf8SourceInfo* sourceInfoStrongRef = sourceInfo->Get();
  1548. if (sourceInfoStrongRef)
  1549. {
  1550. functionBody = sourceInfoStrongRef->FindFunction(predicate);
  1551. if (functionBody)
  1552. {
  1553. return true;
  1554. }
  1555. }
  1556. return false;
  1557. });
  1558. return functionBody;
  1559. }
  1560. }
  1561. #define BEGIN_TEMP_ALLOCATOR(allocator, scriptContext, name) \
  1562. Js::TempArenaAllocatorObject *temp##allocator = scriptContext->GetTemporaryAllocator(name); \
  1563. ArenaAllocator * allocator = temp##allocator->GetAllocator();
  1564. #define END_TEMP_ALLOCATOR(allocator, scriptContext) \
  1565. scriptContext->ReleaseTemporaryAllocator(temp##allocator);
  1566. #define DECLARE_TEMP_ALLOCATOR(allocator) \
  1567. Js::TempArenaAllocatorObject *temp##allocator = nullptr; \
  1568. ArenaAllocator * allocator = nullptr;
  1569. #define ACQUIRE_TEMP_ALLOCATOR(allocator, scriptContext, name) \
  1570. temp##allocator = scriptContext->GetTemporaryAllocator(name); \
  1571. allocator = temp##allocator->GetAllocator();
  1572. #define RELEASE_TEMP_ALLOCATOR(allocator, scriptContext) \
  1573. if (temp##allocator) \
  1574. scriptContext->ReleaseTemporaryAllocator(temp##allocator);
  1575. #define DECLARE_TEMP_GUEST_ALLOCATOR(allocator) \
  1576. Js::TempGuestArenaAllocatorObject *tempGuest##allocator = nullptr; \
  1577. ArenaAllocator * allocator = nullptr;
  1578. #define ACQUIRE_TEMP_GUEST_ALLOCATOR(allocator, scriptContext, name) \
  1579. tempGuest##allocator = scriptContext->GetTemporaryGuestAllocator(name); \
  1580. allocator = tempGuest##allocator->GetAllocator();
  1581. #define RELEASE_TEMP_GUEST_ALLOCATOR(allocator, scriptContext) \
  1582. if (tempGuest##allocator) \
  1583. scriptContext->ReleaseTemporaryGuestAllocator(tempGuest##allocator);