InterpreterStackFrame.h 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation and contributors. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. #ifdef _MSC_VER
  7. extern "C" PVOID _ReturnAddress(VOID);
  8. #pragma intrinsic(_ReturnAddress)
  9. #else
  10. #define _ReturnAddress() __builtin_return_address(0)
  11. #endif
  12. class BailOutRecord;
  13. extern "C" void __cdecl _alloca_probe_16();
  14. namespace Js
  15. {
  16. class EHBailoutData;
  17. enum InterpreterStackFrameFlags : UINT16
  18. {
  19. InterpreterStackFrameFlags_None = 0,
  20. InterpreterStackFrameFlags_WithinTryBlock = 1,
  21. InterpreterStackFrameFlags_WithinCatchBlock = 2,
  22. InterpreterStackFrameFlags_WithinFinallyBlock = 4,
  23. InterpreterStackFrameFlags_FromBailOut = 8,
  24. InterpreterStackFrameFlags_ProcessingBailOutOnArrayAccessHelperCall = 0x10,
  25. InterpreterStackFrameFlags_ProcessingBailOutFromEHCode = 0x20,
  26. InterpreterStackFrameFlags_FromBailOutInInlinee = 0x40,
  27. InterpreterStackFrameFlags_ProcessingBailOutOnArraySpecialization = 0x80,
  28. InterpreterStackFrameFlags_WithinTryFinallyBlock = 0x100,
  29. InterpreterStackFrameFlags_All = 0xFFFF,
  30. };
  31. // TODO: (leish)(swb) this is not always stack allocated now
  32. // with ES6 Generator, this can be allocated with recycler
  33. // need to find a good way to set write barrier, or big refactor.
  34. struct InterpreterStackFrame /* Stack allocated, no virtuals */
  35. {
  36. PREVENT_COPY(InterpreterStackFrame)
  37. friend class ::BailOutRecord;
  38. friend class JavascriptGeneratorFunction;
  39. friend class JavascriptGenerator;
  40. class Setup
  41. {
  42. public:
  43. Setup(ScriptFunction * function, Arguments& args, bool bailout = false, bool inlinee = false);
  44. Setup(ScriptFunction * function, Var * inParams, int inSlotsCount);
  45. size_t GetAllocationVarCount() const { return varAllocCount; }
  46. InterpreterStackFrame * AllocateAndInitialize(bool doProfile, bool * releaseAlloc);
  47. #if DBG
  48. InterpreterStackFrame * InitializeAllocation(__in_ecount(varAllocCount) Var * allocation, bool initParams, bool profileParams, LoopHeader* loopHeaderArray, DWORD_PTR stackAddr, Var invalidStackVar);
  49. #else
  50. InterpreterStackFrame * InitializeAllocation(__in_ecount(varAllocCount) Var * allocation, bool initParams, bool profileParams, LoopHeader* loopHeaderArray, DWORD_PTR stackAddr);
  51. #endif
  52. uint GetLocalCount() const { return localCount; }
  53. private:
  54. template <class Fn>
  55. void InitializeParams(InterpreterStackFrame * newInstance, Fn callback, Var **pprestDest);
  56. template <class Fn>
  57. void InitializeParamsAndUndef(InterpreterStackFrame * newInstance, Fn callback, Var **pprestDest);
  58. void InitializeRestParam(InterpreterStackFrame * newInstance, Var *dest);
  59. void SetupInternal();
  60. Var * inParams;
  61. ScriptFunction * const function;
  62. FunctionBody * const executeFunction;
  63. void** inlineCaches;
  64. int inSlotsCount;
  65. uint localCount;
  66. uint varAllocCount;
  67. uint inlineCacheCount;
  68. Js::CallFlags callFlags;
  69. bool bailedOut;
  70. bool bailedOutOfInlinee;
  71. };
  72. struct AsmJsReturnStruct
  73. {
  74. #ifdef ASMJS_PLAT
  75. int32 i;
  76. int64 l;
  77. float f;
  78. double d;
  79. AsmJsSIMDValue simd;
  80. template<typename T> T GetRetVal();
  81. template<> int32 GetRetVal<int32>() { return i; }
  82. template<> int64 GetRetVal<int64>() { return l; }
  83. template<> float GetRetVal<float>() { return f; }
  84. template<> double GetRetVal<double>() { return d; }
  85. template<> X86SIMDValue GetRetVal<X86SIMDValue>() { return X86SIMDValue::ToX86SIMDValue(simd); }
  86. #endif
  87. };
  88. private:
  89. ByteCodeReader m_reader; // Reader for current function
  90. int m_inSlotsCount; // Count of actual incoming parameters to this function
  91. Js::CallFlags m_callFlags; // CallFlags passed to the current function
  92. Var* m_inParams; // Range of 'in' parameters
  93. Var* m_outParams; // Range of 'out' parameters (offset in m_localSlots)
  94. Var* m_outSp; // Stack pointer for next outparam
  95. Var* m_outSpCached; // Stack pointer for caching previos SP (in order to assist in try..finally)
  96. Var m_arguments; // Dedicated location for this frame's arguments object
  97. StackScriptFunction * stackNestedFunctions;
  98. FrameDisplay * localFrameDisplay;
  99. Var localClosure;
  100. Var paramClosure;
  101. Var *innerScopeArray;
  102. ForInObjectEnumerator * forInObjectEnumerators;
  103. ScriptContext* scriptContext;
  104. ScriptFunction * function;
  105. FunctionBody * m_functionBody;
  106. void** inlineCaches;
  107. void * returnAddress;
  108. void * addressOfReturnAddress; // Tag this frame with stack position, used by (remote) stack walker to test partially initialized interpreter stack frame.
  109. InterpreterStackFrame *previousInterpreterFrame;
  110. LoopHeader* loopHeaderArray; // Keeps alive any JITted loop bodies while the function is being interpreted
  111. // 'stack address' of the frame, used for recursion detection during stepping.
  112. // For frames created via interpreter path, we use 'this', for frames created by bailout we use stack addr of actual jitted frame
  113. // the interpreter frame is created for.
  114. DWORD_PTR m_stackAddress;
  115. #if ENABLE_PROFILE_INFO
  116. ImplicitCallFlags * savedLoopImplicitCallFlags;
  117. #endif
  118. uint inlineCacheCount;
  119. uint currentLoopNum;
  120. uint currentLoopCounter; // This keeps tracks of how many times the current loop is executed. It's hit only in cases where jitloopbodies are not hit
  121. // such as loops inside try\catch.
  122. UINT16 m_flags; // based on InterpreterStackFrameFlags
  123. bool closureInitDone : 1;
  124. bool isParamScopeDone : 1;
  125. bool shouldCacheSP : 1; // Helps in determining if we need to cache the sp in ProcessTryFinally
  126. #if ENABLE_PROFILE_INFO
  127. bool switchProfileMode : 1;
  128. bool isAutoProfiling : 1;
  129. uint32 switchProfileModeOnLoopEndNumber;
  130. #endif
  131. int16 nestedTryDepth;
  132. int16 nestedCatchDepth;
  133. uint retOffset;
  134. int16 nestedFinallyDepth;
  135. void (InterpreterStackFrame::*opLoopBodyStart)(uint32 loopNumber, LayoutSize layoutSize, bool isFirstIteration);
  136. #if ENABLE_PROFILE_INFO
  137. void (InterpreterStackFrame::*opProfiledLoopBodyStart)(uint32 loopNumber, LayoutSize layoutSize, bool isFirstIteration);
  138. #endif
  139. #if DBG || DBG_DUMP
  140. void * DEBUG_currentByteOffset;
  141. #endif
  142. #if DBG
  143. Var* m_outParamsEnd;
  144. #endif
  145. // Asm.js stack pointer
  146. int* m_localIntSlots;
  147. int64* m_localInt64Slots;
  148. double* m_localDoubleSlots;
  149. float* m_localFloatSlots;
  150. union
  151. {
  152. JavascriptArrayBuffer* m_asmJsBuffer;
  153. #ifdef ENABLE_WASM
  154. WebAssemblyMemory * m_wasmMemory;
  155. #endif
  156. };
  157. #ifdef ENABLE_WASM
  158. Wasm::WasmSignature* m_signatures;
  159. #endif
  160. _SIMDValue* m_localSimdSlots;
  161. EHBailoutData * ehBailoutData;
  162. // 16-byte aligned
  163. __declspec(align(16)) Var m_localSlots[0]; // Range of locals and temporaries
  164. static const int LocalsThreshold = 32 * 1024; // Number of locals vars we'll allocate on the frame.
  165. // If there are more, we'll use an arena.
  166. //This class must have an empty ctor (otherwise it will break the code in InterpreterStackFrame::InterpreterThunk
  167. inline InterpreterStackFrame() { }
  168. JavascriptArrayBuffer* GetAsmJsBuffer() const;
  169. #ifdef ENABLE_WASM
  170. WebAssemblyMemory* GetWebAssemblyMemory() const;
  171. #endif
  172. void ProcessTryFinally(const byte* ip, Js::JumpOffset jumpOffset, Js::RegSlot regException = Js::Constants::NoRegister, Js::RegSlot regOffset = Js::Constants::NoRegister, bool hasYield = false);
  173. public:
  174. void OP_SetOutAsmInt(RegSlot outRegisterID, int val);
  175. void OP_SetOutAsmFlt(RegSlot outRegisterID, float val);
  176. void OP_SetOutAsmDb(RegSlot outRegisterID, double val);
  177. void OP_I_SetOutAsmInt(RegSlot outRegisterID, int val);
  178. void OP_I_SetOutAsmDb(RegSlot outRegisterID, double val);
  179. void OP_I_SetOutAsmFlt(RegSlot outRegisterID, float val);
  180. void OP_I_SetOutAsmLong(RegSlot outRegisterID, int64 val);
  181. void OP_I_SetOutAsmSimd(RegSlot outRegisterID, AsmJsSIMDValue val);
  182. template<int type, bool toJs> //type is int to avoid including Wasm headers
  183. void OP_InvalidWasmTypeConversion(...);
  184. void OP_WasmPrintFunc(int index);
  185. template <class T> void OP_WasmPrintFunc(const unaligned T* playout) { OP_WasmPrintFunc((int)playout->I1); }
  186. void SetOut(ArgSlot outRegisterID, Var bValue);
  187. void SetOut(ArgSlot_OneByte outRegisterID, Var bValue);
  188. void PushOut(Var aValue);
  189. void PopOut(ArgSlot argCount);
  190. void CacheSp();
  191. void RestoreSp();
  192. FrameDisplay * GetLocalFrameDisplay() const;
  193. FrameDisplay * GetFrameDisplayForNestedFunc() const;
  194. Var InnerScopeFromRegSlot(RegSlot reg) const;
  195. void SetClosureInitDone(bool done) { closureInitDone = done; }
  196. bool IsClosureInitDone() const { return closureInitDone; }
  197. void ValidateRegValue(Var value, bool allowStackVar = false, bool allowStackVarOnDisabledStackNestedFunc = true) const;
  198. int OP_GetMemorySize();
  199. int32 OP_GrowMemory(int32 delta);
  200. void OP_Unreachable();
  201. template <typename T> using AsmJsMathPtr = T(*)(T a, T b);
  202. template <typename T, AsmJsMathPtr<T> func> static T OP_DivOverflow(T a, T b, ScriptContext* scriptContext);
  203. template <typename T, AsmJsMathPtr<T> func> static T OP_RemOverflow(T a, T b, ScriptContext* scriptContext);
  204. template <typename T, AsmJsMathPtr<T> func> static T OP_UnsignedDivRemCheck(T a, T b, ScriptContext* scriptContext);
  205. void ValidateSetRegValue(Var value, bool allowStackVar = false, bool allowStackVarOnDisabledStackNestedFunc = true) const;
  206. template <typename RegSlotType> Var GetReg(RegSlotType localRegisterID) const;
  207. template <typename RegSlotType> void SetReg(RegSlotType localRegisterID, Var bValue);
  208. template <typename RegSlotType> Var GetRegAllowStackVar(RegSlotType localRegisterID) const;
  209. template <typename RegSlotType> void SetRegAllowStackVar(RegSlotType localRegisterID, Var bValue);
  210. template <typename RegSlotType> int GetRegRawInt( RegSlotType localRegisterID ) const;
  211. template <typename RegSlotType> void SetRegRawInt( RegSlotType localRegisterID, int bValue );
  212. template <typename RegSlotType> int64 GetRegRawInt64( RegSlotType localRegisterID ) const;
  213. template <typename RegSlotType> void SetRegRawInt64( RegSlotType localRegisterID, int64 bValue );
  214. template <typename RegSlotType> void* GetRegRawPtr(RegSlotType localRegisterID) const;
  215. template <typename RegSlotType> void SetRegRawPtr(RegSlotType localRegisterID, void* val);
  216. template <typename RegSlotType> double VECTORCALL GetRegRawDouble(RegSlotType localRegisterID) const;
  217. template <typename RegSlotType> float VECTORCALL GetRegRawFloat(RegSlotType localRegisterID) const;
  218. template <typename RegSlotType> void SetRegRawDouble(RegSlotType localRegisterID, double bValue);
  219. template <typename RegSlotType> void SetRegRawFloat(RegSlotType localRegisterID, float bValue);
  220. template <typename T> T VECTORCALL GetRegRaw( RegSlot localRegisterID ) const;
  221. template <typename T> void SetRegRaw( RegSlot localRegisterID, T bValue );
  222. template <typename RegSlotType> AsmJsSIMDValue GetRegRawSimd(RegSlotType localRegisterID) const;
  223. template <typename RegSlotType> void SetRegRawSimd(RegSlotType localRegisterID, AsmJsSIMDValue bValue);
  224. template <class T> void OP_SimdLdArrGeneric(const unaligned T* playout);
  225. template <class T> void OP_SimdLdArrConstIndex(const unaligned T* playout);
  226. template <class T> void OP_SimdStArrGeneric(const unaligned T* playout);
  227. template <class T> void OP_SimdStArrConstIndex(const unaligned T* playout);
  228. bool SIMDAnyNaN(AsmJsSIMDValue& input);
  229. template <class T> void OP_SimdInt32x4FromFloat32x4(const unaligned T* playout);
  230. template <class T> void OP_SimdUint32x4FromFloat32x4(const unaligned T* playout);
  231. template <class T> void OP_WasmSimdConst(const unaligned T* playout);
  232. template <class T> void OP_SimdShuffleV8X16(const unaligned T* playout);
  233. template <class T> void OP_SimdInt16x8(const unaligned T* playout);
  234. template <class T> void OP_SimdInt8x16(const unaligned T* playout);
  235. template <class T> void OP_SimdUint32x4(const unaligned T* playout);
  236. template <class T> void OP_SimdUint16x8(const unaligned T* playout);
  237. template <class T> void OP_SimdUint8x16(const unaligned T* playout);
  238. template <class T> void OP_SimdBool32x4(const unaligned T* playout);
  239. template <class T> void OP_SimdBool16x8(const unaligned T* playout);
  240. template <class T> void OP_SimdBool8x16(const unaligned T* playout);
  241. template <typename RegSlotType>
  242. Var GetRegAllowStackVarEnableOnly(RegSlotType localRegisterID) const;
  243. template <typename RegSlotType>
  244. void SetRegAllowStackVarEnableOnly(RegSlotType localRegisterID, Var bValue);
  245. Var GetNonVarReg(RegSlot localRegisterID) const;
  246. void SetNonVarReg(RegSlot localRegisterID, void * bValue);
  247. ScriptContext* GetScriptContext() const { return scriptContext; }
  248. Var GetRootObject() const;
  249. ScriptFunction* GetJavascriptFunction() const { return function; }
  250. FunctionBody * GetFunctionBody() const { return m_functionBody; }
  251. ByteCodeReader* GetReader() { return &m_reader;}
  252. uint GetCurrentLoopNum() const { return currentLoopNum; }
  253. InterpreterStackFrame* GetPreviousFrame() const {return previousInterpreterFrame;}
  254. void SetPreviousFrame(InterpreterStackFrame *interpreterFrame) {previousInterpreterFrame = interpreterFrame;}
  255. Var GetArgumentsObject() const { return m_arguments; }
  256. void SetArgumentsObject(Var args) { m_arguments = args; }
  257. UINT16 GetFlags() const { return m_flags; }
  258. void OrFlags(UINT16 addTo) { m_flags |= addTo; }
  259. void ClearFlags(UINT16 flags) { m_flags &= ~flags; }
  260. bool TestFlags(UINT16 flags) { return (m_flags & flags) != 0; }
  261. bool IsInCatchOrFinallyBlock();
  262. static bool IsDelayDynamicInterpreterThunk(JavascriptMethod entryPoint);
  263. Var LdEnv() const;
  264. void SetEnv(FrameDisplay *frameDisplay);
  265. Field(Var)* NewScopeSlots(unsigned int size, ScriptContext *scriptContext, Var scope);
  266. Field(Var)* NewScopeSlots();
  267. Var NewScopeObject();
  268. FrameDisplay * NewFrameDisplay(void *argHead, void *argEnv);
  269. Var CreateHeapArguments(ScriptContext* scriptContext);
  270. bool IsCurrentLoopNativeAddr(void * codeAddr) const;
  271. void * GetReturnAddress() { return returnAddress; }
  272. static uint32 GetOffsetOfLocals() { return offsetof(InterpreterStackFrame, m_localSlots); }
  273. static uint32 GetOffsetOfArguments() { return offsetof(InterpreterStackFrame, m_arguments); }
  274. static uint32 GetOffsetOfInParams() { return offsetof(InterpreterStackFrame, m_inParams); }
  275. static uint32 GetOffsetOfInSlotsCount() { return offsetof(InterpreterStackFrame, m_inSlotsCount); }
  276. static uint32 GetOffsetOfStackNestedFunctions() { return offsetof(InterpreterStackFrame, stackNestedFunctions); }
  277. static uint32 GetOffsetOfForInEnumerators() { return offsetof(InterpreterStackFrame, forInObjectEnumerators); }
  278. static uint32 GetStartLocationOffset() { return offsetof(InterpreterStackFrame, m_reader) + ByteCodeReader::GetStartLocationOffset(); }
  279. static uint32 GetCurrentLocationOffset() { return offsetof(InterpreterStackFrame, m_reader) + ByteCodeReader::GetCurrentLocationOffset(); }
  280. bool IsParamScopeDone() const { return isParamScopeDone; }
  281. void SetIsParamScopeDone(bool value) { isParamScopeDone = value; }
  282. static bool IsBrLong(OpCode op, const byte * ip)
  283. {
  284. #ifdef BYTECODE_BRANCH_ISLAND
  285. CompileAssert(Js::OpCodeInfo<Js::OpCode::BrLong>::IsExtendedOpcode);
  286. return (op == OpCode::ExtendedOpcodePrefix) && ((OpCode)(ByteCodeReader::PeekExtOp(ip)) == OpCode::BrLong);
  287. #else
  288. return false;
  289. #endif
  290. }
  291. DWORD_PTR GetStackAddress() const;
  292. void* GetAddressOfReturnAddress() const;
  293. #if _M_IX86
  294. static int GetRetType(JavascriptFunction* func);
  295. static int GetAsmJsArgSize(AsmJsCallStackLayout * stack);
  296. static int GetDynamicRetType(AsmJsCallStackLayout * stack);
  297. _NOINLINE static void AsmJsInterpreter(AsmJsCallStackLayout * stack, byte* retDst);
  298. #elif _M_X64
  299. template <typename T>
  300. static T AsmJsInterpreter(AsmJsCallStackLayout* layout);
  301. static void * GetAsmJsInterpreterEntryPoint(AsmJsCallStackLayout* stack);
  302. static __m128 AsmJsInterpreterSimdJs(AsmJsCallStackLayout* func);
  303. #endif
  304. #ifdef ASMJS_PLAT
  305. static void StaticInterpreterAsmThunk(RecyclableObject* function, ...);
  306. static void InterpreterAsmThunk(AsmJsCallStackLayout* layout);
  307. #endif
  308. #if DYNAMIC_INTERPRETER_THUNK
  309. static Var AsmJsDelayDynamicInterpreterThunk(RecyclableObject* function, CallInfo callInfo, ...);
  310. static Var DelayDynamicInterpreterThunk(RecyclableObject* function, CallInfo callInfo, ...);
  311. _NOINLINE static Var InterpreterThunk(JavascriptCallStackLayout* layout);
  312. _NOINLINE static Var StaticInterpreterThunk(RecyclableObject* function, CallInfo callInfo, ...);
  313. #else
  314. _NOINLINE static Var InterpreterThunk(RecyclableObject* function, CallInfo callInfo, ...);
  315. #endif
  316. static Var InterpreterHelper(ScriptFunction* function, ArgumentReader args, void* returnAddress, void* addressOfReturnAddress, AsmJsReturnStruct* asmReturn = nullptr);
  317. static const bool ShouldDoProfile(FunctionBody* executeFunction);
  318. static InterpreterStackFrame* CreateInterpreterStackFrameForGenerator(ScriptFunction* function, FunctionBody* executeFunction, JavascriptGenerator* generator, bool doProfile);
  319. void InitializeClosures();
  320. private:
  321. #if DYNAMIC_INTERPRETER_THUNK
  322. static JavascriptMethod EnsureDynamicInterpreterThunk(Js::ScriptFunction * function);
  323. #endif
  324. template<typename OpCodeType, Js::OpCode (ReadOpFunc)(const byte*&), void (TracingFunc)(InterpreterStackFrame*, OpCodeType)>
  325. OpCodeType ReadOp(const byte *& ip);
  326. static void TraceOpCode(InterpreterStackFrame* that, Js::OpCode op);
  327. static void TraceAsmJsOpCode(InterpreterStackFrame* that, Js::OpCodeAsmJs op);
  328. #if ENABLE_TTD
  329. template<typename OpCodeType, Js::OpCode(ReadOpFunc)(const byte*&), void (TracingFunc)(InterpreterStackFrame*, OpCodeType)>
  330. OpCodeType ReadOp_WPreviousStmtTracking(const byte *& ip);
  331. #endif
  332. void* __cdecl operator new(size_t byteSize, void* previousAllocation) throw();
  333. void __cdecl operator delete(void* allocationToFree, void* previousAllocation) throw();
  334. _NOINLINE Var ProcessThunk(void* returnAddress, void* addressOfReturnAddress);
  335. _NOINLINE Var DebugProcessThunk(void* returnAddress, void* addressOfReturnAddress);
  336. void AlignMemoryForAsmJs();
  337. Var Process();
  338. Var ProcessAsmJsModule();
  339. Var ProcessLinkFailedAsmJsModule();
  340. Var ProcessAsmJs();
  341. Var ProcessProfiled();
  342. Var ProcessUnprofiled();
  343. const byte* ProcessProfiledExtendedOpcodePrefix(const byte* ip);
  344. const byte* ProcessUnprofiledExtendedOpcodePrefix(const byte* ip);
  345. const byte* ProcessWithDebuggingExtendedOpcodePrefix(const byte* ip);
  346. const byte* ProcessAsmJsExtendedOpcodePrefix(const byte* ip);
  347. const byte* ProcessProfiledMediumLayoutPrefix(const byte* ip, Var&);
  348. const byte* ProcessUnprofiledMediumLayoutPrefix(const byte* ip, Var&);
  349. const byte* ProcessWithDebuggingMediumLayoutPrefix(const byte* ip, Var&);
  350. const byte* ProcessAsmJsMediumLayoutPrefix(const byte* ip, Var&);
  351. const byte* ProcessProfiledExtendedMediumLayoutPrefix(const byte* ip);
  352. const byte* ProcessUnprofiledExtendedMediumLayoutPrefix(const byte* ip);
  353. const byte* ProcessWithDebuggingExtendedMediumLayoutPrefix(const byte* ip);
  354. const byte* ProcessAsmJsExtendedMediumLayoutPrefix(const byte* ip);
  355. const byte* ProcessProfiledLargeLayoutPrefix(const byte* ip, Var&);
  356. const byte* ProcessUnprofiledLargeLayoutPrefix(const byte* ip, Var&);
  357. const byte* ProcessWithDebuggingLargeLayoutPrefix(const byte* ip, Var&);
  358. const byte* ProcessAsmJsLargeLayoutPrefix(const byte* ip, Var&);
  359. const byte* ProcessProfiledExtendedLargeLayoutPrefix(const byte* ip);
  360. const byte* ProcessUnprofiledExtendedLargeLayoutPrefix(const byte* ip);
  361. const byte* ProcessWithDebuggingExtendedLargeLayoutPrefix(const byte* ip);
  362. const byte* ProcessAsmJsExtendedLargeLayoutPrefix(const byte* ip);
  363. #ifdef ENABLE_SCRIPT_DEBUGGING
  364. Var ProcessWithDebugging();
  365. Var DebugProcess();
  366. bool IsInDebugMode() const { return this->GetFunctionBody()->IsInDebugMode(); }
  367. #endif
  368. #if ENABLE_TTD
  369. Var ProcessWithDebugging_PreviousStmtTracking();
  370. const byte* ProcessWithDebugging_PreviousStmtTrackingExtendedOpcodePrefix(const byte* ip);
  371. const byte* ProcessWithDebugging_PreviousStmtTrackingMediumLayoutPrefix(const byte* ip, Var&);
  372. const byte* ProcessWithDebugging_PreviousStmtTrackingExtendedMediumLayoutPrefix(const byte* ip);
  373. const byte* ProcessWithDebugging_PreviousStmtTrackingLargeLayoutPrefix(const byte* ip, Var&);
  374. const byte* ProcessWithDebugging_PreviousStmtTrackingExtendedLargeLayoutPrefix(const byte* ip);
  375. #if ENABLE_TTD_DIAGNOSTICS_TRACING
  376. Var ProcessUnprofiled_PreviousStmtTracking();
  377. const byte* ProcessUnprofiled_PreviousStmtTrackingExtendedOpcodePrefix(const byte* ip);
  378. const byte* ProcessUnprofiled_PreviousStmtTrackingMediumLayoutPrefix(const byte* ip, Var&);
  379. const byte* ProcessUnprofiled_PreviousStmtTrackingExtendedMediumLayoutPrefix(const byte* ip);
  380. const byte* ProcessUnprofiled_PreviousStmtTrackingLargeLayoutPrefix(const byte* ip, Var&);
  381. const byte* ProcessUnprofiled_PreviousStmtTrackingExtendedLargeLayoutPrefix(const byte* ip);
  382. #endif
  383. #endif
  384. // This will be called for reseting outs when resume from break on error happened
  385. void ResetOut();
  386. Var OP_ArgIn0();
  387. template <class T> void OP_ArgOut_Env(const unaligned T* playout);
  388. template <class T> void OP_ArgOut_A(const unaligned T* playout);
  389. template <class T> void OP_ProfiledArgOut_A(const unaligned T * playout);
  390. #if DBG
  391. template <class T> void OP_ArgOut_ANonVar(const unaligned T* playout);
  392. #endif
  393. FrameDisplay * GetEnvForEvalCode();
  394. BOOL OP_BrFalse_A(Var aValue, ScriptContext* scriptContext);
  395. BOOL OP_BrTrue_A(Var aValue, ScriptContext* scriptContext);
  396. BOOL OP_BrNotNull_A(Var aValue);
  397. BOOL OP_BrUndecl_A(Var aValue);
  398. BOOL OP_BrNotUndecl_A(Var aValue);
  399. BOOL OP_BrOnHasProperty(Var argInstance, uint propertyIdIndex, ScriptContext* scriptContext);
  400. BOOL OP_BrOnNoProperty(Var argInstance, uint propertyIdIndex, ScriptContext* scriptContext);
  401. BOOL OP_BrOnNoEnvProperty(Var envInstance, int32 slotIndex, uint propertyIdIndex, ScriptContext* scriptContext);
  402. BOOL OP_BrOnClassConstructor(Var aValue);
  403. BOOL OP_BrOnBaseConstructorKind(Var aValue);
  404. RecyclableObject * OP_CallGetFunc(Var target);
  405. template <class T> const byte * OP_Br(const unaligned T * playout);
  406. void OP_AsmStartCall(const unaligned OpLayoutStartCall * playout);
  407. void OP_StartCall( const unaligned OpLayoutStartCall * playout );
  408. void OP_StartCall(uint outParamCount);
  409. template <class T> void OP_CallCommon(const unaligned T *playout, RecyclableObject * aFunc, unsigned flags, const Js::AuxArray<uint32> *spreadIndices = nullptr);
  410. void OP_CallAsmInternalCommon(ScriptFunction* function, RegSlot returnReg);
  411. void OP_CallAsmInternal(RegSlot funcReg, RegSlot returnReg);
  412. template <class T> void OP_I_AsmCall(const unaligned T* playout) { OP_CallAsmInternal(playout->Function, playout->Return); }
  413. void OP_ProfiledCallAsmInternal(RegSlot funcReg, RegSlot returnReg, ProfileId profileId);
  414. template <class T> void OP_ProfiledI_AsmCall(const unaligned T* playout) { OP_ProfiledCallAsmInternal(playout->Function, playout->Return, playout->profileId); }
  415. template <class T> void OP_CallCommonI(const unaligned T *playout, RecyclableObject * aFunc, unsigned flags);
  416. template <class T> void OP_ProfileCallCommon(const unaligned T *playout, RecyclableObject * aFunc, unsigned flags, ProfileId profileId, InlineCacheIndex inlineCacheIndex = Js::Constants::NoInlineCacheIndex, const Js::AuxArray<uint32> *spreadIndices = nullptr);
  417. template <class T> void OP_ProfileReturnTypeCallCommon(const unaligned T *playout, RecyclableObject * aFunc, unsigned flags, ProfileId profileId, const Js::AuxArray<uint32> *spreadIndices = nullptr);
  418. template <class T> void OP_AsmCall(const unaligned T* playout);
  419. template <class T> void OP_EnsureHeapAttached(const unaligned T* playout);
  420. template <class T> void OP_CallI(const unaligned T* playout) { OP_CallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), Js::CallFlags_None); }
  421. template <class T> void OP_CallIFlags(const unaligned T* playout) { OP_CallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), playout->callFlags); }
  422. template <class T> void OP_CallIExtended(const unaligned T* playout) { OP_CallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), Js::CallFlags_None, (playout->Options & CallIExtended_SpreadArgs) ? m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody()) : nullptr); }
  423. template <class T> void OP_CallIExtendedFlags(const unaligned T* playout) { OP_CallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), playout->callFlags, (playout->Options & CallIExtended_SpreadArgs) ? m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody()) : nullptr); }
  424. template <class T> void OP_ProfiledCallI(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_ProfileCallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), Js::CallFlags_None, playout->profileId); }
  425. template <class T> void OP_ProfiledCallIFlags(const unaligned T* playout) { OP_ProfileCallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), playout->callFlags, playout->profileId); }
  426. template <class T> void OP_ProfiledCallIExtended(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_ProfileCallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), Js::CallFlags_None, playout->profileId, Js::Constants::NoInlineCacheIndex, (playout->Options & CallIExtended_SpreadArgs) ? m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody()) : nullptr); }
  427. template <class T> void OP_ProfiledCallIExtendedFlags(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_ProfileCallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), playout->callFlags, playout->profileId, Js::Constants::NoInlineCacheIndex, (playout->Options & CallIExtended_SpreadArgs) ? m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody()) : nullptr); }
  428. template <class T> void OP_ProfiledCallIWithICIndex(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_ProfileCallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), Js::CallFlags_None, playout->profileId, playout->inlineCacheIndex); }
  429. template <class T> void OP_ProfiledCallIFlagsWithICIndex(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_ProfileCallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), playout->callFlags, playout->profileId, playout->inlineCacheIndex); }
  430. template <class T> void OP_ProfiledCallIExtendedWithICIndex(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_ProfileCallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), Js::CallFlags_None, playout->profileId, playout->inlineCacheIndex, (playout->Options & CallIExtended_SpreadArgs) ? m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody()) : nullptr); }
  431. template <class T> void OP_ProfiledCallIExtendedFlagsWithICIndex(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_ProfileCallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), playout->callFlags, playout->profileId, playout->inlineCacheIndex, (playout->Options & CallIExtended_SpreadArgs) ? m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody()) : nullptr); }
  432. template <class T> void OP_ProfiledReturnTypeCallI(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_ProfileReturnTypeCallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), Js::CallFlags_None, playout->profileId); }
  433. template <class T> void OP_ProfiledReturnTypeCallIFlags(const unaligned T* playout) { OP_ProfileReturnTypeCallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), playout->callFlags, playout->profileId); }
  434. template <class T> void OP_ProfiledReturnTypeCallIExtended(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_ProfileReturnTypeCallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), Js::CallFlags_None, playout->profileId, (playout->Options & CallIExtended_SpreadArgs) ? m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody()) : nullptr); }
  435. template <class T> void OP_ProfiledReturnTypeCallIExtendedFlags(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_ProfileReturnTypeCallCommon(playout, OP_CallGetFunc(GetRegAllowStackVar(playout->Function)), playout->callFlags, playout->profileId, (playout->Options & CallIExtended_SpreadArgs) ? m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody()) : nullptr); }
  436. // Patching Fastpath Operations
  437. template <class T> void OP_GetRootProperty(unaligned T* playout);
  438. template <class T> void OP_GetRootPropertyForTypeOf(unaligned T* playout);
  439. template <class T> void OP_GetRootProperty_NoFastPath(unaligned T* playout);
  440. template <class T, bool Root, bool Method, bool CallApplyTarget> void ProfiledGetProperty(unaligned T* playout, const Var instance);
  441. template <class T> void OP_ProfiledGetRootProperty(unaligned T* playout);
  442. template <class T> void OP_ProfiledGetRootPropertyForTypeOf(unaligned T* playout);
  443. template <class T> void OP_GetProperty(Var instance, unaligned T* playout);
  444. template <class T> void OP_GetProperty(unaligned T* playout);
  445. template <class T> void OP_GetLocalProperty(unaligned T* playout);
  446. template <class T> void OP_GetSuperProperty(unaligned T* playout);
  447. template <class T> void OP_GetPropertyForTypeOf(unaligned T* playout);
  448. template <class T> void OP_GetProperty_NoFastPath(Var instance, unaligned T* playout);
  449. template <class T> void OP_ProfiledGetProperty(unaligned T* playout);
  450. template <class T> void OP_ProfiledGetLocalProperty(unaligned T* playout);
  451. template <class T> void OP_ProfiledGetSuperProperty(unaligned T* playout);
  452. template <class T> void OP_ProfiledGetPropertyForTypeOf(unaligned T* playout);
  453. template <class T> void OP_ProfiledGetPropertyCallApplyTarget(unaligned T* playout);
  454. template <class T> void OP_GetRootMethodProperty(unaligned T* playout);
  455. template <class T> void OP_GetRootMethodProperty_NoFastPath(unaligned T* playout);
  456. template <class T> void OP_ProfiledGetRootMethodProperty(unaligned T* playout);
  457. template <class T> void OP_GetMethodProperty(unaligned T* playout);
  458. template <class T> void OP_GetLocalMethodProperty(unaligned T* playout);
  459. template <class T> void OP_GetMethodProperty(Var varInstance, unaligned T* playout);
  460. template <class T> void OP_GetMethodProperty_NoFastPath(Var varInstance, unaligned T* playout);
  461. template <class T> void OP_ProfiledGetMethodProperty(unaligned T* playout);
  462. template <class T> void OP_ProfiledGetLocalMethodProperty(unaligned T* playout);
  463. template <typename T> void OP_GetPropertyScoped(const unaligned OpLayoutT_ElementP<T>* playout);
  464. template <typename T> void OP_GetPropertyForTypeOfScoped(const unaligned OpLayoutT_ElementP<T>* playout);
  465. template <typename T> void OP_GetPropertyScoped_NoFastPath(const unaligned OpLayoutT_ElementP<T>* playout);
  466. template <class T> void OP_GetMethodPropertyScoped(unaligned T* playout);
  467. template <class T> void OP_GetMethodPropertyScoped_NoFastPath(unaligned T* playout);
  468. #if ENABLE_PROFILE_INFO
  469. template <class T> void UpdateFldInfoFlagsForGetSetInlineCandidate(unaligned T* playout, FldInfoFlags& fldInfoFlags, CacheType cacheType,
  470. DynamicProfileInfo * dynamicProfileInfo, uint inlineCacheIndex, RecyclableObject * obj);
  471. template <class T> void UpdateFldInfoFlagsForCallApplyInlineCandidate(unaligned T* playout, FldInfoFlags& fldInfoFlags, CacheType cacheType,
  472. DynamicProfileInfo * dynamicProfileInfo, uint inlineCacheIndex, RecyclableObject * obj);
  473. #endif
  474. template <class T> void OP_SetProperty(unaligned T* playout);
  475. template <class T> void OP_SetLocalProperty(unaligned T* playout);
  476. template <class T> void OP_SetSuperProperty(unaligned T* playout);
  477. template <class T> void OP_ProfiledSetProperty(unaligned T* playout);
  478. template <class T> void OP_ProfiledSetLocalProperty(unaligned T* playout);
  479. template <class T> void OP_ProfiledSetSuperProperty(unaligned T* playout);
  480. template <class T> void OP_SetRootProperty(unaligned T* playout);
  481. template <class T> void OP_ProfiledSetRootProperty(unaligned T* playout);
  482. template <class T> void OP_SetPropertyStrict(unaligned T* playout);
  483. template <class T> void OP_ProfiledSetPropertyStrict(unaligned T* playout);
  484. template <class T> void OP_SetRootPropertyStrict(unaligned T* playout);
  485. template <class T> void OP_ProfiledSetRootPropertyStrict(unaligned T* playout);
  486. template <class T> void OP_SetPropertyScoped(unaligned T* playout, PropertyOperationFlags flags = PropertyOperation_None);
  487. template <class T> void OP_SetPropertyScoped_NoFastPath(unaligned T* playout, PropertyOperationFlags flags);
  488. template <class T> void OP_SetPropertyScopedStrict(unaligned T* playout);
  489. template <class T> void OP_ConsoleSetPropertyScoped(unaligned T* playout);
  490. template <class T> void OP_ConsoleSetPropertyScopedStrict(unaligned T* playout);
  491. template <class T> void DoSetProperty(unaligned T* playout, Var instance, PropertyOperationFlags flags);
  492. template <class T> void DoSetSuperProperty(unaligned T* playout, Var instance, PropertyOperationFlags flags);
  493. template <class T> void DoSetProperty_NoFastPath(unaligned T* playout, Var instance, PropertyOperationFlags flags);
  494. template <class T> void DoSetSuperProperty_NoFastPath(unaligned T* playout, Var instance, PropertyOperationFlags flags);
  495. template <class T, bool Root> void ProfiledSetProperty(unaligned T* playout, Var instance, PropertyOperationFlags flags);
  496. template <class T, bool Root> void ProfiledSetSuperProperty(unaligned T* playout, Var instance, Var thisInstance, PropertyOperationFlags flags);
  497. template <class T> void OP_InitProperty(unaligned T* playout);
  498. template <class T> void OP_InitLocalProperty(unaligned T* playout);
  499. template <class T> void OP_InitRootProperty(unaligned T* playout);
  500. template <class T> void OP_InitUndeclLetProperty(unaligned T* playout);
  501. template <class T> void OP_InitUndeclLocalLetProperty(unaligned T* playout);
  502. void OP_InitUndeclRootLetProperty(uint propertyIdIndex);
  503. template <class T> void OP_InitUndeclConstProperty(unaligned T* playout);
  504. template <class T> void OP_InitUndeclLocalConstProperty(unaligned T* playout);
  505. void OP_InitUndeclRootConstProperty(uint propertyIdIndex);
  506. template <class T> void OP_InitUndeclConsoleLetProperty(unaligned T* playout);
  507. template <class T> void OP_InitUndeclConsoleConstProperty(unaligned T* playout);
  508. template <class T> void OP_ProfiledInitProperty(unaligned T* playout);
  509. template <class T> void OP_ProfiledInitLocalProperty(unaligned T* playout);
  510. template <class T> void OP_ProfiledInitRootProperty(unaligned T* playout);
  511. template <class T> void OP_ProfiledInitUndeclProperty(unaligned T* playout);
  512. template <class T> void DoInitProperty(unaligned T* playout, Var instance);
  513. template <class T> void DoInitProperty_NoFastPath(unaligned T* playout, Var instance);
  514. template <class T> void ProfiledInitProperty(unaligned T* playout, Var instance);
  515. template <class T> bool TrySetPropertyLocalFastPath(unaligned T* playout, PropertyId pid, RecyclableObject* instance, InlineCache*& inlineCache, PropertyOperationFlags flags = PropertyOperation_None);
  516. template <bool doProfile> Var ProfiledDivide(Var aLeft, Var aRight, ScriptContext* scriptContext, ProfileId profileId);
  517. template <bool doProfile> Var ProfileModulus(Var aLeft, Var aRight, ScriptContext* scriptContext, ProfileId profileId);
  518. template <bool doProfile> Var ProfiledSwitch(Var exp, ProfileId profileId);
  519. // Non-patching Fastpath operations
  520. template <typename T> void OP_GetElementI(const unaligned T* playout);
  521. template <typename T> void OP_ProfiledGetElementI(const unaligned OpLayoutDynamicProfile<T>* playout);
  522. template <typename T> void OP_SetElementI(const unaligned T* playout, PropertyOperationFlags flags = PropertyOperation_None);
  523. template <typename T> void OP_ProfiledSetElementI(const unaligned OpLayoutDynamicProfile<T>* playout, PropertyOperationFlags flags = PropertyOperation_None);
  524. template <typename T> void OP_SetElementIStrict(const unaligned T* playout);
  525. template <typename T> void OP_ProfiledSetElementIStrict(const unaligned OpLayoutDynamicProfile<T>* playout);
  526. template<class T> void OP_LdLen(const unaligned T *const playout);
  527. template<class T> void OP_ProfiledLdLen(const unaligned OpLayoutDynamicProfile<T> *const playout);
  528. template <bool doProfile> Var ProfiledIsIn(Var argProperty, Var instance, ScriptContext* scriptContext, ProfileId profileId);
  529. Var OP_ProfiledLdThis(Var thisVar, int moduleID, ScriptContext* scriptContext);
  530. Var OP_ProfiledStrictLdThis(Var thisVar, ScriptContext* scriptContext);
  531. template <class T> void OP_SetArrayItemI_CI4(const unaligned T* playout);
  532. template <class T> void OP_SetArrayItemC_CI4(const unaligned T* playout);
  533. template <class T> void OP_SetArraySegmentItem_CI4(const unaligned T* playout);
  534. template <class T> void SetArrayLiteralItem(JavascriptArray *arr, uint32 index, T value);
  535. void OP_SetArraySegmentVars(const unaligned OpLayoutAuxiliary * playout);
  536. template <class T> void OP_NewScArray(const unaligned T * playout);
  537. template <bool Profiled, class T> void ProfiledNewScArray(const unaligned OpLayoutDynamicProfile<T> * playout);
  538. template <class T> void OP_ProfiledNewScArray(const unaligned OpLayoutDynamicProfile<T> * playout) { ProfiledNewScArray<true, T>(playout); }
  539. template <class T> void OP_ProfiledNewScArray_NoProfile(const unaligned OpLayoutDynamicProfile<T> * playout) { ProfiledNewScArray<false, T>(playout); }
  540. void OP_NewScIntArray(const unaligned OpLayoutAuxiliary * playout);
  541. void OP_NewScFltArray(const unaligned OpLayoutAuxiliary * playout);
  542. void OP_ProfiledNewScIntArray(const unaligned OpLayoutDynamicProfile<OpLayoutAuxiliary> * playout);
  543. void OP_ProfiledNewScFltArray(const unaligned OpLayoutDynamicProfile<OpLayoutAuxiliary> * playout);
  544. template <class T> void OP_LdArrayHeadSegment(const unaligned T* playout);
  545. inline JavascriptFunction* GetFunctionExpression();
  546. template <class T> inline void OP_LdFunctionExpression(const unaligned T* playout);
  547. template <class T> inline void OP_StFunctionExpression(const unaligned T* playout);
  548. template <class T> inline void OP_StLocalFunctionExpression(const unaligned T* playout);
  549. void OP_StFunctionExpression(Var instance, Var value, PropertyIdIndexType index);
  550. template <class T> inline void OP_LdNewTarget(const unaligned T* playout);
  551. inline Var OP_Ld_A(Var aValue);
  552. inline Var OP_LdLocalObj();
  553. inline Var OP_LdParamObj();
  554. void OP_ChkUndecl(Var aValue);
  555. void OP_ChkNewCallFlag();
  556. void OP_EnsureNoRootProperty(uint propertyIdIndex);
  557. void OP_EnsureNoRootRedeclProperty(uint propertyIdIndex);
  558. void OP_ScopedEnsureNoRedeclProperty(Var aValue, uint propertyIdIndex, Var aValue2);
  559. Var OP_InitUndecl();
  560. void OP_InitUndeclSlot(Var aValue, int32 slot);
  561. template <class T> inline void OP_InitInnerFld(const unaligned T * playout);
  562. template <class T> inline void OP_InitLetFld(const unaligned T * playout);
  563. template <class T> inline void OP_InitLocalLetFld(const unaligned T* playout);
  564. template <class T> inline void OP_InitInnerLetFld(const unaligned T * playout);
  565. template <class T> inline void OP_InitRootLetFld(const unaligned T * playout);
  566. template <class T> inline void OP_InitConstFld(const unaligned T * playout);
  567. template <class T> inline void OP_InitRootConstFld(const unaligned T * playout);
  568. template <class T> inline void DoInitLetFld(const unaligned T * playout, Var instance, PropertyOperationFlags flags = PropertyOperation_None);
  569. template <class T> inline void DoInitConstFld(const unaligned T * playout, Var instance, PropertyOperationFlags flags = PropertyOperation_None);
  570. template <class T> inline void OP_InitClassMember(const unaligned T * playout);
  571. template <class T> inline void OP_InitClassMemberComputedName(const unaligned T * playout);
  572. template <class T> inline void OP_InitClassMemberGet(const unaligned T * playout);
  573. template <class T> inline void OP_InitClassMemberSet(const unaligned T * playout);
  574. template <class T> inline void OP_InitClassMemberGetComputedName(const unaligned T * playout);
  575. template <class T> inline void OP_InitClassMemberSetComputedName(const unaligned T * playout);
  576. template <typename ArrayType, typename RegType = ArrayType> inline void OP_LdArr( uint32 index, RegSlot value );
  577. template <class T> inline void OP_LdArrFunc(const unaligned T* playout);
  578. template <class T> inline void OP_LdArrWasmFunc(const unaligned T* playout);
  579. template <class T> inline void OP_CheckSignature(const unaligned T* playout);
  580. template<typename T> T GetArrayViewOverflowVal();
  581. template <typename ArrayType, typename RegType = ArrayType> inline void OP_StArr( uint32 index, RegSlot value );
  582. template <class T> inline void OP_LdAsmJsSlot(const unaligned T* playout );
  583. template <class T, typename T2> inline void OP_StSlotPrimitive(const unaligned T* playout);
  584. template <class T, typename T2> inline void OP_LdSlotPrimitive( const unaligned T* playout );
  585. template <class T> inline void OP_LdArrGeneric ( const unaligned T* playout );
  586. template <class T> inline void OP_LdArrWasm ( const unaligned T* playout );
  587. template <class T> inline void OP_LdArrConstIndex( const unaligned T* playout );
  588. template <class T> inline void OP_StArrGeneric ( const unaligned T* playout );
  589. template <class T> inline void OP_StArrWasm ( const unaligned T* playout );
  590. template <class T> inline void OP_StArrConstIndex( const unaligned T* playout );
  591. template <class T> inline void OP_LdArrAtomic ( const unaligned T* playout );
  592. template <class T> inline void OP_StArrAtomic ( const unaligned T* playout );
  593. template<typename MemType> void WasmArrayBoundsCheck(uint64 index, uint32 byteLength);
  594. template<typename MemType> MemType* WasmAtomicsArrayBoundsCheck(byte* buffer, uint64 index, uint32 byteLength);
  595. inline Var OP_LdSlot(Var instance, int32 slotIndex);
  596. inline Var OP_LdObjSlot(Var instance, int32 slotIndex);
  597. inline Var OP_LdFrameDisplaySlot(Var instance, int32 slotIndex);
  598. template <class T> inline Var OP_LdSlot(Var instance, const unaligned T* playout);
  599. template <class T> inline Var OP_ProfiledLdSlot(Var instance, const unaligned T* playout);
  600. template <class T> inline Var OP_LdInnerSlot(Var instance, const unaligned T* playout);
  601. template <class T> inline Var OP_ProfiledLdInnerSlot(Var instance, const unaligned T* playout);
  602. template <class T> inline Var OP_LdInnerObjSlot(Var instance, const unaligned T* playout);
  603. template <class T> inline Var OP_ProfiledLdInnerObjSlot(Var instance, const unaligned T* playout);
  604. template <class T> inline Var OP_LdEnvSlot(Var instance, const unaligned T* playout);
  605. template <class T> inline Var OP_ProfiledLdEnvSlot(Var instance, const unaligned T* playout);
  606. template <class T> inline Var OP_LdEnvObj(Var instance, const unaligned T* playout);
  607. template <class T> inline Var OP_LdObjSlot(Var instance, const unaligned T* playout);
  608. template <class T> inline Var OP_ProfiledLdObjSlot(Var instance, const unaligned T* playout);
  609. template <class T> inline Var OP_LdEnvObjSlot(Var instance, const unaligned T* playout);
  610. template <class T> inline Var OP_ProfiledLdEnvObjSlot(Var instance, const unaligned T* playout);
  611. template <class T> inline Var OP_LdModuleSlot(Var instance, const unaligned T* playout);
  612. inline void OP_StModuleSlot(Var instance, uint32 slotIndex1, uint32 slotIndex2, Var value);
  613. inline void OP_StSlot(Var instance, int32 slotIndex, Var value);
  614. inline void OP_StSlotChkUndecl(Var instance, int32 slotIndex, Var value);
  615. inline void OP_StEnvSlot(Var instance, int32 slotIndex1, int32 slotIndex2, Var value);
  616. inline void OP_StEnvSlotChkUndecl(Var instance, int32 slotIndex1, int32 slotIndex2, Var value);
  617. inline void OP_StObjSlot(Var instance, int32 slotIndex, Var value);
  618. inline void OP_StObjSlotChkUndecl(Var instance, int32 slotIndex, Var value);
  619. inline void OP_StEnvObjSlot(Var instance, int32 slotIndex1, int32 slotIndex2, Var value);
  620. inline void OP_StEnvObjSlotChkUndecl(Var instance, int32 slotIndex1, int32 slotIndex2, Var value);
  621. inline void* OP_LdArgCnt();
  622. template <bool letArgs> Var LdHeapArgumentsImpl(Var argsArray, ScriptContext* scriptContext);
  623. Var OP_LdHeapArguments(ScriptContext* scriptContext);
  624. inline Var OP_LdLetHeapArguments(ScriptContext* scriptContext);
  625. inline Var OP_LdHeapArgsCached(ScriptContext* scriptContext);
  626. inline Var OP_LdLetHeapArgsCached(ScriptContext* scriptContext);
  627. inline Var OP_LdStackArgPtr();
  628. inline Var OP_LdArgumentsFromFrame();
  629. Var OP_NewScObjectSimple();
  630. void OP_NewScObjectLiteral(const unaligned OpLayoutAuxiliary * playout);
  631. void OP_NewScObjectLiteral_LS(const unaligned OpLayoutAuxiliary * playout, RegSlot& target);
  632. void OP_LdPropIds(const unaligned OpLayoutAuxiliary * playout);
  633. template <bool Profile, bool JITLoopBody> void LoopBodyStart(uint32 loopNumber, LayoutSize layoutSize, bool isFirstIteration);
  634. LoopHeader const * DoLoopBodyStart(uint32 loopNumber, LayoutSize layoutSize, const bool doProfileLoopCheck, bool isFirstIteration);
  635. template <bool Profile, bool JITLoopBody> void ProfiledLoopBodyStart(uint32 loopNumber, LayoutSize layoutSize, bool isFirstIteration);
  636. void OP_RecordImplicitCall(uint loopNumber);
  637. template <class T, bool Profiled, bool ICIndex> void OP_NewScObject_Impl(const unaligned T* playout, InlineCacheIndex inlineCacheIndex = Js::Constants::NoInlineCacheIndex, const Js::AuxArray<uint32> *spreadIndices = nullptr);
  638. template <class T, bool Profiled> void OP_NewScObjArray_Impl(const unaligned T* playout, const Js::AuxArray<uint32> *spreadIndices = nullptr);
  639. template <class T> void OP_NewScObject(const unaligned T* playout) { OP_NewScObject_Impl<T, false, false>(playout); }
  640. template <class T> void OP_NewScObjectNoCtorFull(const unaligned T* playout);
  641. template <class T> void OP_NewScObjectSpread(const unaligned T* playout) { OP_NewScObject_Impl<T, false, false>(playout, Js::Constants::NoInlineCacheIndex, m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody())); }
  642. template <class T> void OP_NewScObjArray(const unaligned T* playout) { OP_NewScObjArray_Impl<T, false>(playout); }
  643. template <class T> void OP_NewScObjArraySpread(const unaligned T* playout) { OP_NewScObjArray_Impl<T, false>(playout, m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody())); }
  644. template <class T> void OP_ProfiledNewScObject(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_NewScObject_Impl<T, true, false>(playout); }
  645. template <class T> void OP_ProfiledNewScObjectSpread(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_NewScObject_Impl<T, true, false>(playout, Js::Constants::NoInlineCacheIndex, m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody())); }
  646. template <class T> void OP_ProfiledNewScObjectWithICIndex(const unaligned OpLayoutDynamicProfile<T>* playout) { OP_NewScObject_Impl<T, true, true>(playout, playout->inlineCacheIndex); }
  647. template <class T> void OP_ProfiledNewScObjArray(const unaligned OpLayoutDynamicProfile2<T>* playout) { OP_NewScObjArray_Impl<T, true>(playout); }
  648. template <class T> void OP_ProfiledNewScObjArray_NoProfile(const unaligned OpLayoutDynamicProfile2<T>* playout) { OP_NewScObjArray_Impl<T, false>(playout); }
  649. template <class T> void OP_ProfiledNewScObjArraySpread(const unaligned OpLayoutDynamicProfile2<T>* playout) { OP_NewScObjArray_Impl<T, true>(playout, m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody())); }
  650. template <class T> void OP_ProfiledNewScObjArraySpread_NoProfile(const unaligned OpLayoutDynamicProfile2<T>* playout) { OP_NewScObjArray_Impl<T, true>(playout, m_reader.ReadAuxArray<uint32>(playout->SpreadAuxOffset, this->GetFunctionBody())); }
  651. Var NewScObject_Helper(Var target, ArgSlot ArgCount, const Js::AuxArray<uint32> *spreadIndices = nullptr);
  652. Var ProfiledNewScObject_Helper(Var target, ArgSlot ArgCount, ProfileId profileId, InlineCacheIndex inlineCacheIndex, const Js::AuxArray<uint32> *spreadIndices = nullptr);
  653. template <class T, bool Profiled, bool ICIndex> Var OP_NewScObjectNoArg_Impl(const unaligned T *playout, InlineCacheIndex inlineCacheIndex = Js::Constants::NoInlineCacheIndex);
  654. void OP_NewScObject_A_Impl(const unaligned OpLayoutAuxiliary * playout, RegSlot *target = nullptr);
  655. void OP_NewScObject_A(const unaligned OpLayoutAuxiliary * playout) { return OP_NewScObject_A_Impl(playout); }
  656. void OP_InitCachedFuncs(const unaligned OpLayoutAuxNoReg * playout);
  657. Var OP_GetCachedFunc(Var instance, int32 index);
  658. void OP_CommitScope();
  659. void OP_CommitScopeHelper(const PropertyIdArray *propIds);
  660. void OP_TryCatch(const unaligned OpLayoutBr* playout);
  661. void ProcessCatch();
  662. int ProcessFinally();
  663. void ProcessTryHandlerBailout(EHBailoutData * innermostEHBailoutData, uint32 tryNestingDepth);
  664. void OP_TryFinally(const unaligned OpLayoutBr* playout);
  665. void OP_TryFinallyWithYield(const byte* ip, Js::JumpOffset jumpOffset, Js::RegSlot regException, Js::RegSlot regOffset);
  666. void OP_ResumeCatch();
  667. void OP_ResumeFinally(const byte* ip, Js::JumpOffset jumpOffset, RegSlot exceptionRegSlot, RegSlot offsetRegSlot);
  668. inline Var OP_ResumeYield(Var yieldDataVar, RegSlot yieldStarIterator = Js::Constants::NoRegister);
  669. template <typename T> void OP_IsInst(const unaligned T * playout);
  670. template <class T> void OP_InitClass(const unaligned OpLayoutT_Class<T> * playout);
  671. inline Var OP_LdHomeObj(ScriptContext * scriptContext);
  672. inline Var OP_LdFuncObj(ScriptContext * scriptContext);
  673. template <typename T> void OP_LdElementUndefined(const unaligned OpLayoutT_ElementU<T>* playout);
  674. template <typename T> void OP_LdLocalElementUndefined(const unaligned OpLayoutT_ElementRootU<T>* playout);
  675. template <typename T> void OP_LdElementUndefinedScoped(const unaligned OpLayoutT_ElementScopedU<T>* playout);
  676. void OP_SpreadArrayLiteral(const unaligned OpLayoutReg2Aux * playout);
  677. template <LayoutSize layoutSize,bool profiled> const byte * OP_ProfiledLoopStart(const byte *ip);
  678. template <LayoutSize layoutSize,bool profiled> const byte * OP_ProfiledLoopEnd(const byte *ip);
  679. template <LayoutSize layoutSize, bool profiled> const byte * OP_ProfiledLoopBodyStart(const byte *ip);
  680. template <LayoutSize layoutSize, bool profiled> const byte * OP_ProfiledWasmLoopBodyStart(const byte *ip);
  681. template <LayoutSize layoutSize, bool profiled> const byte * OP_ProfiledLoopBodyStart(uint loopId);
  682. template <typename T> void OP_ApplyArgs(const unaligned OpLayoutT_Reg5<T> * playout);
  683. template <class T> void OP_EmitTmpRegCount(const unaligned OpLayoutT_Unsigned1<T> * ip);
  684. Var OP_ImportCall(Var specifier, ScriptContext *scriptContext);
  685. HeapArgumentsObject * CreateEmptyHeapArgumentsObject(ScriptContext* scriptContext);
  686. void TrySetFrameObjectInHeapArgObj(ScriptContext * scriptContext, bool hasNonSimpleParam, bool isScopeObjRestored);
  687. Var InnerScopeFromIndex(uint32 index) const;
  688. void SetInnerScopeFromIndex(uint32 index, Var scope);
  689. void OP_NewInnerScopeSlots(uint index, uint count, int scopeIndex, ScriptContext *scriptContext, FunctionBody *functionBody);
  690. template <typename T> void OP_CloneInnerScopeSlots(const unaligned OpLayoutT_Unsigned1<T> *playout);
  691. template <typename T> void OP_CloneBlockScope(const unaligned OpLayoutT_Unsigned1<T> *playout);
  692. FrameDisplay * OP_LdFrameDisplay(void *argHead, void *argEnv, ScriptContext *scriptContext);
  693. FrameDisplay * OP_LdFrameDisplaySetLocal(void *argHead, void *argEnv, ScriptContext *scriptContext);
  694. template <bool innerFD> FrameDisplay * OP_LdFrameDisplayNoParent(void *argHead, ScriptContext *scriptContext);
  695. FrameDisplay * OP_LdFuncExprFrameDisplaySetLocal(void *argHead1, void *argHead2, ScriptContext *scriptContext);
  696. FrameDisplay * OP_LdInnerFrameDisplay(void *argHead, void *argEnv, ScriptContext *scriptContext);
  697. FrameDisplay * OP_LdInnerFrameDisplayNoParent(void *argHead, ScriptContext *scriptContext);
  698. template <class T> void OP_NewStackScFunc(const unaligned T * playout);
  699. template <class T> void OP_NewInnerStackScFunc(const unaligned T * playout);
  700. template <class T> void OP_DeleteFld(const unaligned T * playout);
  701. template <class T> void OP_DeleteLocalFld(const unaligned T * playout);
  702. template <class T> void OP_DeleteRootFld(const unaligned T * playout);
  703. template <class T> void OP_DeleteFldStrict(const unaligned T * playout);
  704. template <class T> void OP_DeleteRootFldStrict(const unaligned T * playout);
  705. template <typename T> void OP_ScopedDeleteFld(const unaligned OpLayoutT_ElementScopedC<T> * playout);
  706. template <typename T> void OP_ScopedDeleteFldStrict(const unaligned OpLayoutT_ElementScopedC<T> * playout);
  707. template <class T> void OP_ScopedLdInst(const unaligned T * playout);
  708. template <typename T> void OP_ScopedInitFunc(const unaligned OpLayoutT_ElementScopedC<T> * playout);
  709. template <class T> void OP_ClearAttributes(const unaligned T * playout);
  710. template <class T> void OP_InitGetFld(const unaligned T * playout);
  711. template <class T> void OP_InitSetFld(const unaligned T * playout);
  712. template <class T> void OP_InitSetElemI(const unaligned T * playout);
  713. template <class T> void OP_InitGetElemI(const unaligned T * playout);
  714. template <class T> void OP_InitComputedProperty(const unaligned T * playout);
  715. template <class T> void OP_InitProto(const unaligned T * playout);
  716. void OP_BeginBodyScope();
  717. void OP_InitForInEnumerator(Var object, uint forInLoopLevel);
  718. void OP_InitForInEnumeratorWithCache(Var object, uint forInLoopLevel, ProfileId profileId);
  719. ForInObjectEnumerator * GetForInEnumerator(uint forInLoopLevel);
  720. uint CallLoopBody(JavascriptMethod address);
  721. uint CallAsmJsLoopBody(JavascriptMethod address);
  722. void DoInterruptProbe();
  723. void CheckIfLoopIsHot(uint profiledLoopCounter);
  724. bool CheckAndResetImplicitCall(DisableImplicitFlags prevDisableImplicitFlags,ImplicitCallFlags savedImplicitCallFlags);
  725. class PushPopFrameHelper
  726. {
  727. public:
  728. PushPopFrameHelper(InterpreterStackFrame *interpreterFrame, void *returnAddress, void *addressOfReturnAddress)
  729. : m_threadContext(interpreterFrame->GetScriptContext()->GetThreadContext()), m_interpreterFrame(interpreterFrame), m_isHiddenFrame(false)
  730. {
  731. interpreterFrame->returnAddress = returnAddress; // Ensure these are set before pushing to interpreter frame list
  732. interpreterFrame->addressOfReturnAddress = addressOfReturnAddress;
  733. if (interpreterFrame->GetFunctionBody()->GetIsAsmjsMode())
  734. {
  735. m_isHiddenFrame = true;
  736. }
  737. else
  738. {
  739. m_threadContext->PushInterpreterFrame(interpreterFrame);
  740. }
  741. }
  742. ~ PushPopFrameHelper()
  743. {
  744. if (!m_isHiddenFrame)
  745. {
  746. Js::InterpreterStackFrame *interpreterFrame = m_threadContext->PopInterpreterFrame();
  747. AssertMsg(interpreterFrame == m_interpreterFrame,
  748. "Interpreter frame chain corrupted?");
  749. }
  750. }
  751. private:
  752. ThreadContext *m_threadContext;
  753. InterpreterStackFrame *m_interpreterFrame;
  754. bool m_isHiddenFrame;
  755. };
  756. inline InlineCache* GetInlineCache(uint cacheIndex)
  757. {
  758. Assert(this->inlineCaches != nullptr);
  759. Assert(cacheIndex < this->inlineCacheCount);
  760. return reinterpret_cast<InlineCache *>(this->inlineCaches[cacheIndex]);
  761. }
  762. inline IsInstInlineCache* GetIsInstInlineCache(uint cacheIndex)
  763. {
  764. return m_functionBody->GetIsInstInlineCache(cacheIndex);
  765. }
  766. inline PropertyId GetPropertyIdFromCacheId(uint cacheIndex)
  767. {
  768. return m_functionBody->GetPropertyIdFromCacheId(cacheIndex);
  769. }
  770. void InitializeStackFunctions(StackScriptFunction * scriptFunctions);
  771. StackScriptFunction * GetStackNestedFunction(uint index);
  772. void SetExecutingStackFunction(ScriptFunction * scriptFunction);
  773. friend class StackScriptFunction;
  774. void SetLocalFrameDisplay(FrameDisplay *frameDisplay);
  775. Var GetLocalClosure() const;
  776. void SetLocalClosure(Var closure);
  777. Var GetParamClosure() const;
  778. void SetParamClosure(Var closure);
  779. void TrySetRetOffset();
  780. };
  781. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  782. // Used to track how many interpreter stack frames we have on stack.
  783. class InterpreterThunkStackCountTracker
  784. {
  785. public:
  786. InterpreterThunkStackCountTracker() { ++s_count; }
  787. ~InterpreterThunkStackCountTracker() { --s_count; }
  788. static int GetCount() { return s_count; }
  789. private:
  790. THREAD_LOCAL static int s_count;
  791. };
  792. #endif
  793. } // namespace Js