mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
70c40a1658
Differential Revision: https://phabricator.services.mozilla.com/D184896
173 lines
5.8 KiB
C++
173 lines
5.8 KiB
C++
/* -*- 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/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 ScriptLoadContext;
|
|
|
|
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 off-thread operation and move it
|
|
// to the main thread.
|
|
[[nodiscard]] nsresult JoinOffThread(ScriptLoadContext* aContext);
|
|
|
|
// 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_ */
|