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/. */
7 #ifndef jit_BaselineFrame_inl_h
8 #define jit_BaselineFrame_inl_h
10 #include "jit/BaselineFrame.h"
12 #include "jit/TrialInlining.h"
13 #include "jit/VMFunctions.h"
14 #include "vm/JSContext.h"
17 #include "vm/EnvironmentObject-inl.h"
18 #include "vm/JSScript-inl.h"
19 #include "vm/NativeObject-inl.h" // js::NativeObject::initDenseElementsFromRange
24 template <typename SpecificEnvironment
>
25 inline void BaselineFrame::pushOnEnvironmentChain(SpecificEnvironment
& env
) {
26 MOZ_ASSERT(*environmentChain() == env
.enclosingEnvironment());
28 if (IsFrameInitialEnvironment(this, env
)) {
29 flags_
|= HAS_INITIAL_ENV
;
33 template <typename SpecificEnvironment
>
34 inline void BaselineFrame::popOffEnvironmentChain() {
35 MOZ_ASSERT(envChain_
->is
<SpecificEnvironment
>());
36 envChain_
= &envChain_
->as
<SpecificEnvironment
>().enclosingEnvironment();
39 inline void BaselineFrame::replaceInnermostEnvironment(EnvironmentObject
& env
) {
40 MOZ_ASSERT(env
.enclosingEnvironment() ==
41 envChain_
->as
<EnvironmentObject
>().enclosingEnvironment());
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.
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());
56 inline bool BaselineFrame::pushLexicalEnvironment(JSContext
* cx
,
57 Handle
<LexicalScope
*> scope
) {
58 BlockLexicalEnvironmentObject
* env
=
59 BlockLexicalEnvironmentObject::createForFrame(cx
, scope
, this);
63 pushOnEnvironmentChain(*env
);
68 inline bool BaselineFrame::pushClassBodyEnvironment(
69 JSContext
* cx
, Handle
<ClassBodyScope
*> scope
) {
70 ClassBodyLexicalEnvironmentObject
* env
=
71 ClassBodyLexicalEnvironmentObject::createForFrame(cx
, scope
, this);
75 pushOnEnvironmentChain(*env
);
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
);
91 if constexpr (IsDebuggee
) {
93 Rooted
<BlockLexicalEnvironmentObject
*> cloneRoot(cx
, clone
);
94 MOZ_ALWAYS_TRUE(DebugLeaveLexicalEnv(cx
, this, pc
));
98 replaceInnermostEnvironment(*clone
);
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
);
113 if constexpr (IsDebuggee
) {
115 Rooted
<BlockLexicalEnvironmentObject
*> cloneRoot(cx
, clone
);
116 MOZ_ALWAYS_TRUE(DebugLeaveLexicalEnv(cx
, this, pc
));
120 replaceInnermostEnvironment(*clone
);
124 inline CallObject
& BaselineFrame::callObj() const {
125 MOZ_ASSERT(hasInitialEnvironment());
126 MOZ_ASSERT(callee()->needsCallObject());
128 JSObject
* obj
= environmentChain();
129 while (!obj
->is
<CallObject
>()) {
130 obj
= obj
->enclosingEnvironment();
132 return obj
->as
<CallObject
>();
135 inline JSScript
* BaselineFrame::outerScript() const {
136 if (!icScript()->isInlined()) {
139 return icScript()->inliningRoot()->owningScript();
142 inline void BaselineFrame::unsetIsDebuggee() {
143 MOZ_ASSERT(!script()->isDebuggee());
150 #endif /* jit_BaselineFrame_inl_h */