ScriptFunction.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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. namespace Js
  7. {
  8. class ScriptFunctionBase : public JavascriptFunction
  9. {
  10. protected:
  11. ScriptFunctionBase(DynamicType * type);
  12. ScriptFunctionBase(DynamicType * type, FunctionInfo * functionInfo);
  13. DEFINE_VTABLE_CTOR(ScriptFunctionBase, JavascriptFunction);
  14. public:
  15. virtual Var GetHomeObj() const = 0;
  16. virtual void SetHomeObj(Var homeObj) = 0;
  17. virtual void SetComputedNameVar(Var computedNameVar) = 0;
  18. virtual Var GetComputedNameVar() const = 0;
  19. virtual bool IsAnonymousFunction() const = 0;
  20. };
  21. template <> bool VarIsImpl<ScriptFunctionBase>(RecyclableObject* obj);
  22. template <class BaseClass>
  23. class FunctionWithComputedName : public BaseClass
  24. {
  25. private:
  26. Field(Var) computedNameVar;
  27. protected:
  28. DEFINE_VTABLE_CTOR(FunctionWithComputedName<BaseClass>, BaseClass);
  29. DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(FunctionWithComputedName<BaseClass>);
  30. public:
  31. FunctionWithComputedName(FunctionProxy * proxy, ScriptFunctionType* deferredPrototypeType)
  32. : BaseClass(proxy, deferredPrototypeType), computedNameVar(nullptr)
  33. {
  34. Assert(proxy->GetFunctionInfo()->HasComputedName());
  35. }
  36. virtual Var GetComputedNameVar() const override { return this->computedNameVar; }
  37. virtual void SetComputedNameVar(Var computedNameVar) override;
  38. virtual VTableValue DummyVirtualFunctionToHinderLinkerICF() const;
  39. };
  40. template <class BaseClass>
  41. class FunctionWithHomeObj : public BaseClass
  42. {
  43. private:
  44. Field(Var) homeObj;
  45. protected:
  46. DEFINE_VTABLE_CTOR(FunctionWithHomeObj<BaseClass>, BaseClass);
  47. DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(FunctionWithHomeObj<BaseClass>);
  48. public:
  49. FunctionWithHomeObj(FunctionProxy* proxy, ScriptFunctionType* deferredPrototypeType)
  50. : BaseClass(proxy, deferredPrototypeType), homeObj(nullptr)
  51. {
  52. Assert(proxy->GetFunctionInfo()->HasHomeObj());
  53. }
  54. virtual Var GetHomeObj() const override { return homeObj; }
  55. virtual void SetHomeObj(Var homeObj) override { this->homeObj = homeObj; }
  56. static uint32 GetOffsetOfHomeObj() { return offsetof(FunctionWithHomeObj<BaseClass>, homeObj); }
  57. virtual VTableValue DummyVirtualFunctionToHinderLinkerICF() const;
  58. };
  59. class ScriptFunction : public ScriptFunctionBase
  60. {
  61. private:
  62. Field(FrameDisplay*) environment; // Optional environment, for closures
  63. Field(ActivationObjectEx *) cachedScopeObj;
  64. Field(bool) hasInlineCaches;
  65. static JavascriptString* GetComputedName(Var computedNameVar, ScriptContext * scriptContext);
  66. static bool GetSymbolName(Var computedNameVar, const char16** symbolName, charcount_t *length);
  67. protected:
  68. DEFINE_VTABLE_CTOR(ScriptFunction, ScriptFunctionBase);
  69. DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(ScriptFunction);
  70. public:
  71. ScriptFunction(FunctionProxy * proxy, ScriptFunctionType* deferredPrototypeType);
  72. inline static BOOL Test(JavascriptFunction *func) { return func->IsScriptFunction(); }
  73. static ScriptFunction * OP_NewScFunc(FrameDisplay *environment, FunctionInfoPtrPtr infoRef);
  74. static ScriptFunction * OP_NewScFuncHomeObj(FrameDisplay *environment, FunctionInfoPtrPtr infoRef, Var homeObj);
  75. static ScriptFunction * OP_NewClassConstructor(FrameDisplay *environment, FunctionInfoPtrPtr infoRef, Var homeObject, RecyclableObject * constructorParent);
  76. static void CopyEntryPointInfoToThreadContextIfNecessary(ProxyEntryPointInfo* oldEntryPointInfo, ProxyEntryPointInfo* newEntryPointInfo);
  77. ProxyEntryPointInfo* GetEntryPointInfo() const;
  78. FunctionEntryPointInfo* GetFunctionEntryPointInfo() const
  79. {
  80. Assert(this->GetFunctionProxy()->IsDeferred() == FALSE);
  81. ProxyEntryPointInfo* result = this->GetEntryPointInfo();
  82. Assert(result->IsFunctionEntryPointInfo());
  83. return (FunctionEntryPointInfo*)result;
  84. }
  85. FunctionProxy * GetFunctionProxy() const;
  86. ScriptFunctionType * GetScriptFunctionType() const;
  87. FrameDisplay* GetEnvironment() const { return environment; }
  88. void SetEnvironment(FrameDisplay * environment);
  89. ActivationObjectEx *GetCachedScope() const { return cachedScopeObj; }
  90. void SetCachedScope(ActivationObjectEx *obj) { cachedScopeObj = obj; }
  91. void InvalidateCachedScopeChain();
  92. static uint32 GetOffsetOfEnvironment() { return offsetof(ScriptFunction, environment); }
  93. static uint32 GetOffsetOfCachedScopeObj() { return offsetof(ScriptFunction, cachedScopeObj); };
  94. static uint32 GetOffsetOfHasInlineCaches() { return offsetof(ScriptFunction, hasInlineCaches); };
  95. void ChangeEntryPoint(ProxyEntryPointInfo* entryPointInfo, JavascriptMethod entryPoint);
  96. JavascriptMethod UpdateThunkEntryPoint(FunctionEntryPointInfo* entryPointInfo, JavascriptMethod entryPoint);
  97. bool IsNewEntryPointAvailable();
  98. JavascriptMethod UpdateUndeferredBody(FunctionBody* newFunctionInfo);
  99. virtual ScriptFunctionType * DuplicateType() override;
  100. virtual void PrepareForConversionToNonPathType() override;
  101. virtual void ReplaceTypeWithPredecessorType(DynamicType * previousType) override;
  102. virtual Var GetSourceString() const;
  103. virtual JavascriptString * EnsureSourceString();
  104. bool GetHasInlineCaches() { return hasInlineCaches; }
  105. void SetHasInlineCaches(bool has) { hasInlineCaches = has; }
  106. bool HasSuperReference();
  107. virtual Var GetHomeObj() const override { return nullptr; }
  108. virtual void SetHomeObj(Var homeObj) override { AssertMsg(false, "Should have created FunctionWithHomeObj variant"); }
  109. virtual Var GetComputedNameVar() const override { return nullptr; }
  110. virtual void SetComputedNameVar(Var computedNameVar) override { AssertMsg(false, "Should have created the FunctionWithComputedName variant"); }
  111. virtual JavascriptString* GetDisplayNameImpl() const override;
  112. virtual bool IsAnonymousFunction() const override;
  113. virtual bool IsAsmJsFunction() const { return false; }
  114. virtual bool IsWasmFunction() const { return false; }
  115. virtual JavascriptFunction* GetRealFunctionObject() { return this; }
  116. bool HasFunctionBody();
  117. #if ENABLE_TTD
  118. public:
  119. virtual void MarkVisitKindSpecificPtrs(TTD::SnapshotExtractor* extractor) override;
  120. virtual void ProcessCorePaths() override;
  121. virtual TTD::NSSnapObjects::SnapObjectType GetSnapTag_TTD() const override;
  122. virtual void ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc) override;
  123. virtual void ExtractSnapObjectDataIntoSnapScriptFunctionInfo(/*TTD::NSSnapObjects::SnapScriptFunctionInfo* */ void* ssfi, TTD::SlabAllocator& alloc);
  124. #endif
  125. public:
  126. virtual VTableValue DummyVirtualFunctionToHinderLinkerICF()
  127. {
  128. return VTableValue::VtableScriptFunction;
  129. }
  130. };
  131. template <> inline bool VarIsImpl<ScriptFunction>(RecyclableObject* obj)
  132. {
  133. return VarIs<JavascriptFunction>(obj) && UnsafeVarTo<JavascriptFunction>(obj)->IsScriptFunction();
  134. }
  135. typedef FunctionWithComputedName<ScriptFunction> ScriptFunctionWithComputedName;
  136. typedef FunctionWithHomeObj<ScriptFunction> ScriptFunctionWithHomeObj;
  137. class AsmJsScriptFunction : public ScriptFunction
  138. {
  139. public:
  140. AsmJsScriptFunction(FunctionProxy * proxy, ScriptFunctionType* deferredPrototypeType);
  141. static AsmJsScriptFunction * OP_NewAsmJsFunc(FrameDisplay *environment, FunctionInfoPtrPtr infoRef);
  142. virtual bool IsAsmJsFunction() const override { return true; }
  143. void SetModuleEnvironment(Field(Var)* mem) { m_moduleEnvironment = mem; }
  144. Field(Var)* GetModuleEnvironment() const { return m_moduleEnvironment; }
  145. static uint32 GetOffsetOfModuleMemory() { return offsetof(AsmJsScriptFunction, m_moduleEnvironment); }
  146. class JavascriptArrayBuffer* GetAsmJsArrayBuffer() const;
  147. protected:
  148. DEFINE_VTABLE_CTOR(AsmJsScriptFunction, ScriptFunction);
  149. DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(AsmJsScriptFunction);
  150. private:
  151. Field(Field(Var)*) m_moduleEnvironment;
  152. };
  153. template <> inline bool VarIsImpl<AsmJsScriptFunction>(RecyclableObject* obj)
  154. {
  155. return VarIs<ScriptFunction>(obj) && UnsafeVarTo<ScriptFunction>(obj)->IsAsmJsFunction();
  156. }
  157. typedef FunctionWithComputedName<AsmJsScriptFunction> AsmJsScriptFunctionWithComputedName;
  158. #ifdef ENABLE_WASM
  159. class WasmScriptFunction : public AsmJsScriptFunction
  160. {
  161. public:
  162. WasmScriptFunction(FunctionProxy * proxy, ScriptFunctionType* deferredPrototypeType);
  163. void SetSignature(Wasm::WasmSignature * sig) { m_signature = sig; }
  164. Wasm::WasmSignature * GetSignature() const { return m_signature; }
  165. static uint32 GetOffsetOfSignature() { return offsetof(WasmScriptFunction, m_signature); }
  166. WebAssemblyMemory* GetWebAssemblyMemory() const;
  167. virtual bool IsWasmFunction() const override { return true; }
  168. protected:
  169. DEFINE_VTABLE_CTOR(WasmScriptFunction, AsmJsScriptFunction);
  170. DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(WasmScriptFunction);
  171. private:
  172. Field(Wasm::WasmSignature *) m_signature;
  173. };
  174. template <> inline bool VarIsImpl<WasmScriptFunction>(RecyclableObject* obj)
  175. {
  176. return VarIs<ScriptFunction>(obj) && UnsafeVarTo<ScriptFunction>(obj)->IsWasmFunction();
  177. }
  178. #else
  179. class WasmScriptFunction : public AsmJsScriptFunction
  180. {
  181. };
  182. template <> inline bool VarIsImpl<WasmScriptFunction>(RecyclableObject* obj) { return false; }
  183. #endif
  184. class ScriptFunctionWithInlineCache : public ScriptFunction
  185. {
  186. private:
  187. Field(void**) m_inlineCaches;
  188. #if DBG
  189. #define InlineCacheTypeNone 0x00
  190. #define InlineCacheTypeInlineCache 0x01
  191. #define InlineCacheTypeIsInst 0x02
  192. Field(byte *) m_inlineCacheTypes;
  193. #endif
  194. Field(uint) inlineCacheCount;
  195. Field(uint) rootObjectLoadInlineCacheStart;
  196. Field(uint) rootObjectLoadMethodInlineCacheStart;
  197. Field(uint) rootObjectStoreInlineCacheStart;
  198. Field(uint) isInstInlineCacheCount;
  199. protected:
  200. ScriptFunctionWithInlineCache(DynamicType * type);
  201. DEFINE_VTABLE_CTOR(ScriptFunctionWithInlineCache, ScriptFunction);
  202. DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(ScriptFunctionWithInlineCache);
  203. public:
  204. ScriptFunctionWithInlineCache(FunctionProxy * proxy, ScriptFunctionType* deferredPrototypeType);
  205. void CreateInlineCache();
  206. void AllocateInlineCache();
  207. void ClearInlineCacheOnFunctionObject();
  208. InlineCache * GetInlineCache(uint index);
  209. uint GetInlineCacheCount() { return inlineCacheCount; }
  210. Field(void**) GetInlineCaches() const { return m_inlineCaches; }
  211. static uint32 GetOffsetOfInlineCaches() { return offsetof(ScriptFunctionWithInlineCache, m_inlineCaches); };
  212. template<bool isShutdown>
  213. void FreeOwnInlineCaches();
  214. virtual void Finalize(bool isShutdown) override;
  215. };
  216. template <> inline bool VarIsImpl<ScriptFunctionWithInlineCache>(RecyclableObject* obj)
  217. {
  218. return VarIs<ScriptFunction>(obj) && UnsafeVarTo<ScriptFunction>(obj)->GetHasInlineCaches();
  219. }
  220. typedef FunctionWithComputedName<ScriptFunctionWithInlineCache> ScriptFunctionWithInlineCacheAndComputedName;
  221. } // namespace Js