StackScriptFunction.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  9. #define BOX_PARAM(function, returnAddress, reason) function, returnAddress, reason
  10. #else
  11. #define BOX_PARAM(function, returnAddress, reason) function, returnAddress
  12. #endif
  13. class StackScriptFunction : public ScriptFunction
  14. {
  15. public:
  16. static JavascriptFunction * EnsureBoxed(BOX_PARAM(JavascriptFunction * function, void * returnAddress, char16 const * reason));
  17. static void Box(FunctionBody * functionBody, ScriptFunction ** functionRef);
  18. static ScriptFunction * OP_NewStackScFunc(FrameDisplay *environment, FunctionInfoPtrPtr infoRef, ScriptFunction * stackFunction);
  19. static uint32 GetOffsetOfBoxedScriptFunction() { return offsetof(StackScriptFunction, boxedScriptFunction); }
  20. static JavascriptFunction * GetCurrentFunctionObject(JavascriptFunction * function);
  21. StackScriptFunction(FunctionProxy * proxy, ScriptFunctionType* deferredPrototypeType) :
  22. ScriptFunction(proxy, deferredPrototypeType), boxedScriptFunction(nullptr) {};
  23. #if DBG
  24. static bool IsBoxed(Var var)
  25. {
  26. return StackScriptFunction::FromVar(var)->boxedScriptFunction != nullptr;
  27. }
  28. #endif
  29. // A stack function object does not escape, so it should never be marshaled.
  30. // Defining this function also make the vtable unique, so that we can detect stack function
  31. // via the vtable
  32. DEFINE_VTABLE_CTOR(StackScriptFunction, ScriptFunction);
  33. virtual void MarshalToScriptContext(Js::ScriptContext * scriptContext) override
  34. {
  35. Assert(false);
  36. }
  37. private:
  38. static ScriptFunction * Box(StackScriptFunction * stackScriptFunction, void * returnAddress);
  39. static StackScriptFunction * FromVar(Var var);
  40. static StackScriptFunction * UnsafeFromVar(Var var);
  41. struct BoxState
  42. {
  43. public:
  44. BoxState(ArenaAllocator * alloc, FunctionBody * functionBody, ScriptContext * scriptContext, void * returnAddress = nullptr);
  45. void Box();
  46. ScriptFunction * GetBoxedScriptFunction(ScriptFunction * stackScriptFunction);
  47. private:
  48. JsUtil::BaseHashSet<FunctionBody *, ArenaAllocator> frameToBox;
  49. JsUtil::BaseHashSet<FunctionProxy *, ArenaAllocator> functionObjectToBox;
  50. JsUtil::BaseDictionary<void *, void*, ArenaAllocator> boxedValues;
  51. ScriptContext * scriptContext;
  52. void * returnAddress;
  53. Field(Var) * BoxScopeSlots(Field(Var) * scopeSlots, uint count);
  54. bool NeedBoxFrame(FunctionBody * functionBody);
  55. bool NeedBoxScriptFunction(ScriptFunction * scriptFunction);
  56. ScriptFunction * BoxStackFunction(ScriptFunction * scriptFunction);
  57. FrameDisplay * BoxFrameDisplay(FrameDisplay * frameDisplay);
  58. FrameDisplay * GetFrameDisplayFromNativeFrame(JavascriptStackWalker const& walker, FunctionBody * callerFunctionBody);
  59. Var * GetScopeSlotsFromNativeFrame(JavascriptStackWalker const& walker, FunctionBody * callerFunctionBody);
  60. void SetFrameDisplayFromNativeFrame(JavascriptStackWalker const& walker, FunctionBody * callerFunctionBody, FrameDisplay * frameDisplay);
  61. void SetScopeSlotsFromNativeFrame(JavascriptStackWalker const& walker, FunctionBody * callerFunctionBody, Var * scopeSlots);
  62. void BoxNativeFrame(JavascriptStackWalker const& walker, FunctionBody * callerFunctionBody);
  63. void UpdateFrameDisplay(ScriptFunction *nestedFunc);
  64. void Finish();
  65. template<class Fn>
  66. void ForEachStackNestedFunction(JavascriptStackWalker const& walker, FunctionBody * callerFunctionBody, Fn fn);
  67. template<class Fn>
  68. void ForEachStackNestedFunctionInterpreted(InterpreterStackFrame *interpreterFrame, FunctionBody * callerFunctionBody, Fn fn);
  69. template<class Fn>
  70. void ForEachStackNestedFunctionNative(JavascriptStackWalker const& walker, FunctionBody * callerFunctionBody, Fn fn);
  71. static uintptr_t GetNativeFrameDisplayIndex(FunctionBody * functionBody);
  72. static uintptr_t GetNativeScopeSlotsIndex(FunctionBody * functionBody);
  73. };
  74. ScriptFunction * boxedScriptFunction;
  75. #if ENABLE_TTD
  76. virtual TTD::NSSnapObjects::SnapObjectType GetSnapTag_TTD() const override;
  77. virtual void ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc) override;
  78. virtual void MarshalCrossSite_TTDInflate() override
  79. {
  80. Assert(false);
  81. }
  82. #endif
  83. public:
  84. virtual VTableValue DummyVirtualFunctionToHinderLinkerICF()
  85. {
  86. return VTableValue::VtableStackScriptFunction;
  87. }
  88. };
  89. };