BaselineFrame-inl.h (4616B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef jit_BaselineFrame_inl_h 8 #define jit_BaselineFrame_inl_h 9 10 #include "jit/BaselineFrame.h" 11 12 #include "jit/TrialInlining.h" 13 #include "jit/VMFunctions.h" 14 #include "vm/JSContext.h" 15 #include "vm/Realm.h" 16 17 #include "vm/EnvironmentObject-inl.h" 18 #include "vm/JSScript-inl.h" 19 #include "vm/NativeObject-inl.h" // js::NativeObject::initDenseElementsFromRange 20 21 namespace js { 22 namespace jit { 23 24 template <typename SpecificEnvironment> 25 inline void BaselineFrame::pushOnEnvironmentChain(SpecificEnvironment& env) { 26 MOZ_ASSERT(*environmentChain() == env.enclosingEnvironment()); 27 envChain_ = &env; 28 if (IsFrameInitialEnvironment(this, env)) { 29 flags_ |= HAS_INITIAL_ENV; 30 } 31 } 32 33 template <typename SpecificEnvironment> 34 inline void BaselineFrame::popOffEnvironmentChain() { 35 MOZ_ASSERT(envChain_->is<SpecificEnvironment>()); 36 envChain_ = &envChain_->as<SpecificEnvironment>().enclosingEnvironment(); 37 } 38 39 inline void BaselineFrame::replaceInnermostEnvironment(EnvironmentObject& env) { 40 MOZ_ASSERT(env.enclosingEnvironment() == 41 envChain_->as<EnvironmentObject>().enclosingEnvironment()); 42 envChain_ = &env; 43 } 44 45 inline bool BaselineFrame::saveGeneratorSlots(JSContext* cx, unsigned nslots, 46 ArrayObject* dest) const { 47 // By convention, generator slots are stored in interpreter order, 48 // which is the reverse of BaselineFrame order. 49 50 MOZ_ASSERT(nslots == numValueSlots(debugFrameSize()) - 1); 51 const Value* end = reinterpret_cast<const Value*>(this); 52 mozilla::Span<const Value> span{end - nslots, end}; 53 return dest->initDenseElementsFromRange(cx, span.rbegin(), span.rend()); 54 } 55 56 inline bool BaselineFrame::pushLexicalEnvironment(JSContext* cx, 57 Handle<LexicalScope*> scope) { 58 BlockLexicalEnvironmentObject* env = 59 BlockLexicalEnvironmentObject::createForFrame(cx, scope, this); 60 if (!env) { 61 return false; 62 } 63 pushOnEnvironmentChain(*env); 64 65 return true; 66 } 67 68 inline bool BaselineFrame::pushClassBodyEnvironment( 69 JSContext* cx, Handle<ClassBodyScope*> scope) { 70 ClassBodyLexicalEnvironmentObject* env = 71 ClassBodyLexicalEnvironmentObject::createForFrame(cx, scope, this); 72 if (!env) { 73 return false; 74 } 75 pushOnEnvironmentChain(*env); 76 77 return true; 78 } 79 80 template <bool IsDebuggee> 81 inline bool BaselineFrame::freshenLexicalEnvironment(JSContext* cx, 82 const jsbytecode* pc) { 83 Rooted<BlockLexicalEnvironmentObject*> current( 84 cx, &envChain_->as<BlockLexicalEnvironmentObject>()); 85 BlockLexicalEnvironmentObject* clone = 86 BlockLexicalEnvironmentObject::clone(cx, current); 87 if (!clone) { 88 return false; 89 } 90 91 if constexpr (IsDebuggee) { 92 MOZ_ASSERT(pc); 93 Rooted<BlockLexicalEnvironmentObject*> cloneRoot(cx, clone); 94 MOZ_ALWAYS_TRUE(DebugLeaveLexicalEnv(cx, this, pc)); 95 clone = cloneRoot; 96 } 97 98 replaceInnermostEnvironment(*clone); 99 return true; 100 } 101 102 template <bool IsDebuggee> 103 inline bool BaselineFrame::recreateLexicalEnvironment(JSContext* cx, 104 const jsbytecode* pc) { 105 Rooted<BlockLexicalEnvironmentObject*> current( 106 cx, &envChain_->as<BlockLexicalEnvironmentObject>()); 107 BlockLexicalEnvironmentObject* clone = 108 BlockLexicalEnvironmentObject::recreate(cx, current); 109 if (!clone) { 110 return false; 111 } 112 113 if constexpr (IsDebuggee) { 114 MOZ_ASSERT(pc); 115 Rooted<BlockLexicalEnvironmentObject*> cloneRoot(cx, clone); 116 MOZ_ALWAYS_TRUE(DebugLeaveLexicalEnv(cx, this, pc)); 117 clone = cloneRoot; 118 } 119 120 replaceInnermostEnvironment(*clone); 121 return true; 122 } 123 124 inline CallObject& BaselineFrame::callObj() const { 125 MOZ_ASSERT(hasInitialEnvironment()); 126 MOZ_ASSERT(callee()->needsCallObject()); 127 128 JSObject* obj = environmentChain(); 129 while (!obj->is<CallObject>()) { 130 obj = obj->enclosingEnvironment(); 131 } 132 return obj->as<CallObject>(); 133 } 134 135 inline JSScript* BaselineFrame::outerScript() const { 136 if (!icScript()->isInlined()) { 137 return script(); 138 } 139 return icScript()->inliningRoot()->owningScript(); 140 } 141 142 inline void BaselineFrame::unsetIsDebuggee() { 143 MOZ_ASSERT(!script()->isDebuggee()); 144 flags_ &= ~DEBUGGEE; 145 } 146 147 } // namespace jit 148 } // namespace js 149 150 #endif /* jit_BaselineFrame_inl_h */