summaryrefslogtreecommitdiffstats
path: root/dom/base/JSExecutionContext.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dom/base/JSExecutionContext.h171
1 files changed, 171 insertions, 0 deletions
diff --git a/dom/base/JSExecutionContext.h b/dom/base/JSExecutionContext.h
new file mode 100644
index 0000000000..7bfb42301a
--- /dev/null
+++ b/dom/base/JSExecutionContext.h
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef DOM_BASE_JSEXECUTIONCONTEXT_H_
+#define DOM_BASE_JSEXECUTIONCONTEXT_H_
+
+#include "js/GCVector.h"
+#include "js/OffThreadScriptCompilation.h"
+#include "js/TypeDecls.h"
+#include "js/Value.h"
+#include "js/experimental/JSStencil.h"
+#include "jsapi.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/ProfilerLabels.h"
+#include "mozilla/Vector.h"
+#include "nsStringFwd.h"
+#include "nscore.h"
+
+class nsIScriptContext;
+class nsIScriptElement;
+class nsIScriptGlobalObject;
+class nsXBLPrototypeBinding;
+
+namespace mozilla {
+union Utf8Unit;
+
+namespace dom {
+
+class MOZ_STACK_CLASS JSExecutionContext final {
+ // Register stack annotations for the Gecko profiler.
+ mozilla::AutoProfilerLabel mAutoProfilerLabel;
+
+ JSContext* mCx;
+
+ // Handles switching to our global's realm.
+ JSAutoRealm mRealm;
+
+ // Set to a valid handle if a return value is expected.
+ JS::Rooted<JS::Value> mRetValue;
+
+ // The compiled script.
+ JS::Rooted<JSScript*> mScript;
+
+ // The compilation options applied throughout
+ JS::CompileOptions& mCompileOptions;
+
+ // Debug Metadata: Values managed for the benefit of the debugger when
+ // inspecting code.
+ //
+ // For more details see CompilationAndEvaluation.h, and the comments on
+ // UpdateDebugMetadata
+ JS::Rooted<JS::Value> mDebuggerPrivateValue;
+ JS::Rooted<JSScript*> mDebuggerIntroductionScript;
+
+ // returned value forwarded when we have to interupt the execution eagerly
+ // with mSkip.
+ nsresult mRv;
+
+ // Used to skip upcoming phases in case of a failure. In such case the
+ // result is carried by mRv.
+ bool mSkip;
+
+ // Should the result be serialized before being returned.
+ bool mCoerceToString;
+
+ // Encode the bytecode before it is being executed.
+ bool mEncodeBytecode;
+
+#ifdef DEBUG
+ // Should we set the return value.
+ bool mWantsReturnValue;
+
+ bool mScriptUsed;
+#endif
+
+ private:
+ // Compile a script contained in a SourceText.
+ template <typename Unit>
+ nsresult InternalCompile(JS::SourceText<Unit>& aSrcBuf);
+
+ // Instantiate (on main-thread) a JS::Stencil generated by off-thread or
+ // main-thread parsing or decoding.
+ nsresult InstantiateStencil(RefPtr<JS::Stencil>&& aStencil,
+ JS::InstantiationStorage* aStorage = nullptr);
+
+ public:
+ // Enter compartment in which the code would be executed. The JSContext
+ // must come from an AutoEntryScript.
+ //
+ // The JS engine can associate metadata for the debugger with scripts at
+ // compile time. The optional last arguments here cover that metadata.
+ JSExecutionContext(
+ JSContext* aCx, JS::Handle<JSObject*> aGlobal,
+ JS::CompileOptions& aCompileOptions,
+ JS::Handle<JS::Value> aDebuggerPrivateValue = JS::UndefinedHandleValue,
+ JS::Handle<JSScript*> aDebuggerIntroductionScript = nullptr);
+
+ JSExecutionContext(const JSExecutionContext&) = delete;
+ JSExecutionContext(JSExecutionContext&&) = delete;
+
+ ~JSExecutionContext() {
+ // This flag is reset when the returned value is extracted.
+ MOZ_ASSERT_IF(!mSkip, !mWantsReturnValue);
+
+ // If encoding was started we expect the script to have been
+ // used when ending the encoding.
+ MOZ_ASSERT_IF(mEncodeBytecode && mScript && mRv == NS_OK, mScriptUsed);
+ }
+
+ // The returned value would be converted to a string if the
+ // |aCoerceToString| is flag set.
+ JSExecutionContext& SetCoerceToString(bool aCoerceToString) {
+ mCoerceToString = aCoerceToString;
+ return *this;
+ }
+
+ // When set, this flag records and encodes the bytecode as soon as it is
+ // being compiled, and before it is being executed. The bytecode can then be
+ // requested by using |JS::FinishIncrementalEncoding| with the mutable
+ // handle |aScript| argument of |CompileAndExec| or |JoinAndExec|.
+ JSExecutionContext& SetEncodeBytecode(bool aEncodeBytecode) {
+ mEncodeBytecode = aEncodeBytecode;
+ return *this;
+ }
+
+ // After getting a notification that an off-thread compile/decode finished,
+ // this function will take the result of the parser and move it to the main
+ // thread.
+ [[nodiscard]] nsresult JoinOffThread(JS::OffThreadToken** aOffThreadToken);
+
+ // Compile a script contained in a SourceText.
+ nsresult Compile(JS::SourceText<char16_t>& aSrcBuf);
+ nsresult Compile(JS::SourceText<mozilla::Utf8Unit>& aSrcBuf);
+
+ // Compile a script contained in a string.
+ nsresult Compile(const nsAString& aScript);
+
+ // Decode a script contained in a buffer.
+ nsresult Decode(mozilla::Vector<uint8_t>& aBytecodeBuf,
+ size_t aBytecodeIndex);
+
+ // Get a successfully compiled script.
+ JSScript* GetScript();
+
+ // Get the compiled script if present, or nullptr.
+ JSScript* MaybeGetScript();
+
+ // Execute the compiled script and ignore the return value.
+ [[nodiscard]] nsresult ExecScript();
+
+ // Execute the compiled script a get the return value.
+ //
+ // Copy the returned value into the mutable handle argument. In case of a
+ // evaluation failure either during the execution or the conversion of the
+ // result to a string, the nsresult is be set to the corresponding result
+ // code and the mutable handle argument remains unchanged.
+ //
+ // The value returned in the mutable handle argument is part of the
+ // compartment given as argument to the JSExecutionContext constructor. If the
+ // caller is in a different compartment, then the out-param value should be
+ // wrapped by calling |JS_WrapValue|.
+ [[nodiscard]] nsresult ExecScript(JS::MutableHandle<JS::Value> aRetValue);
+};
+} // namespace dom
+} // namespace mozilla
+
+#endif /* DOM_BASE_JSEXECUTIONCONTEXT_H_ */