Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
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 vm_JSScript_inl_h
8 : #define vm_JSScript_inl_h
9 :
10 : #include "vm/JSScript.h"
11 :
12 : #include <utility>
13 :
14 : #include "jit/BaselineJIT.h"
15 : #include "jit/IonAnalysis.h"
16 : #include "vm/EnvironmentObject.h"
17 : #include "vm/RegExpObject.h"
18 : #include "wasm/AsmJS.h"
19 :
20 : #include "vm/Realm-inl.h"
21 : #include "vm/Shape-inl.h"
22 :
23 : namespace js {
24 :
25 0 : ScriptCounts::ScriptCounts()
26 : : pcCounts_(),
27 : throwCounts_(),
28 0 : ionCounts_(nullptr)
29 : {
30 : }
31 :
32 3799 : ScriptCounts::ScriptCounts(PCCountsVector&& jumpTargets)
33 0 : : pcCounts_(std::move(jumpTargets)),
34 : throwCounts_(),
35 7598 : ionCounts_(nullptr)
36 : {
37 : }
38 :
39 0 : ScriptCounts::ScriptCounts(ScriptCounts&& src)
40 0 : : pcCounts_(std::move(src.pcCounts_)),
41 0 : throwCounts_(std::move(src.throwCounts_)),
42 0 : ionCounts_(std::move(src.ionCounts_))
43 : {
44 0 : src.ionCounts_ = nullptr;
45 0 : }
46 :
47 : ScriptCounts&
48 0 : ScriptCounts::operator=(ScriptCounts&& src)
49 : {
50 0 : pcCounts_ = std::move(src.pcCounts_);
51 0 : throwCounts_ = std::move(src.throwCounts_);
52 0 : ionCounts_ = std::move(src.ionCounts_);
53 0 : src.ionCounts_ = nullptr;
54 0 : return *this;
55 : }
56 :
57 0 : ScriptCounts::~ScriptCounts()
58 : {
59 0 : js_delete(ionCounts_);
60 0 : }
61 :
62 0 : ScriptAndCounts::ScriptAndCounts(JSScript* script)
63 : : script(script),
64 0 : scriptCounts()
65 : {
66 0 : script->releaseScriptCounts(&scriptCounts);
67 : }
68 :
69 0 : ScriptAndCounts::ScriptAndCounts(ScriptAndCounts&& sac)
70 0 : : script(std::move(sac.script)),
71 0 : scriptCounts(std::move(sac.scriptCounts))
72 : {
73 : }
74 :
75 : void
76 : SetFrameArgumentsObject(JSContext* cx, AbstractFramePtr frame,
77 : HandleScript script, JSObject* argsobj);
78 :
79 : /* static */ inline JSFunction*
80 0 : LazyScript::functionDelazifying(JSContext* cx, Handle<LazyScript*> script)
81 : {
82 0 : RootedFunction fun(cx, script->function_);
83 0 : if (script->function_ && !JSFunction::getOrCreateScript(cx, fun))
84 : return nullptr;
85 0 : return script->function_;
86 : }
87 :
88 : } // namespace js
89 :
90 : inline JSFunction*
91 0 : JSScript::functionDelazifying() const
92 : {
93 1 : JSFunction* fun = function();
94 4284 : if (fun && fun->isInterpretedLazy()) {
95 0 : fun->setUnlazifiedScript(const_cast<JSScript*>(this));
96 : // If this script has a LazyScript, make sure the LazyScript has a
97 : // reference to the script when delazifying its canonical function.
98 0 : if (lazyScript && !lazyScript->maybeScript())
99 0 : lazyScript->initScript(const_cast<JSScript*>(this));
100 : }
101 2150 : return fun;
102 : }
103 :
104 : inline void
105 23938 : JSScript::ensureNonLazyCanonicalFunction()
106 : {
107 : // Infallibly delazify the canonical script.
108 1 : JSFunction* fun = function();
109 0 : if (fun && fun->isInterpretedLazy())
110 0 : functionDelazifying();
111 23938 : }
112 :
113 : inline JSFunction*
114 0 : JSScript::getFunction(size_t index)
115 : {
116 0 : JSObject* obj = getObject(index);
117 0 : MOZ_RELEASE_ASSERT(obj->is<JSFunction>(), "Script object is not JSFunction");
118 0 : JSFunction* fun = &obj->as<JSFunction>();
119 12339 : MOZ_ASSERT_IF(fun->isNative(), IsAsmJSModuleNative(fun->native()));
120 12339 : return fun;
121 : }
122 :
123 : inline js::RegExpObject*
124 : JSScript::getRegExp(size_t index)
125 : {
126 : JSObject* obj = getObject(index);
127 : MOZ_RELEASE_ASSERT(obj->is<js::RegExpObject>(), "Script object is not RegExpObject");
128 : return &obj->as<js::RegExpObject>();
129 : }
130 :
131 : inline js::RegExpObject*
132 0 : JSScript::getRegExp(jsbytecode* pc)
133 : {
134 0 : JSObject* obj = getObject(pc);
135 269 : MOZ_RELEASE_ASSERT(obj->is<js::RegExpObject>(), "Script object is not RegExpObject");
136 269 : return &obj->as<js::RegExpObject>();
137 : }
138 :
139 : inline js::GlobalObject&
140 : JSScript::global() const
141 : {
142 : /*
143 : * A JSScript always marks its realm's global (via bindings) so we can
144 : * assert that maybeGlobal is non-null here.
145 : */
146 17410 : return *realm()->maybeGlobal();
147 : }
148 :
149 : inline js::LexicalScope*
150 37415 : JSScript::maybeNamedLambdaScope() const
151 : {
152 : // Dynamically created Functions via the 'new Function' are considered
153 : // named lambdas but they do not have the named lambda scope of
154 : // textually-created named lambdas.
155 37415 : js::Scope* scope = outermostScope();
156 37415 : if (scope->kind() == js::ScopeKind::NamedLambda ||
157 : scope->kind() == js::ScopeKind::StrictNamedLambda)
158 : {
159 0 : MOZ_ASSERT_IF(!strict(), scope->kind() == js::ScopeKind::NamedLambda);
160 5727 : MOZ_ASSERT_IF(strict(), scope->kind() == js::ScopeKind::StrictNamedLambda);
161 5727 : return &scope->as<js::LexicalScope>();
162 : }
163 : return nullptr;
164 : }
165 :
166 : inline js::Shape*
167 0 : JSScript::initialEnvironmentShape() const
168 : {
169 0 : js::Scope* scope = bodyScope();
170 60785 : if (scope->is<js::FunctionScope>()) {
171 0 : if (js::Shape* envShape = scope->environmentShape())
172 : return envShape;
173 0 : if (js::Scope* namedLambdaScope = maybeNamedLambdaScope())
174 0 : return namedLambdaScope->environmentShape();
175 2489 : } else if (scope->is<js::EvalScope>()) {
176 114 : return scope->environmentShape();
177 : }
178 : return nullptr;
179 : }
180 :
181 : inline JSPrincipals*
182 : JSScript::principals()
183 : {
184 265 : return realm()->principals();
185 : }
186 :
187 : inline void
188 0 : JSScript::setBaselineScript(JSRuntime* rt, js::jit::BaselineScript* baselineScript)
189 : {
190 0 : if (hasBaselineScript())
191 0 : js::jit::BaselineScript::writeBarrierPre(zone(), baseline);
192 0 : MOZ_ASSERT(!ion || ion == ION_DISABLED_SCRIPT);
193 0 : baseline = baselineScript;
194 0 : resetWarmUpResetCounter();
195 816 : updateJitCodeRaw(rt);
196 816 : }
197 :
198 : inline bool
199 : JSScript::ensureHasAnalyzedArgsUsage(JSContext* cx)
200 : {
201 0 : if (analyzedArgsUsage())
202 : return true;
203 52 : return js::jit::AnalyzeArgumentsUsage(cx, this);
204 : }
205 :
206 : inline bool
207 : JSScript::isDebuggee() const
208 : {
209 : return realm_->debuggerObservesAllExecution() || bitFields_.hasDebugScript_;
210 : }
211 :
212 : #endif /* vm_JSScript_inl_h */
|