ScriptContext.h 79 KB

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