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 DOM_BASE_JSEXECUTIONCONTEXT_H_
8 #define DOM_BASE_JSEXECUTIONCONTEXT_H_
10 #include "js/GCVector.h"
11 #include "js/OffThreadScriptCompilation.h"
12 #include "js/TypeDecls.h"
14 #include "js/experimental/JSStencil.h"
16 #include "mozilla/Assertions.h"
17 #include "mozilla/Attributes.h"
18 #include "mozilla/ProfilerLabels.h"
19 #include "mozilla/Vector.h"
20 #include "nsStringFwd.h"
23 class nsIScriptContext
;
24 class nsIScriptElement
;
25 class nsIScriptGlobalObject
;
26 class nsXBLPrototypeBinding
;
33 class MOZ_STACK_CLASS JSExecutionContext final
{
34 // Register stack annotations for the Gecko profiler.
35 mozilla::AutoProfilerLabel mAutoProfilerLabel
;
39 // Handles switching to our global's realm.
42 // Set to a valid handle if a return value is expected.
43 JS::Rooted
<JS::Value
> mRetValue
;
45 // The compiled script.
46 JS::Rooted
<JSScript
*> mScript
;
48 // The compilation options applied throughout
49 JS::CompileOptions
& mCompileOptions
;
51 // Debug Metadata: Values managed for the benefit of the debugger when
54 // For more details see CompilationAndEvaluation.h, and the comments on
55 // UpdateDebugMetadata
56 JS::Rooted
<JS::Value
> mDebuggerPrivateValue
;
57 JS::Rooted
<JSScript
*> mDebuggerIntroductionScript
;
59 // returned value forwarded when we have to interupt the execution eagerly
63 // Used to skip upcoming phases in case of a failure. In such case the
64 // result is carried by mRv.
67 // Should the result be serialized before being returned.
70 // Encode the bytecode before it is being executed.
74 // Should we set the return value.
75 bool mWantsReturnValue
;
81 // Compile a script contained in a SourceText.
82 template <typename Unit
>
83 nsresult
InternalCompile(JS::SourceText
<Unit
>& aSrcBuf
);
85 // Instantiate (on main-thread) a JS::Stencil generated by off-thread or
86 // main-thread parsing or decoding.
87 nsresult
InstantiateStencil(RefPtr
<JS::Stencil
>&& aStencil
,
88 JS::InstantiationStorage
* aStorage
= nullptr);
91 // Enter compartment in which the code would be executed. The JSContext
92 // must come from an AutoEntryScript.
94 // The JS engine can associate metadata for the debugger with scripts at
95 // compile time. The optional last arguments here cover that metadata.
97 JSContext
* aCx
, JS::Handle
<JSObject
*> aGlobal
,
98 JS::CompileOptions
& aCompileOptions
,
99 JS::Handle
<JS::Value
> aDebuggerPrivateValue
= JS::UndefinedHandleValue
,
100 JS::Handle
<JSScript
*> aDebuggerIntroductionScript
= nullptr);
102 JSExecutionContext(const JSExecutionContext
&) = delete;
103 JSExecutionContext(JSExecutionContext
&&) = delete;
105 ~JSExecutionContext() {
106 // This flag is reset when the returned value is extracted.
107 MOZ_ASSERT_IF(!mSkip
, !mWantsReturnValue
);
109 // If encoding was started we expect the script to have been
110 // used when ending the encoding.
111 MOZ_ASSERT_IF(mEncodeBytecode
&& mScript
&& mRv
== NS_OK
, mScriptUsed
);
114 // The returned value would be converted to a string if the
115 // |aCoerceToString| is flag set.
116 JSExecutionContext
& SetCoerceToString(bool aCoerceToString
) {
117 mCoerceToString
= aCoerceToString
;
121 // When set, this flag records and encodes the bytecode as soon as it is
122 // being compiled, and before it is being executed. The bytecode can then be
123 // requested by using |JS::FinishIncrementalEncoding| with the mutable
124 // handle |aScript| argument of |CompileAndExec| or |JoinAndExec|.
125 JSExecutionContext
& SetEncodeBytecode(bool aEncodeBytecode
) {
126 mEncodeBytecode
= aEncodeBytecode
;
130 // After getting a notification that an off-thread compile/decode finished,
131 // this function will take the result of the parser and move it to the main
133 [[nodiscard
]] nsresult
JoinOffThread(JS::OffThreadToken
** aOffThreadToken
);
135 // Compile a script contained in a SourceText.
136 nsresult
Compile(JS::SourceText
<char16_t
>& aSrcBuf
);
137 nsresult
Compile(JS::SourceText
<mozilla::Utf8Unit
>& aSrcBuf
);
139 // Compile a script contained in a string.
140 nsresult
Compile(const nsAString
& aScript
);
142 // Decode a script contained in a buffer.
143 nsresult
Decode(mozilla::Vector
<uint8_t>& aBytecodeBuf
,
144 size_t aBytecodeIndex
);
146 // Get a successfully compiled script.
147 JSScript
* GetScript();
149 // Get the compiled script if present, or nullptr.
150 JSScript
* MaybeGetScript();
152 // Execute the compiled script and ignore the return value.
153 [[nodiscard
]] nsresult
ExecScript();
155 // Execute the compiled script a get the return value.
157 // Copy the returned value into the mutable handle argument. In case of a
158 // evaluation failure either during the execution or the conversion of the
159 // result to a string, the nsresult is be set to the corresponding result
160 // code and the mutable handle argument remains unchanged.
162 // The value returned in the mutable handle argument is part of the
163 // compartment given as argument to the JSExecutionContext constructor. If the
164 // caller is in a different compartment, then the out-param value should be
165 // wrapped by calling |JS_WrapValue|.
166 [[nodiscard
]] nsresult
ExecScript(JS::MutableHandle
<JS::Value
> aRetValue
);
169 } // namespace mozilla
171 #endif /* DOM_BASE_JSEXECUTIONCONTEXT_H_ */