Bug 1812499 [wpt PR 38184] - Simplify handling of name-to-subdir mapping in canvas...
[gecko.git] / dom / base / JSExecutionContext.h
blob7bfb42301a13fb28bec34acea853cea07481afcc
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"
13 #include "js/Value.h"
14 #include "js/experimental/JSStencil.h"
15 #include "jsapi.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"
21 #include "nscore.h"
23 class nsIScriptContext;
24 class nsIScriptElement;
25 class nsIScriptGlobalObject;
26 class nsXBLPrototypeBinding;
28 namespace mozilla {
29 union Utf8Unit;
31 namespace dom {
33 class MOZ_STACK_CLASS JSExecutionContext final {
34 // Register stack annotations for the Gecko profiler.
35 mozilla::AutoProfilerLabel mAutoProfilerLabel;
37 JSContext* mCx;
39 // Handles switching to our global's realm.
40 JSAutoRealm mRealm;
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
52 // inspecting code.
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
60 // with mSkip.
61 nsresult mRv;
63 // Used to skip upcoming phases in case of a failure. In such case the
64 // result is carried by mRv.
65 bool mSkip;
67 // Should the result be serialized before being returned.
68 bool mCoerceToString;
70 // Encode the bytecode before it is being executed.
71 bool mEncodeBytecode;
73 #ifdef DEBUG
74 // Should we set the return value.
75 bool mWantsReturnValue;
77 bool mScriptUsed;
78 #endif
80 private:
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);
90 public:
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.
96 JSExecutionContext(
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;
118 return *this;
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;
127 return *this;
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
132 // thread.
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);
168 } // namespace dom
169 } // namespace mozilla
171 #endif /* DOM_BASE_JSEXECUTIONCONTEXT_H_ */