ScriptContext.h 81 KB

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