From 9436bfa1756024db9f1fe5d535c616da39d4ce40 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Tue, 25 Feb 2025 15:46:46 +0100 Subject: [PATCH 1/8] Issue #2692 - Part 1: Split out JS CompileOptions to its own header. --- js/public/CompileOptions.h | 401 +++++++++++++++++++++++++++++++++++++ js/src/jsapi.h | 375 +--------------------------------- js/src/jspubtd.h | 8 +- js/src/moz.build | 1 + 4 files changed, 407 insertions(+), 378 deletions(-) create mode 100644 js/public/CompileOptions.h diff --git a/js/public/CompileOptions.h b/js/public/CompileOptions.h new file mode 100644 index 0000000000..39472705fb --- /dev/null +++ b/js/public/CompileOptions.h @@ -0,0 +1,401 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +/* Options for JavaScript compilation. */ + +/* + * In the most common use case, a CompileOptions instance is allocated on the + * stack, and holds non-owning references to non-POD option values: strings; + * principals; objects; and so on. The code declaring the instance guarantees + * that such option values will outlive the CompileOptions itself: objects are + * otherwise rooted; principals have had their reference counts bumped; strings + * will not be freed until the CompileOptions goes out of scope. In this + * situation, CompileOptions only refers to things others own, so it can be + * lightweight. + * + * In some cases, however, we need to hold compilation options with a + * non-stack-like lifetime. For example, JS::CompileOffThread needs to save + * compilation options where a worker thread can find them, and then return + * immediately. The worker thread will come along at some later point, and use + * the options. + * + * The compiler itself just needs to be able to access a collection of options; + * it doesn't care who owns them, or what's keeping them alive. It does its own + * addrefs/copies/tracing/etc. + * + * Furthermore, in some cases compile options are propagated from one entity to + * another (e.g. from a script to a function defined in that script). This + * involves copying over some, but not all, of the options. + * + * So, we have a class hierarchy that reflects these four use cases: + * + * - TransitiveCompileOptions is the common base class, representing options + * that should get propagated from a script to functions defined in that + * script. This is never instantiated directly. + * + * - ReadOnlyCompileOptions is the only subclass of TransitiveCompileOptions, + * representing a full set of compile options. It can be used by code that + * simply needs to access options set elsewhere, like the compiler. This, + * again, is never instantiated directly. + * + * - The usual CompileOptions class must be stack-allocated, and holds + * non-owning references to the filename, element, and so on. It's derived + * from ReadOnlyCompileOptions, so the compiler can use it. + * + * - OwningCompileOptions roots / copies / reference counts of all its values, + * and unroots / frees / releases them when it is destructed. It too is + * derived from ReadOnlyCompileOptions, so the compiler accepts it. + */ + +#ifndef js_CompileOptions_h +#define js_CompileOptions_h + +#include "mozilla/MemoryReporting.h" // mozilla::MallocSizeOf + +#include // size_t +#include // uint8_t + +#include "jstypes.h" // JS_PUBLIC_API + +#include "js/RootingAPI.h" // JS::PersistentRooted, JS::Rooted + +struct JSContext; +class JSObject; +class JSScript; +class JSString; + +namespace JS { + +enum class AsmJSOption : uint8_t { Enabled, Disabled, DisabledByDebugger }; + +/** + * The common base class for the CompileOptions hierarchy. + * + * Use this in code that needs to propagate compile options from one compilation + * unit to another. + */ +class JS_FRIEND_API(TransitiveCompileOptions) +{ + protected: + // The Web Platform allows scripts to be loaded from arbitrary cross-origin + // sources. This allows an attack by which a malicious website loads a + // sensitive file (say, a bank statement) cross-origin (using the user's + // cookies), and sniffs the generated syntax errors (via a window.onerror + // handler) for juicy morsels of its contents. + // + // To counter this attack, HTML5 specifies that script errors should be + // sanitized ("muted") when the script is not same-origin with the global + // for which it is loaded. Callers should set this flag for cross-origin + // scripts, and it will be propagated appropriately to child scripts and + // passed back in JSErrorReports. + bool mutedErrors_; + const char* filename_; + const char* introducerFilename_; + const char16_t* sourceMapURL_; + + // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure + // is unusable until that's set to something more specific; the derived + // classes' constructors take care of that, in ways appropriate to their + // purpose. + TransitiveCompileOptions() + : mutedErrors_(false), + filename_(nullptr), + introducerFilename_(nullptr), + sourceMapURL_(nullptr), + version(JSVERSION_UNKNOWN), + versionSet(false), + utf8(false), + selfHostingMode(false), + canLazilyParse(true), + strictOption(false), + extraWarningsOption(false), + werrorOption(false), + asmJSOption(AsmJSOption::Disabled), + throwOnAsmJSValidationFailureOption(false), + forceAsync(false), + sourceIsLazy(false), + introductionType(nullptr), + introductionLineno(0), + introductionOffset(0), + hasIntroductionInfo(false) + { } + + // Set all POD options (those not requiring reference counts, copies, + // rooting, or other hand-holding) to their values in |rhs|. + void copyPODTransitiveOptions(const TransitiveCompileOptions& rhs); + + public: + // Read-only accessors for non-POD options. The proper way to set these + // depends on the derived type. + bool mutedErrors() const { return mutedErrors_; } + const char* filename() const { return filename_; } + const char* introducerFilename() const { return introducerFilename_; } + const char16_t* sourceMapURL() const { return sourceMapURL_; } + virtual JSObject* element() const = 0; + virtual JSString* elementAttributeName() const = 0; + virtual JSScript* introductionScript() const = 0; + + // POD options. + JSVersion version; + bool versionSet; + bool utf8; + bool selfHostingMode; + bool canLazilyParse; + bool strictOption; + bool extraWarningsOption; + bool werrorOption; + AsmJSOption asmJSOption; + bool throwOnAsmJSValidationFailureOption; + bool forceAsync; + bool sourceIsLazy; + + // |introductionType| is a statically allocated C string: + // one of "eval", "Function", or "GeneratorFunction". + const char* introductionType; + unsigned introductionLineno; + uint32_t introductionOffset; + bool hasIntroductionInfo; + + private: + void operator=(const TransitiveCompileOptions&) = delete; +}; + +/** + * The class representing a full set of compile options. + * + * Use this in code that only needs to access compilation options created + * elsewhere, like the compiler. Don't instantiate this class (the constructor + * is protected anyway); instead, create instances only of the derived classes: + * CompileOptions and OwningCompileOptions. + */ +class JS_FRIEND_API(ReadOnlyCompileOptions) : public TransitiveCompileOptions +{ + friend class CompileOptions; + + protected: + ReadOnlyCompileOptions() + : TransitiveCompileOptions(), + lineno(1), + column(0), + isRunOnce(false), + noScriptRval(false) + { } + + // Set all POD options (those not requiring reference counts, copies, + // rooting, or other hand-holding) to their values in |rhs|. + void copyPODOptions(const ReadOnlyCompileOptions& rhs); + + public: + // Read-only accessors for non-POD options. The proper way to set these + // depends on the derived type. + bool mutedErrors() const { return mutedErrors_; } + const char* filename() const { return filename_; } + const char* introducerFilename() const { return introducerFilename_; } + const char16_t* sourceMapURL() const { return sourceMapURL_; } + virtual JSObject* element() const = 0; + virtual JSString* elementAttributeName() const = 0; + virtual JSScript* introductionScript() const = 0; + + // POD options. + unsigned lineno; + unsigned column; + // isRunOnce only applies to non-function scripts. + bool isRunOnce; + bool noScriptRval; + + private: + void operator=(const ReadOnlyCompileOptions&) = delete; +}; + +/** + * Compilation options, with dynamic lifetime. An instance of this type + * makes a copy of / holds / roots all dynamically allocated resources + * (principals; elements; strings) that it refers to. Its destructor frees + * / drops / unroots them. This is heavier than CompileOptions, below, but + * unlike CompileOptions, it can outlive any given stack frame. + * + * Note that this *roots* any JS values it refers to - they're live + * unconditionally. Thus, instances of this type can't be owned, directly + * or indirectly, by a JavaScript object: if any value that this roots ever + * comes to refer to the object that owns this, then the whole cycle, and + * anything else it entrains, will never be freed. + */ +class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions +{ + PersistentRootedObject elementRoot; + PersistentRootedString elementAttributeNameRoot; + PersistentRootedScript introductionScriptRoot; + + public: + // A minimal constructor, for use with OwningCompileOptions::copy. This + // leaves |this.version| set to JSVERSION_UNKNOWN; the instance + // shouldn't be used until we've set that to something real (as |copy| + // will). + explicit OwningCompileOptions(JSContext* cx); + ~OwningCompileOptions(); + + JSObject* element() const override { return elementRoot; } + JSString* elementAttributeName() const override { return elementAttributeNameRoot; } + JSScript* introductionScript() const override { return introductionScriptRoot; } + + // Set this to a copy of |rhs|. Return false on OOM. + bool copy(JSContext* cx, const ReadOnlyCompileOptions& rhs); + + /* These setters make copies of their string arguments, and are fallible. */ + bool setFile(JSContext* cx, const char* f); + bool setFileAndLine(JSContext* cx, const char* f, unsigned l); + bool setSourceMapURL(JSContext* cx, const char16_t* s); + bool setIntroducerFilename(JSContext* cx, const char* s); + + /* These setters are infallible, and can be chained. */ + OwningCompileOptions& setLine(unsigned l) { lineno = l; return *this; } + OwningCompileOptions& setElement(JSObject* e) { + elementRoot = e; + return *this; + } + OwningCompileOptions& setElementAttributeName(JSString* p) { + elementAttributeNameRoot = p; + return *this; + } + OwningCompileOptions& setIntroductionScript(JSScript* s) { + introductionScriptRoot = s; + return *this; + } + OwningCompileOptions& setMutedErrors(bool mute) { + mutedErrors_ = mute; + return *this; + } + OwningCompileOptions& setVersion(JSVersion v) { + version = v; + versionSet = true; + return *this; + } + OwningCompileOptions& setUTF8(bool u) { utf8 = u; return *this; } + OwningCompileOptions& setColumn(unsigned c) { column = c; return *this; } + OwningCompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; } + OwningCompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; } + OwningCompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; } + OwningCompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; } + OwningCompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; } + OwningCompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; } + bool setIntroductionInfo(JSContext* cx, const char* introducerFn, const char* intro, + unsigned line, JSScript* script, uint32_t offset) + { + if (!setIntroducerFilename(cx, introducerFn)) + return false; + introductionType = intro; + introductionLineno = line; + introductionScriptRoot = script; + introductionOffset = offset; + hasIntroductionInfo = true; + return true; + } + + private: + void operator=(const CompileOptions& rhs) = delete; +}; + +/** + * Compilation options stored on the stack. An instance of this type + * simply holds references to dynamically allocated resources (element; + * filename; source map URL) that are owned by something else. If you + * create an instance of this type, it's up to you to guarantee that + * everything you store in it will outlive it. + */ +class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) final : public ReadOnlyCompileOptions +{ + RootedObject elementRoot; + RootedString elementAttributeNameRoot; + RootedScript introductionScriptRoot; + + public: + explicit CompileOptions(JSContext* cx, JSVersion version = JSVERSION_UNKNOWN); + CompileOptions(js::ContextFriendFields* cx, const ReadOnlyCompileOptions& rhs) + : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx), + introductionScriptRoot(cx) + { + copyPODOptions(rhs); + + filename_ = rhs.filename(); + introducerFilename_ = rhs.introducerFilename(); + sourceMapURL_ = rhs.sourceMapURL(); + elementRoot = rhs.element(); + elementAttributeNameRoot = rhs.elementAttributeName(); + introductionScriptRoot = rhs.introductionScript(); + } + + CompileOptions(js::ContextFriendFields* cx, const TransitiveCompileOptions& rhs) + : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx), + introductionScriptRoot(cx) + { + copyPODTransitiveOptions(rhs); + + filename_ = rhs.filename(); + introducerFilename_ = rhs.introducerFilename(); + sourceMapURL_ = rhs.sourceMapURL(); + elementRoot = rhs.element(); + elementAttributeNameRoot = rhs.elementAttributeName(); + introductionScriptRoot = rhs.introductionScript(); + } + + JSObject* element() const override { return elementRoot; } + JSString* elementAttributeName() const override { return elementAttributeNameRoot; } + JSScript* introductionScript() const override { return introductionScriptRoot; } + + CompileOptions& setFile(const char* f) { filename_ = f; return *this; } + CompileOptions& setLine(unsigned l) { lineno = l; return *this; } + CompileOptions& setFileAndLine(const char* f, unsigned l) { + filename_ = f; lineno = l; return *this; + } + CompileOptions& setSourceMapURL(const char16_t* s) { sourceMapURL_ = s; return *this; } + CompileOptions& setElement(JSObject* e) { elementRoot = e; return *this; } + CompileOptions& setElementAttributeName(JSString* p) { + elementAttributeNameRoot = p; + return *this; + } + CompileOptions& setIntroductionScript(JSScript* s) { + introductionScriptRoot = s; + return *this; + } + CompileOptions& setMutedErrors(bool mute) { + mutedErrors_ = mute; + return *this; + } + CompileOptions& setVersion(JSVersion v) { + version = v; + versionSet = true; + return *this; + } + CompileOptions& setUTF8(bool u) { utf8 = u; return *this; } + CompileOptions& setColumn(unsigned c) { column = c; return *this; } + CompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; } + CompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; } + CompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; } + CompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; } + CompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; } + CompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; } + CompileOptions& setIntroductionInfo(const char* introducerFn, const char* intro, + unsigned line, JSScript* script, uint32_t offset) + { + introducerFilename_ = introducerFn; + introductionType = intro; + introductionLineno = line; + introductionScriptRoot = script; + introductionOffset = offset; + hasIntroductionInfo = true; + return *this; + } + CompileOptions& maybeMakeStrictMode(bool strict) { + strictOption = strictOption || strict; + return *this; + } + + private: + void operator=(const CompileOptions& rhs) = delete; +}; + +} // namespace JS + +#endif /* js_CompileOptions_h */ \ No newline at end of file diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 1f4f52c3bb..37c49e95ee 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -29,6 +29,7 @@ #include "js/CallArgs.h" #include "js/CharacterEncoding.h" #include "js/Class.h" +#include "js/CompileOptions.h" #include "js/GCVector.h" #include "js/HashTable.h" #include "js/Id.h" @@ -3728,380 +3729,6 @@ JS_GetFunctionScript(JSContext* cx, JS::HandleFunction fun); namespace JS { -/* Options for JavaScript compilation. */ - -/* - * In the most common use case, a CompileOptions instance is allocated on the - * stack, and holds non-owning references to non-POD option values: strings; - * principals; objects; and so on. The code declaring the instance guarantees - * that such option values will outlive the CompileOptions itself: objects are - * otherwise rooted; principals have had their reference counts bumped; strings - * will not be freed until the CompileOptions goes out of scope. In this - * situation, CompileOptions only refers to things others own, so it can be - * lightweight. - * - * In some cases, however, we need to hold compilation options with a - * non-stack-like lifetime. For example, JS::CompileOffThread needs to save - * compilation options where a worker thread can find them, and then return - * immediately. The worker thread will come along at some later point, and use - * the options. - * - * The compiler itself just needs to be able to access a collection of options; - * it doesn't care who owns them, or what's keeping them alive. It does its own - * addrefs/copies/tracing/etc. - * - * Furthermore, in some cases compile options are propagated from one entity to - * another (e.g. from a script to a function defined in that script). This - * involves copying over some, but not all, of the options. - * - * So, we have a class hierarchy that reflects these four use cases: - * - * - TransitiveCompileOptions is the common base class, representing options - * that should get propagated from a script to functions defined in that - * script. This is never instantiated directly. - * - * - ReadOnlyCompileOptions is the only subclass of TransitiveCompileOptions, - * representing a full set of compile options. It can be used by code that - * simply needs to access options set elsewhere, like the compiler. This, - * again, is never instantiated directly. - * - * - The usual CompileOptions class must be stack-allocated, and holds - * non-owning references to the filename, element, and so on. It's derived - * from ReadOnlyCompileOptions, so the compiler can use it. - * - * - OwningCompileOptions roots / copies / reference counts of all its values, - * and unroots / frees / releases them when it is destructed. It too is - * derived from ReadOnlyCompileOptions, so the compiler accepts it. - */ - -enum class AsmJSOption : uint8_t { Enabled, Disabled, DisabledByDebugger }; - -/** - * The common base class for the CompileOptions hierarchy. - * - * Use this in code that needs to propagate compile options from one compilation - * unit to another. - */ -class JS_FRIEND_API(TransitiveCompileOptions) -{ - protected: - // The Web Platform allows scripts to be loaded from arbitrary cross-origin - // sources. This allows an attack by which a malicious website loads a - // sensitive file (say, a bank statement) cross-origin (using the user's - // cookies), and sniffs the generated syntax errors (via a window.onerror - // handler) for juicy morsels of its contents. - // - // To counter this attack, HTML5 specifies that script errors should be - // sanitized ("muted") when the script is not same-origin with the global - // for which it is loaded. Callers should set this flag for cross-origin - // scripts, and it will be propagated appropriately to child scripts and - // passed back in JSErrorReports. - bool mutedErrors_; - const char* filename_; - const char* introducerFilename_; - const char16_t* sourceMapURL_; - - // This constructor leaves 'version' set to JSVERSION_UNKNOWN. The structure - // is unusable until that's set to something more specific; the derived - // classes' constructors take care of that, in ways appropriate to their - // purpose. - TransitiveCompileOptions() - : mutedErrors_(false), - filename_(nullptr), - introducerFilename_(nullptr), - sourceMapURL_(nullptr), - version(JSVERSION_UNKNOWN), - versionSet(false), - utf8(false), - selfHostingMode(false), - canLazilyParse(true), - strictOption(false), - extraWarningsOption(false), - werrorOption(false), - asmJSOption(AsmJSOption::Disabled), - throwOnAsmJSValidationFailureOption(false), - forceAsync(false), - sourceIsLazy(false), - introductionType(nullptr), - introductionLineno(0), - introductionOffset(0), - hasIntroductionInfo(false) - { } - - // Set all POD options (those not requiring reference counts, copies, - // rooting, or other hand-holding) to their values in |rhs|. - void copyPODTransitiveOptions(const TransitiveCompileOptions& rhs); - - public: - // Read-only accessors for non-POD options. The proper way to set these - // depends on the derived type. - bool mutedErrors() const { return mutedErrors_; } - const char* filename() const { return filename_; } - const char* introducerFilename() const { return introducerFilename_; } - const char16_t* sourceMapURL() const { return sourceMapURL_; } - virtual JSObject* element() const = 0; - virtual JSString* elementAttributeName() const = 0; - virtual JSScript* introductionScript() const = 0; - - // POD options. - JSVersion version; - bool versionSet; - bool utf8; - bool selfHostingMode; - bool canLazilyParse; - bool strictOption; - bool extraWarningsOption; - bool werrorOption; - AsmJSOption asmJSOption; - bool throwOnAsmJSValidationFailureOption; - bool forceAsync; - bool sourceIsLazy; - - // |introductionType| is a statically allocated C string: - // one of "eval", "Function", or "GeneratorFunction". - const char* introductionType; - unsigned introductionLineno; - uint32_t introductionOffset; - bool hasIntroductionInfo; - - private: - void operator=(const TransitiveCompileOptions&) = delete; -}; - -/** - * The class representing a full set of compile options. - * - * Use this in code that only needs to access compilation options created - * elsewhere, like the compiler. Don't instantiate this class (the constructor - * is protected anyway); instead, create instances only of the derived classes: - * CompileOptions and OwningCompileOptions. - */ -class JS_FRIEND_API(ReadOnlyCompileOptions) : public TransitiveCompileOptions -{ - friend class CompileOptions; - - protected: - ReadOnlyCompileOptions() - : TransitiveCompileOptions(), - lineno(1), - column(0), - isRunOnce(false), - noScriptRval(false) - { } - - // Set all POD options (those not requiring reference counts, copies, - // rooting, or other hand-holding) to their values in |rhs|. - void copyPODOptions(const ReadOnlyCompileOptions& rhs); - - public: - // Read-only accessors for non-POD options. The proper way to set these - // depends on the derived type. - bool mutedErrors() const { return mutedErrors_; } - const char* filename() const { return filename_; } - const char* introducerFilename() const { return introducerFilename_; } - const char16_t* sourceMapURL() const { return sourceMapURL_; } - virtual JSObject* element() const = 0; - virtual JSString* elementAttributeName() const = 0; - virtual JSScript* introductionScript() const = 0; - - // POD options. - unsigned lineno; - unsigned column; - // isRunOnce only applies to non-function scripts. - bool isRunOnce; - bool noScriptRval; - - private: - void operator=(const ReadOnlyCompileOptions&) = delete; -}; - -/** - * Compilation options, with dynamic lifetime. An instance of this type - * makes a copy of / holds / roots all dynamically allocated resources - * (principals; elements; strings) that it refers to. Its destructor frees - * / drops / unroots them. This is heavier than CompileOptions, below, but - * unlike CompileOptions, it can outlive any given stack frame. - * - * Note that this *roots* any JS values it refers to - they're live - * unconditionally. Thus, instances of this type can't be owned, directly - * or indirectly, by a JavaScript object: if any value that this roots ever - * comes to refer to the object that owns this, then the whole cycle, and - * anything else it entrains, will never be freed. - */ -class JS_FRIEND_API(OwningCompileOptions) : public ReadOnlyCompileOptions -{ - PersistentRootedObject elementRoot; - PersistentRootedString elementAttributeNameRoot; - PersistentRootedScript introductionScriptRoot; - - public: - // A minimal constructor, for use with OwningCompileOptions::copy. This - // leaves |this.version| set to JSVERSION_UNKNOWN; the instance - // shouldn't be used until we've set that to something real (as |copy| - // will). - explicit OwningCompileOptions(JSContext* cx); - ~OwningCompileOptions(); - - JSObject* element() const override { return elementRoot; } - JSString* elementAttributeName() const override { return elementAttributeNameRoot; } - JSScript* introductionScript() const override { return introductionScriptRoot; } - - // Set this to a copy of |rhs|. Return false on OOM. - bool copy(JSContext* cx, const ReadOnlyCompileOptions& rhs); - - /* These setters make copies of their string arguments, and are fallible. */ - bool setFile(JSContext* cx, const char* f); - bool setFileAndLine(JSContext* cx, const char* f, unsigned l); - bool setSourceMapURL(JSContext* cx, const char16_t* s); - bool setIntroducerFilename(JSContext* cx, const char* s); - - /* These setters are infallible, and can be chained. */ - OwningCompileOptions& setLine(unsigned l) { lineno = l; return *this; } - OwningCompileOptions& setElement(JSObject* e) { - elementRoot = e; - return *this; - } - OwningCompileOptions& setElementAttributeName(JSString* p) { - elementAttributeNameRoot = p; - return *this; - } - OwningCompileOptions& setIntroductionScript(JSScript* s) { - introductionScriptRoot = s; - return *this; - } - OwningCompileOptions& setMutedErrors(bool mute) { - mutedErrors_ = mute; - return *this; - } - OwningCompileOptions& setVersion(JSVersion v) { - version = v; - versionSet = true; - return *this; - } - OwningCompileOptions& setUTF8(bool u) { utf8 = u; return *this; } - OwningCompileOptions& setColumn(unsigned c) { column = c; return *this; } - OwningCompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; } - OwningCompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; } - OwningCompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; } - OwningCompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; } - OwningCompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; } - OwningCompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; } - bool setIntroductionInfo(JSContext* cx, const char* introducerFn, const char* intro, - unsigned line, JSScript* script, uint32_t offset) - { - if (!setIntroducerFilename(cx, introducerFn)) - return false; - introductionType = intro; - introductionLineno = line; - introductionScriptRoot = script; - introductionOffset = offset; - hasIntroductionInfo = true; - return true; - } - - private: - void operator=(const CompileOptions& rhs) = delete; -}; - -/** - * Compilation options stored on the stack. An instance of this type - * simply holds references to dynamically allocated resources (element; - * filename; source map URL) that are owned by something else. If you - * create an instance of this type, it's up to you to guarantee that - * everything you store in it will outlive it. - */ -class MOZ_STACK_CLASS JS_FRIEND_API(CompileOptions) final : public ReadOnlyCompileOptions -{ - RootedObject elementRoot; - RootedString elementAttributeNameRoot; - RootedScript introductionScriptRoot; - - public: - explicit CompileOptions(JSContext* cx, JSVersion version = JSVERSION_UNKNOWN); - CompileOptions(js::ContextFriendFields* cx, const ReadOnlyCompileOptions& rhs) - : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx), - introductionScriptRoot(cx) - { - copyPODOptions(rhs); - - filename_ = rhs.filename(); - introducerFilename_ = rhs.introducerFilename(); - sourceMapURL_ = rhs.sourceMapURL(); - elementRoot = rhs.element(); - elementAttributeNameRoot = rhs.elementAttributeName(); - introductionScriptRoot = rhs.introductionScript(); - } - - CompileOptions(js::ContextFriendFields* cx, const TransitiveCompileOptions& rhs) - : ReadOnlyCompileOptions(), elementRoot(cx), elementAttributeNameRoot(cx), - introductionScriptRoot(cx) - { - copyPODTransitiveOptions(rhs); - - filename_ = rhs.filename(); - introducerFilename_ = rhs.introducerFilename(); - sourceMapURL_ = rhs.sourceMapURL(); - elementRoot = rhs.element(); - elementAttributeNameRoot = rhs.elementAttributeName(); - introductionScriptRoot = rhs.introductionScript(); - } - - JSObject* element() const override { return elementRoot; } - JSString* elementAttributeName() const override { return elementAttributeNameRoot; } - JSScript* introductionScript() const override { return introductionScriptRoot; } - - CompileOptions& setFile(const char* f) { filename_ = f; return *this; } - CompileOptions& setLine(unsigned l) { lineno = l; return *this; } - CompileOptions& setFileAndLine(const char* f, unsigned l) { - filename_ = f; lineno = l; return *this; - } - CompileOptions& setSourceMapURL(const char16_t* s) { sourceMapURL_ = s; return *this; } - CompileOptions& setElement(JSObject* e) { elementRoot = e; return *this; } - CompileOptions& setElementAttributeName(JSString* p) { - elementAttributeNameRoot = p; - return *this; - } - CompileOptions& setIntroductionScript(JSScript* s) { - introductionScriptRoot = s; - return *this; - } - CompileOptions& setMutedErrors(bool mute) { - mutedErrors_ = mute; - return *this; - } - CompileOptions& setVersion(JSVersion v) { - version = v; - versionSet = true; - return *this; - } - CompileOptions& setUTF8(bool u) { utf8 = u; return *this; } - CompileOptions& setColumn(unsigned c) { column = c; return *this; } - CompileOptions& setIsRunOnce(bool once) { isRunOnce = once; return *this; } - CompileOptions& setNoScriptRval(bool nsr) { noScriptRval = nsr; return *this; } - CompileOptions& setSelfHostingMode(bool shm) { selfHostingMode = shm; return *this; } - CompileOptions& setCanLazilyParse(bool clp) { canLazilyParse = clp; return *this; } - CompileOptions& setSourceIsLazy(bool l) { sourceIsLazy = l; return *this; } - CompileOptions& setIntroductionType(const char* t) { introductionType = t; return *this; } - CompileOptions& setIntroductionInfo(const char* introducerFn, const char* intro, - unsigned line, JSScript* script, uint32_t offset) - { - introducerFilename_ = introducerFn; - introductionType = intro; - introductionLineno = line; - introductionScriptRoot = script; - introductionOffset = offset; - hasIntroductionInfo = true; - return *this; - } - CompileOptions& maybeMakeStrictMode(bool strict) { - strictOption = strictOption || strict; - return *this; - } - - private: - void operator=(const CompileOptions& rhs) = delete; -}; - /** * |script| will always be set. On failure, it will be set to nullptr. */ diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index 4bc8b0649a..b2be737904 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -34,10 +34,10 @@ class CallArgs; template class Rooted; -class JS_FRIEND_API(CompileOptions); -class JS_FRIEND_API(ReadOnlyCompileOptions); -class JS_FRIEND_API(OwningCompileOptions); -class JS_FRIEND_API(TransitiveCompileOptions); +class JS_PUBLIC_API(CompileOptions); +class JS_PUBLIC_API(ReadOnlyCompileOptions); +class JS_PUBLIC_API(OwningCompileOptions); +class JS_PUBLIC_API(TransitiveCompileOptions); class JS_PUBLIC_API(CompartmentOptions); struct RootingContext; diff --git a/js/src/moz.build b/js/src/moz.build index d42cf59730..89a3f37e3c 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -67,6 +67,7 @@ EXPORTS.js += [ '../public/CallNonGenericMethod.h', '../public/CharacterEncoding.h', '../public/Class.h', + '../public/CompileOptions.h', '../public/Conversions.h', '../public/Date.h', '../public/Debug.h', From 565fb4b05a0d4c42c2fda297dc05acdae57a3637 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Tue, 25 Feb 2025 16:04:51 +0100 Subject: [PATCH 2/8] Issue #2692 - Part 2: Split out JS SourceBufferHolder to its own header. --- js/public/SourceBufferHolder.h | 116 +++++++++++++++++++++++++++++++++ js/src/jsapi.h | 97 +-------------------------- js/src/moz.build | 1 + 3 files changed, 118 insertions(+), 96 deletions(-) create mode 100644 js/public/SourceBufferHolder.h diff --git a/js/public/SourceBufferHolder.h b/js/public/SourceBufferHolder.h new file mode 100644 index 0000000000..67336ef113 --- /dev/null +++ b/js/public/SourceBufferHolder.h @@ -0,0 +1,116 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +/** + * Container class for passing in script source buffers to the JS engine. This + * not only groups the buffer and length values, it also provides a way to + * optionally pass ownership of the buffer to the JS engine without copying. + * Rules for use: + * + * 1) The data array must be allocated with js_malloc() or js_realloc() if + * ownership is being granted to the SourceBufferHolder. + * 2) If ownership is not given to the SourceBufferHolder, then the memory + * must be kept alive until the JS compilation is complete. + * 3) Any code calling SourceBufferHolder::take() must guarantee to keep the + * memory alive until JS compilation completes. Normally only the JS + * engine should be calling take(). + * + * Example use: + * + * size_t length = 512; + * char16_t* chars = static_cast(js_malloc(sizeof(char16_t) * length)); + * JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership); + * JS::Compile(cx, options, srcBuf); + */ + +#ifndef js_SourceBufferHolder_h +#define js_SourceBufferHolder_h + +#include "mozilla/Assertions.h" // MOZ_ASSERT + +#include // size_t + +#include "js/Utility.h" // JS::UniqueTwoByteChars + +namespace JS { + +class MOZ_STACK_CLASS SourceBufferHolder final +{ + public: + enum Ownership { + NoOwnership, + GiveOwnership + }; + + SourceBufferHolder(const char16_t* data, size_t dataLength, Ownership ownership) + : data_(data), + length_(dataLength), + ownsChars_(ownership == GiveOwnership) + { + // Ensure that null buffers properly return an unowned, empty, + // null-terminated string. + static const char16_t NullChar_ = 0; + if (!get()) { + data_ = &NullChar_; + length_ = 0; + ownsChars_ = false; + } + } + + SourceBufferHolder(SourceBufferHolder&& other) + : data_(other.data_), + length_(other.length_), + ownsChars_(other.ownsChars_) + { + other.data_ = nullptr; + other.length_ = 0; + other.ownsChars_ = false; + } + + ~SourceBufferHolder() { + if (ownsChars_) + js_free(const_cast(data_)); + } + + // Access the underlying source buffer without affecting ownership. + const char16_t* get() const { return data_; } + + // Length of the source buffer in char16_t code units (not bytes) + size_t length() const { return length_; } + + // Returns true if the SourceBufferHolder owns the buffer and will free + // it upon destruction. If true, it is legal to call take(). + bool ownsChars() const { return ownsChars_; } + + // Retrieve and take ownership of the underlying data buffer. The caller + // is now responsible for calling js_free() on the returned value, *but only + // after JS script compilation has completed*. + // + // After the buffer has been taken the SourceBufferHolder functions as if + // it had been constructed on an unowned buffer; get() and length() still + // work. In order for this to be safe the taken buffer must be kept alive + // until after JS script compilation completes as noted above. + // + // Note, it's the caller's responsibility to check ownsChars() before taking + // the buffer. Taking and then free'ing an unowned buffer will have dire + // consequences. + char16_t* take() { + MOZ_ASSERT(ownsChars_); + ownsChars_ = false; + return const_cast(data_); + } + + private: + SourceBufferHolder(SourceBufferHolder&) = delete; + SourceBufferHolder& operator=(SourceBufferHolder&) = delete; + + const char16_t* data_; + size_t length_; + bool ownsChars_; +}; + +} // namespace JS + +#endif /* js_SourceBufferHolder_h */ diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 37c49e95ee..496af32b41 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -36,6 +36,7 @@ #include "js/Principals.h" #include "js/Realm.h" #include "js/RootingAPI.h" +#include "js/SourceBufferHolder.h" #include "js/Stream.h" #include "js/TracingAPI.h" #include "js/UniquePtr.h" @@ -751,102 +752,6 @@ JS_StringHasBeenPinned(JSContext* cx, JSString* str); namespace JS { -/** - * Container class for passing in script source buffers to the JS engine. This - * not only groups the buffer and length values, it also provides a way to - * optionally pass ownership of the buffer to the JS engine without copying. - * Rules for use: - * - * 1) The data array must be allocated with js_malloc() or js_realloc() if - * ownership is being granted to the SourceBufferHolder. - * 2) If ownership is not given to the SourceBufferHolder, then the memory - * must be kept alive until the JS compilation is complete. - * 3) Any code calling SourceBufferHolder::take() must guarantee to keep the - * memory alive until JS compilation completes. Normally only the JS - * engine should be calling take(). - * - * Example use: - * - * size_t length = 512; - * char16_t* chars = static_cast(js_malloc(sizeof(char16_t) * length)); - * JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership); - * JS::Compile(cx, options, srcBuf); - */ -class MOZ_STACK_CLASS SourceBufferHolder final -{ - public: - enum Ownership { - NoOwnership, - GiveOwnership - }; - - SourceBufferHolder(const char16_t* data, size_t dataLength, Ownership ownership) - : data_(data), - length_(dataLength), - ownsChars_(ownership == GiveOwnership) - { - // Ensure that null buffers properly return an unowned, empty, - // null-terminated string. - static const char16_t NullChar_ = 0; - if (!get()) { - data_ = &NullChar_; - length_ = 0; - ownsChars_ = false; - } - } - - SourceBufferHolder(SourceBufferHolder&& other) - : data_(other.data_), - length_(other.length_), - ownsChars_(other.ownsChars_) - { - other.data_ = nullptr; - other.length_ = 0; - other.ownsChars_ = false; - } - - ~SourceBufferHolder() { - if (ownsChars_) - js_free(const_cast(data_)); - } - - // Access the underlying source buffer without affecting ownership. - const char16_t* get() const { return data_; } - - // Length of the source buffer in char16_t code units (not bytes) - size_t length() const { return length_; } - - // Returns true if the SourceBufferHolder owns the buffer and will free - // it upon destruction. If true, it is legal to call take(). - bool ownsChars() const { return ownsChars_; } - - // Retrieve and take ownership of the underlying data buffer. The caller - // is now responsible for calling js_free() on the returned value, *but only - // after JS script compilation has completed*. - // - // After the buffer has been taken the SourceBufferHolder functions as if - // it had been constructed on an unowned buffer; get() and length() still - // work. In order for this to be safe the taken buffer must be kept alive - // until after JS script compilation completes as noted above. - // - // Note, it's the caller's responsibility to check ownsChars() before taking - // the buffer. Taking and then free'ing an unowned buffer will have dire - // consequences. - char16_t* take() { - MOZ_ASSERT(ownsChars_); - ownsChars_ = false; - return const_cast(data_); - } - - private: - SourceBufferHolder(SourceBufferHolder&) = delete; - SourceBufferHolder& operator=(SourceBufferHolder&) = delete; - - const char16_t* data_; - size_t length_; - bool ownsChars_; -}; - } /* namespace JS */ /************************************************************************/ diff --git a/js/src/moz.build b/js/src/moz.build index 89a3f37e3c..3421fe9e99 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -93,6 +93,7 @@ EXPORTS.js += [ '../public/Result.h', '../public/RootingAPI.h', '../public/SliceBudget.h', + '../public/SourceBufferHolder.h', '../public/Stream.h', '../public/StructuredClone.h', '../public/SweepingAPI.h', From eca185aa790526938aabde258d314e5598cb0421 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Mon, 3 Mar 2025 21:59:04 +0100 Subject: [PATCH 3/8] Issue #2692 - Part 3: Split out JS compiled script transcoding to its own header. --- js/public/Transcoding.h | 85 +++++++++++++++++++++++++++++++++++++++++ js/src/jsapi.h | 58 +--------------------------- js/src/moz.build | 1 + js/src/vm/Xdr.h | 1 + 4 files changed, 88 insertions(+), 57 deletions(-) create mode 100644 js/public/Transcoding.h diff --git a/js/public/Transcoding.h b/js/public/Transcoding.h new file mode 100644 index 0000000000..f90d4663a3 --- /dev/null +++ b/js/public/Transcoding.h @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +/* + * Structures and functions for transcoding compiled scripts and functions to + * and from memory. + */ + +#ifndef js_Transcoding_h +#define js_Transcoding_h + +#include "mozilla/Range.h" // mozilla::Range +#include "mozilla/Vector.h" // mozilla::Vector + +#include // size_t +#include // uint8_t, uint32_t + +#include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle + +struct JSContext; +class JSFunction; +class JSObject; +class JSScript; + +namespace JS { + +// typedef mozilla::Vector TranscodeBuffer; +using TranscodeBuffer = mozilla::Vector; + +enum TranscodeResult +{ + // Successful encoding / decoding. + TranscodeResult_Ok = 0, + + // A warning message, is set to the message out-param. + TranscodeResult_Failure = 0x100, + TranscodeResult_Failure_BadBuildId = TranscodeResult_Failure | 0x1, + TranscodeResult_Failure_RunOnceNotSupported = TranscodeResult_Failure | 0x2, + TranscodeResult_Failure_AsmJSNotSupported = TranscodeResult_Failure | 0x3, + TranscodeResult_Failure_BadDecode = TranscodeResult_Failure | 0x4, + + TranscodeResult_Failure_WrongCompileOption = TranscodeResult_Failure | 0x5, + TranscodeResult_Failure_NotInterpretedFun = TranscodeResult_Failure | 0x6, + + // There is a pending exception on the context. + TranscodeResult_Throw = 0x200 +}; + +extern JS_PUBLIC_API(TranscodeResult) +EncodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::HandleScript script); + +extern JS_PUBLIC_API(TranscodeResult) +EncodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::HandleObject funobj); + +extern JS_PUBLIC_API(TranscodeResult) +DecodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleScript scriptp, + size_t cursorIndex = 0); + +extern JS_PUBLIC_API(TranscodeResult) +DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleFunction funp, + size_t cursorIndex = 0); + +// Register an encoder on the given script source, such that all functions can +// be encoded as they are parsed. This strategy is used to avoid blocking the +// main thread in a non-interruptible way. +// +// The |script| argument of |StartIncrementalEncoding| and +// |FinishIncrementalEncoding| should be the top-level script returned either as +// an out-param of any of the |Compile| functions, or the result of +// |FinishOffThreadScript|. +// +// The |buffer| argument of |FinishIncrementalEncoding| is used for appending +// the encoded bytecode into the buffer. If any of these functions failed, the +// content of |buffer| would be undefined. +extern JS_PUBLIC_API(bool) +StartIncrementalEncoding(JSContext* cx, JS::HandleScript script); + +extern JS_PUBLIC_API(bool) +FinishIncrementalEncoding(JSContext* cx, JS::HandleScript script, TranscodeBuffer& buffer); + +} /* namespace JS */ + +#endif /* js_Transcoding_h */ diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 496af32b41..9ae22ddacc 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -39,6 +39,7 @@ #include "js/SourceBufferHolder.h" #include "js/Stream.h" #include "js/TracingAPI.h" +#include "js/Transcoding.h" #include "js/UniquePtr.h" #include "js/Utility.h" #include "js/Value.h" @@ -5710,63 +5711,6 @@ class MOZ_RAII AutoHideScriptedCaller MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; -/* - * Encode/Decode interpreted scripts and functions to/from memory. - */ - -typedef mozilla::Vector TranscodeBuffer; - -enum TranscodeResult -{ - // Successful encoding / decoding. - TranscodeResult_Ok = 0, - - // A warning message, is set to the message out-param. - TranscodeResult_Failure = 0x100, - TranscodeResult_Failure_BadBuildId = TranscodeResult_Failure | 0x1, - TranscodeResult_Failure_RunOnceNotSupported = TranscodeResult_Failure | 0x2, - TranscodeResult_Failure_AsmJSNotSupported = TranscodeResult_Failure | 0x3, - TranscodeResult_Failure_BadDecode = TranscodeResult_Failure | 0x4, - - TranscodeResult_Failure_WrongCompileOption = TranscodeResult_Failure | 0x5, - TranscodeResult_Failure_NotInterpretedFun = TranscodeResult_Failure | 0x6, - - // There is a pending exception on the context. - TranscodeResult_Throw = 0x200 -}; - -extern JS_PUBLIC_API(TranscodeResult) -EncodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::HandleScript script); - -extern JS_PUBLIC_API(TranscodeResult) -EncodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::HandleObject funobj); - -extern JS_PUBLIC_API(TranscodeResult) -DecodeScript(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleScript scriptp, - size_t cursorIndex = 0); - -extern JS_PUBLIC_API(TranscodeResult) -DecodeInterpretedFunction(JSContext* cx, TranscodeBuffer& buffer, JS::MutableHandleFunction funp, - size_t cursorIndex = 0); - -// Register an encoder on the given script source, such that all functions can -// be encoded as they are parsed. This strategy is used to avoid blocking the -// main thread in a non-interruptible way. -// -// The |script| argument of |StartIncrementalEncoding| and -// |FinishIncrementalEncoding| should be the top-level script returned either as -// an out-param of any of the |Compile| functions, or the result of -// |FinishOffThreadScript|. -// -// The |buffer| argument of |FinishIncrementalEncoding| is used for appending -// the encoded bytecode into the buffer. If any of these functions failed, the -// content of |buffer| would be undefined. -extern JS_PUBLIC_API(bool) -StartIncrementalEncoding(JSContext* cx, JS::HandleScript script); - -extern JS_PUBLIC_API(bool) -FinishIncrementalEncoding(JSContext* cx, JS::HandleScript script, TranscodeBuffer& buffer); - } /* namespace JS */ namespace js { diff --git a/js/src/moz.build b/js/src/moz.build index 3421fe9e99..9670d64bb5 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -100,6 +100,7 @@ EXPORTS.js += [ '../public/TraceKind.h', '../public/TracingAPI.h', '../public/TrackedOptimizationInfo.h', + '../public/Transcoding.h', '../public/TypeDecls.h', '../public/UbiNode.h', '../public/UbiNodeBreadthFirst.h', diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h index 419b0dc86b..483a9aeabc 100644 --- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -9,6 +9,7 @@ #include "mozilla/EndianUtils.h" #include "mozilla/TypeTraits.h" +#include "js/Transcoding.h" #include "jsatom.h" #include "jsfriendapi.h" From 307621db50950a28904f917e02a9eb6006c4f120 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Tue, 4 Mar 2025 00:24:59 +0100 Subject: [PATCH 4/8] Issue #2692 - Part 4: Split out off-thread compilation API to its own header. --- js/public/OffThreadScriptCompilation.h | 93 ++++++++++++++++++++++++++ js/src/jsapi.h | 54 +-------------- js/src/jspubtd.h | 2 - js/src/moz.build | 1 + 4 files changed, 95 insertions(+), 55 deletions(-) create mode 100644 js/public/OffThreadScriptCompilation.h diff --git a/js/public/OffThreadScriptCompilation.h b/js/public/OffThreadScriptCompilation.h new file mode 100644 index 0000000000..2194791bab --- /dev/null +++ b/js/public/OffThreadScriptCompilation.h @@ -0,0 +1,93 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +/* + * Types and functions related to the compilation of JavaScript off the + * direct JSAPI-using thread. + */ + +#ifndef js_OffThreadScriptCompilation_h +#define js_OffThreadScriptCompilation_h + +#include "mozilla/Range.h" // mozilla::Range +#include "mozilla/Vector.h" // mozilla::Vector + +#include // size_t + +#include "jstypes.h" // JS_PUBLIC_API + +#include "js/CompileOptions.h" // JS::ReadOnlyCompileOptions +#include "js/GCVector.h" // JS::GCVector +#include "js/Transcoding.h" // JS::TranscodeSource + +struct JSContext; +class JSScript; + +namespace JS { + +class SourceBufferHolder; + +} // namespace JS + +namespace JS { + +using OffThreadCompileCallback = void (*)(void* token, void* callbackData); + +extern JS_PUBLIC_API(bool) +CanCompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, size_t length); + +/* + * Off thread compilation control flow. + * + * After successfully triggering an off thread compile of a script, the + * callback will eventually be invoked with the specified data and a token + * for the compilation. The callback will be invoked while off the main thread, + * so must ensure that its operations are thread safe. Afterwards, one of the + * following functions must be invoked on the main thread: + * + * - FinishOffThreadScript, to get the result script (or nullptr on failure). + * - CancelOffThreadScript, to free the resources without creating a script. + * + * The characters passed in to CompileOffThread must remain live until the + * callback is invoked, and the resulting script will be rooted until the call + * to FinishOffThreadScript. + */ + +extern JS_PUBLIC_API(bool) +CompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, + const char16_t* chars, size_t length, + OffThreadCompileCallback callback, void* callbackData); + +extern JS_PUBLIC_API(JSScript*) +FinishOffThreadScript(JSContext* cx, void* token); + +extern JS_PUBLIC_API(void) +CancelOffThreadScript(JSContext* cx, void* token); + +extern JS_PUBLIC_API(bool) +CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options, + const char16_t* chars, size_t length, + OffThreadCompileCallback callback, void* callbackData); + +extern JS_PUBLIC_API(JSObject*) +FinishOffThreadModule(JSContext* cx, void* token); + +extern JS_PUBLIC_API(void) +CancelOffThreadModule(JSContext* cx, void* token); + +extern JS_PUBLIC_API(bool) +DecodeOffThreadScript(JSContext* cx, const ReadOnlyCompileOptions& options, + mozilla::Vector& buffer /* TranscodeBuffer& */, size_t cursor, + OffThreadCompileCallback callback, void* callbackData); + +extern JS_PUBLIC_API(JSScript*) +FinishOffThreadScriptDecoder(JSContext* cx, void* token); + +extern JS_PUBLIC_API(void) +CancelOffThreadScriptDecoder(JSContext* cx, void* token); + +} // namespace JS + +#endif /* js_OffThreadScriptCompilation_h */ \ No newline at end of file diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 9ae22ddacc..39828d25ff 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -33,6 +33,7 @@ #include "js/GCVector.h" #include "js/HashTable.h" #include "js/Id.h" +#include "js/OffThreadScriptCompilation.h" #include "js/Principals.h" #include "js/Realm.h" #include "js/RootingAPI.h" @@ -3678,59 +3679,6 @@ extern JS_PUBLIC_API(bool) CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, const char* filename, JS::MutableHandleScript script); -extern JS_PUBLIC_API(bool) -CanCompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, size_t length); - -/* - * Off thread compilation control flow. - * - * After successfully triggering an off thread compile of a script, the - * callback will eventually be invoked with the specified data and a token - * for the compilation. The callback will be invoked while off the main thread, - * so must ensure that its operations are thread safe. Afterwards, one of the - * following functions must be invoked on the main thread: - * - * - FinishOffThreadScript, to get the result script (or nullptr on failure). - * - CancelOffThreadScript, to free the resources without creating a script. - * - * The characters passed in to CompileOffThread must remain live until the - * callback is invoked, and the resulting script will be rooted until the call - * to FinishOffThreadScript. - */ - -extern JS_PUBLIC_API(bool) -CompileOffThread(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, - OffThreadCompileCallback callback, void* callbackData); - -extern JS_PUBLIC_API(JSScript*) -FinishOffThreadScript(JSContext* cx, void* token); - -extern JS_PUBLIC_API(void) -CancelOffThreadScript(JSContext* cx, void* token); - -extern JS_PUBLIC_API(bool) -CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, - OffThreadCompileCallback callback, void* callbackData); - -extern JS_PUBLIC_API(JSObject*) -FinishOffThreadModule(JSContext* cx, void* token); - -extern JS_PUBLIC_API(void) -CancelOffThreadModule(JSContext* cx, void* token); - -extern JS_PUBLIC_API(bool) -DecodeOffThreadScript(JSContext* cx, const ReadOnlyCompileOptions& options, - mozilla::Vector& buffer /* TranscodeBuffer& */, size_t cursor, - OffThreadCompileCallback callback, void* callbackData); - -extern JS_PUBLIC_API(JSScript*) -FinishOffThreadScriptDecoder(JSContext* cx, void* token); - -extern JS_PUBLIC_API(void) -CancelOffThreadScriptDecoder(JSContext* cx, void* token); - /** * Compile a function with envChain plus the global as its scope chain. * envChain must contain objects in the current compartment of cx. The actual diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index b2be737904..21318af6c9 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -150,8 +150,6 @@ class JS_PUBLIC_API(AutoEnterCycleCollection); class JS_PUBLIC_API(AutoAssertOnBarrier); struct JS_PUBLIC_API(PropertyDescriptor); -typedef void (*OffThreadCompileCallback)(void* token, void* callbackData); - enum class HeapState { Idle, // doing nothing with the GC heap Tracing, // tracing the GC heap without collecting, e.g. IterateCompartments() diff --git a/js/src/moz.build b/js/src/moz.build index 9670d64bb5..383ea8233f 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -84,6 +84,7 @@ EXPORTS.js += [ '../public/Initialization.h', '../public/LegacyIntTypes.h', '../public/MemoryMetrics.h', + '../public/OffThreadScriptCompilation.h', '../public/Principals.h', '../public/ProfilingFrameIterator.h', '../public/ProfilingStack.h', From 40ed1b10f43418b530814a353a6694cabf9386ef Mon Sep 17 00:00:00 2001 From: Moonchild Date: Tue, 4 Mar 2025 12:03:05 +0100 Subject: [PATCH 5/8] Issue #2692 - Part 5: Split out compilation and evaluation APIs into its own header. --- js/public/CompilationAndEvaluation.h | 236 +++++++++++++++++++++++++++ js/src/jsapi.h | 208 +---------------------- js/src/moz.build | 1 + 3 files changed, 238 insertions(+), 207 deletions(-) create mode 100644 js/public/CompilationAndEvaluation.h diff --git a/js/public/CompilationAndEvaluation.h b/js/public/CompilationAndEvaluation.h new file mode 100644 index 0000000000..c3838d4c88 --- /dev/null +++ b/js/public/CompilationAndEvaluation.h @@ -0,0 +1,236 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +/* Functions for compiling and evaluating scripts. */ + +#ifndef js_CompilationAndEvaluation_h +#define js_CompilationAndEvaluation_h + +#include // size_t +#include // FILE + +#include "jstypes.h" // JS_PUBLIC_API + +#include "js/CompileOptions.h" // JS::CompileOptions, JS::ReadOnlyCompileOptions +#include "js/RootingAPI.h" // JS::Handle, JS::MutableHandle +#include "js/GCVector.h" + +struct JSContext; +class JSFunction; +class JSObject; +class JSScript; + +namespace JS { + +class AutoObjectVector : public Rooted> { + using Vec = GCVector; + using Base = Rooted; + public: + explicit AutoObjectVector(JSContext* cx) : Base(cx, Vec(cx)) {} + explicit AutoObjectVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {} +}; + +class SourceBufferHolder; + +} // namespace JS + +/** + * Given a buffer, return false if the buffer might become a valid + * javascript statement with the addition of more lines. Otherwise return + * true. The intent is to support interactive compilation - accumulate + * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to + * the compiler. + */ +extern JS_PUBLIC_API(bool) +JS_BufferIsCompilableUnit(JSContext* cx, JS::Handle obj, const char* utf8, + size_t length); + +/* + * NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either + * they use the global as the scope, or they take an AutoObjectVector of objects + * to use as the scope chain. In the former case, the global is also used as + * the "this" keyword value and the variables object (ECMA parlance for where + * 'var' and 'function' bind names) of the execution context for script. In the + * latter case, the first object in the provided list is used, unless the list + * is empty, in which case the global is used. + * + * Why a runtime option? The alternative is to add APIs duplicating those + * for the other value of flags, and that doesn't seem worth the code bloat + * cost. Such new entry points would probably have less obvious names, too, so + * would not tend to be used. The ContextOptionsRef adjustment, OTOH, can be + * more easily hacked into existing code that does not depend on the bug; such + * code can continue to use the familiar JS::Evaluate, etc., entry points. + */ + +/** + * Evaluate a script in the scope of the current global of cx. + */ +extern JS_PUBLIC_API(bool) +JS_ExecuteScript(JSContext* cx, JS::HandleScript script, JS::MutableHandleValue rval); + +extern JS_PUBLIC_API(bool) +JS_ExecuteScript(JSContext* cx, JS::HandleScript script); + +/** + * As above, but providing an explicit scope chain. envChain must not include + * the global object on it; that's implicit. It needs to contain the other + * objects that should end up on the script's scope chain. + */ +extern JS_PUBLIC_API(bool) +JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, + JS::HandleScript script, JS::MutableHandleValue rval); + +extern JS_PUBLIC_API(bool) +JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, JS::HandleScript script); + +/** + * |script| will always be set. On failure, it will be set to nullptr. + */ +extern JS_PUBLIC_API(bool) +JS_CompileScript(JSContext* cx, const char* ascii, size_t length, + const JS::CompileOptions& options, + JS::MutableHandleScript script); + +/** + * |script| will always be set. On failure, it will be set to nullptr. + */ +extern JS_PUBLIC_API(bool) +JS_CompileUCScript(JSContext* cx, const char16_t* chars, size_t length, + const JS::CompileOptions& options, + JS::MutableHandleScript script); + +namespace JS { + +/** + * Like the above, but handles a cross-compartment script. If the script is + * cross-compartment, it is cloned into the current compartment before executing. + */ +extern JS_PUBLIC_API(bool) +CloneAndExecuteScript(JSContext* cx, JS::Handle script, + JS::MutableHandleValue rval); + +/** + * Evaluate the given source buffer in the scope of the current global of cx. + */ +extern JS_PUBLIC_API(bool) +Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, + SourceBufferHolder& srcBuf, JS::MutableHandleValue rval); + +/** + * As above, but providing an explicit scope chain. envChain must not include + * the global object on it; that's implicit. It needs to contain the other + * objects that should end up on the script's scope chain. + */ +extern JS_PUBLIC_API(bool) +Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options, + SourceBufferHolder& srcBuf, JS::MutableHandleValue rval); + +/** + * Evaluate the given character buffer in the scope of the current global of cx. + */ +extern JS_PUBLIC_API(bool) +Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, + const char16_t* chars, size_t length, JS::MutableHandleValue rval); + +/** + * As above, but providing an explicit scope chain. envChain must not include + * the global object on it; that's implicit. It needs to contain the other + * objects that should end up on the script's scope chain. + */ +extern JS_PUBLIC_API(bool) +Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options, + const char16_t* chars, size_t length, JS::MutableHandleValue rval); + +/** + * Evaluate the given byte buffer in the scope of the current global of cx. + */ +extern JS_PUBLIC_API(bool) +Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, + const char* bytes, size_t length, JS::MutableHandleValue rval); + +/** + * Evaluate the given file in the scope of the current global of cx. + */ +extern JS_PUBLIC_API(bool) +Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, + const char* filename, JS::MutableHandleValue rval); + +/** + * |script| will always be set. On failure, it will be set to nullptr. + */ +extern JS_PUBLIC_API(bool) +Compile(JSContext* cx, const ReadOnlyCompileOptions& options, + SourceBufferHolder& srcBuf, JS::MutableHandleScript script); + +extern JS_PUBLIC_API(bool) +Compile(JSContext* cx, const ReadOnlyCompileOptions& options, + const char* bytes, size_t length, JS::MutableHandleScript script); + +extern JS_PUBLIC_API(bool) +Compile(JSContext* cx, const ReadOnlyCompileOptions& options, + const char16_t* chars, size_t length, JS::MutableHandleScript script); + +extern JS_PUBLIC_API(bool) +Compile(JSContext* cx, const ReadOnlyCompileOptions& options, + FILE* file, JS::MutableHandleScript script); + +extern JS_PUBLIC_API(bool) +Compile(JSContext* cx, const ReadOnlyCompileOptions& options, + const char* filename, JS::MutableHandleScript script); + +extern JS_PUBLIC_API(bool) +CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, + SourceBufferHolder& srcBuf, JS::MutableHandleScript script); + +extern JS_PUBLIC_API(bool) +CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, + const char* bytes, size_t length, JS::MutableHandleScript script); + +extern JS_PUBLIC_API(bool) +CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, + const char16_t* chars, size_t length, JS::MutableHandleScript script); + +extern JS_PUBLIC_API(bool) +CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, + FILE* file, JS::MutableHandleScript script); + +extern JS_PUBLIC_API(bool) +CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, + const char* filename, JS::MutableHandleScript script); + +/** + * Compile a function with envChain plus the global as its scope chain. + * envChain must contain objects in the current compartment of cx. The actual + * scope chain used for the function will consist of With wrappers for those + * objects, followed by the current global of the compartment cx is in. This + * global must not be explicitly included in the scope chain. + */ +extern JS_PUBLIC_API(bool) +CompileFunction(JSContext* cx, AutoObjectVector& envChain, + const ReadOnlyCompileOptions& options, + const char* name, unsigned nargs, const char* const* argnames, + const char16_t* chars, size_t length, JS::MutableHandleFunction fun); + +/** + * Same as above, but taking a SourceBufferHolder for the function body. + */ +extern JS_PUBLIC_API(bool) +CompileFunction(JSContext* cx, AutoObjectVector& envChain, + const ReadOnlyCompileOptions& options, + const char* name, unsigned nargs, const char* const* argnames, + SourceBufferHolder& srcBuf, JS::MutableHandleFunction fun); + +/** + * Same as above, but taking a const char * for the function body. + */ +extern JS_PUBLIC_API(bool) +CompileFunction(JSContext* cx, AutoObjectVector& envChain, + const ReadOnlyCompileOptions& options, + const char* name, unsigned nargs, const char* const* argnames, + const char* bytes, size_t length, JS::MutableHandleFunction fun); + +} /* namespace JS */ + +#endif /* js_CompilationAndEvaluation_h */ diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 39828d25ff..ac7610f5f8 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -29,6 +29,7 @@ #include "js/CallArgs.h" #include "js/CharacterEncoding.h" #include "js/Class.h" +#include "js/CompilationAndEvaluation.h" #include "js/CompileOptions.h" #include "js/GCVector.h" #include "js/HashTable.h" @@ -242,14 +243,6 @@ class AutoIdVector : public Rooted> { bool appendAll(const AutoIdVector& other) { return this->Base::appendAll(other.get()); } }; -class AutoObjectVector : public Rooted> { - using Vec = GCVector; - using Base = Rooted; - public: - explicit AutoObjectVector(JSContext* cx) : Base(cx, Vec(cx)) {} - explicit AutoObjectVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {} -}; - using ValueVector = JS::GCVector; using IdVector = JS::GCVector; using ScriptVector = JS::GCVector; @@ -3595,32 +3588,7 @@ CloneFunctionObject(JSContext* cx, HandleObject funobj, AutoObjectVector& scopeC } // namespace JS -/** - * Given a buffer, return false if the buffer might become a valid - * javascript statement with the addition of more lines. Otherwise return - * true. The intent is to support interactive compilation - accumulate - * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to - * the compiler. - */ -extern JS_PUBLIC_API(bool) -JS_BufferIsCompilableUnit(JSContext* cx, JS::Handle obj, const char* utf8, - size_t length); -/** - * |script| will always be set. On failure, it will be set to nullptr. - */ -extern JS_PUBLIC_API(bool) -JS_CompileScript(JSContext* cx, const char* ascii, size_t length, - const JS::CompileOptions& options, - JS::MutableHandleScript script); - -/** - * |script| will always be set. On failure, it will be set to nullptr. - */ -extern JS_PUBLIC_API(bool) -JS_CompileUCScript(JSContext* cx, const char16_t* chars, size_t length, - const JS::CompileOptions& options, - JS::MutableHandleScript script); extern JS_PUBLIC_API(JSObject*) JS_GetGlobalFromScript(JSScript* script); @@ -3634,84 +3602,6 @@ JS_GetScriptBaseLineNumber(JSContext* cx, JSScript* script); extern JS_PUBLIC_API(JSScript*) JS_GetFunctionScript(JSContext* cx, JS::HandleFunction fun); -namespace JS { - -/** - * |script| will always be set. On failure, it will be set to nullptr. - */ -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* bytes, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - FILE* file, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -Compile(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* filename, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* bytes, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - FILE* file, JS::MutableHandleScript script); - -extern JS_PUBLIC_API(bool) -CompileForNonSyntacticScope(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* filename, JS::MutableHandleScript script); - -/** - * Compile a function with envChain plus the global as its scope chain. - * envChain must contain objects in the current compartment of cx. The actual - * scope chain used for the function will consist of With wrappers for those - * objects, followed by the current global of the compartment cx is in. This - * global must not be explicitly included in the scope chain. - */ -extern JS_PUBLIC_API(bool) -CompileFunction(JSContext* cx, AutoObjectVector& envChain, - const ReadOnlyCompileOptions& options, - const char* name, unsigned nargs, const char* const* argnames, - const char16_t* chars, size_t length, JS::MutableHandleFunction fun); - -/** - * Same as above, but taking a SourceBufferHolder for the function body. - */ -extern JS_PUBLIC_API(bool) -CompileFunction(JSContext* cx, AutoObjectVector& envChain, - const ReadOnlyCompileOptions& options, - const char* name, unsigned nargs, const char* const* argnames, - SourceBufferHolder& srcBuf, JS::MutableHandleFunction fun); - -/** - * Same as above, but taking a const char * for the function body. - */ -extern JS_PUBLIC_API(bool) -CompileFunction(JSContext* cx, AutoObjectVector& envChain, - const ReadOnlyCompileOptions& options, - const char* name, unsigned nargs, const char* const* argnames, - const char* bytes, size_t length, JS::MutableHandleFunction fun); - -} /* namespace JS */ - extern JS_PUBLIC_API(JSString*) JS_DecompileScript(JSContext* cx, JS::Handle script); @@ -3719,104 +3609,8 @@ extern JS_PUBLIC_API(JSString*) JS_DecompileFunction(JSContext* cx, JS::Handle fun); -/* - * NB: JS_ExecuteScript and the JS::Evaluate APIs come in two flavors: either - * they use the global as the scope, or they take an AutoObjectVector of objects - * to use as the scope chain. In the former case, the global is also used as - * the "this" keyword value and the variables object (ECMA parlance for where - * 'var' and 'function' bind names) of the execution context for script. In the - * latter case, the first object in the provided list is used, unless the list - * is empty, in which case the global is used. - * - * Why a runtime option? The alternative is to add APIs duplicating those - * for the other value of flags, and that doesn't seem worth the code bloat - * cost. Such new entry points would probably have less obvious names, too, so - * would not tend to be used. The ContextOptionsRef adjustment, OTOH, can be - * more easily hacked into existing code that does not depend on the bug; such - * code can continue to use the familiar JS::Evaluate, etc., entry points. - */ - -/** - * Evaluate a script in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::HandleScript script, JS::MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::HandleScript script); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, - JS::HandleScript script, JS::MutableHandleValue rval); - -extern JS_PUBLIC_API(bool) -JS_ExecuteScript(JSContext* cx, JS::AutoObjectVector& envChain, JS::HandleScript script); - namespace JS { -/** - * Like the above, but handles a cross-compartment script. If the script is - * cross-compartment, it is cloned into the current compartment before executing. - */ -extern JS_PUBLIC_API(bool) -CloneAndExecuteScript(JSContext* cx, JS::Handle script, - JS::MutableHandleValue rval); - -} /* namespace JS */ - -namespace JS { - -/** - * Evaluate the given source buffer in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleValue rval); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, JS::MutableHandleValue rval); - -/** - * Evaluate the given character buffer in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleValue rval); - -/** - * As above, but providing an explicit scope chain. envChain must not include - * the global object on it; that's implicit. It needs to contain the other - * objects that should end up on the script's scope chain. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, AutoObjectVector& envChain, const ReadOnlyCompileOptions& options, - const char16_t* chars, size_t length, JS::MutableHandleValue rval); - -/** - * Evaluate the given byte buffer in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* bytes, size_t length, JS::MutableHandleValue rval); - -/** - * Evaluate the given file in the scope of the current global of cx. - */ -extern JS_PUBLIC_API(bool) -Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options, - const char* filename, JS::MutableHandleValue rval); - using ModuleResolveHook = JSObject* (*)(JSContext*, HandleValue, HandleString); /** diff --git a/js/src/moz.build b/js/src/moz.build index 383ea8233f..def03e98e1 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -67,6 +67,7 @@ EXPORTS.js += [ '../public/CallNonGenericMethod.h', '../public/CharacterEncoding.h', '../public/Class.h', + '../public/CompilationAndEvaluation.h', '../public/CompileOptions.h', '../public/Conversions.h', '../public/Date.h', From 2e4620b5afe29d845fbc0acaee1282ccbccecf91 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Tue, 4 Mar 2025 20:16:54 +0100 Subject: [PATCH 6/8] Issue #2692 - Part 6: Don't #include js/SourceBufferHolder.h in jsapi.h. Instead, require users to do so. This is a minor translation-unit size improvement for anyone who never has to use SourceBufferHolder other than by reference. --- dom/base/nsFrameMessageManager.cpp | 1 + dom/base/nsJSUtils.cpp | 1 + dom/script/ScriptLoader.cpp | 1 + dom/workers/ScriptLoader.cpp | 1 + dom/workers/WorkerPrivate.cpp | 1 + dom/worklet/Worklet.cpp | 1 + dom/xul/XULDocument.cpp | 1 + dom/xul/nsXULElement.cpp | 1 + ipc/testshell/XPCShellEnvironment.cpp | 1 + js/src/NamespaceImports.h | 1 - js/src/builtin/Eval.cpp | 2 ++ js/src/frontend/BytecodeCompiler.cpp | 4 ++++ js/src/frontend/BytecodeCompiler.h | 8 ++++---- js/src/jsapi-tests/testJSEvaluateScript.cpp | 1 + js/src/jsapi-tests/testMutedErrors.cpp | 1 + js/src/jsapi-tests/testScriptObject.cpp | 1 + js/src/jsapi.cpp | 2 ++ js/src/jsapi.h | 1 - js/src/jsfun.cpp | 2 ++ js/src/jsscript.cpp | 3 +++ js/src/shell/js.cpp | 5 +++-- js/src/vm/Debugger.cpp | 2 ++ js/src/vm/HelperThreads.cpp | 3 +++ js/src/vm/HelperThreads.h | 1 + js/src/wasm/AsmJS.cpp | 2 ++ js/xpconnect/loader/mozJSComponentLoader.cpp | 1 + js/xpconnect/loader/mozJSSubScriptLoader.cpp | 1 + js/xpconnect/src/Sandbox.cpp | 1 + 28 files changed, 43 insertions(+), 8 deletions(-) diff --git a/dom/base/nsFrameMessageManager.cpp b/dom/base/nsFrameMessageManager.cpp index 88ec9c911f..ffb5709e46 100644 --- a/dom/base/nsFrameMessageManager.cpp +++ b/dom/base/nsFrameMessageManager.cpp @@ -27,6 +27,7 @@ #include "nsIScriptSecurityManager.h" #include "nsIDOMClassInfo.h" #include "xpcpublic.h" +#include "js/SourceBufferHolder.h" #include "mozilla/CycleCollectedJSContext.h" #include "mozilla/IntentionalCrash.h" #include "mozilla/Preferences.h" diff --git a/dom/base/nsJSUtils.cpp b/dom/base/nsJSUtils.cpp index 5182886256..5a1dfc3028 100644 --- a/dom/base/nsJSUtils.cpp +++ b/dom/base/nsJSUtils.cpp @@ -13,6 +13,7 @@ #include "nsJSUtils.h" #include "jsapi.h" #include "jsfriendapi.h" +#include "js/SourceBufferHolder.h" #include "nsIScriptContext.h" #include "nsIScriptGlobalObject.h" #include "nsIXPConnect.h" diff --git a/dom/script/ScriptLoader.cpp b/dom/script/ScriptLoader.cpp index 0780601767..b6462a0cee 100644 --- a/dom/script/ScriptLoader.cpp +++ b/dom/script/ScriptLoader.cpp @@ -11,6 +11,7 @@ #include "prsystem.h" #include "jsapi.h" #include "jsfriendapi.h" +#include "js/SourceBufferHolder.h" #include "xpcpublic.h" #include "nsCycleCollectionParticipant.h" #include "nsIContent.h" diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index c05309dd0a..f6a4943653 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -24,6 +24,7 @@ #include "jsapi.h" #include "jsfriendapi.h" +#include "js/SourceBufferHolder.h" #include "nsError.h" #include "nsContentPolicyUtils.h" #include "nsContentUtils.h" diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index a0206ec776..bb745ba491 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -37,6 +37,7 @@ #include "ImageContainer.h" #include "jsfriendapi.h" #include "js/MemoryMetrics.h" +#include "js/SourceBufferHolder.h" #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/ContentEvents.h" diff --git a/dom/worklet/Worklet.cpp b/dom/worklet/Worklet.cpp index 5bfdc9c176..9d3f2f5436 100644 --- a/dom/worklet/Worklet.cpp +++ b/dom/worklet/Worklet.cpp @@ -13,6 +13,7 @@ #include "mozilla/dom/Response.h" #include "mozilla/dom/ScriptLoader.h" #include "mozilla/dom/ScriptSettings.h" +#include "js/SourceBufferHolder.h" #include "nsIInputStreamPump.h" #include "nsIThreadRetargetableRequest.h" #include "nsNetUtil.h" diff --git a/dom/xul/XULDocument.cpp b/dom/xul/XULDocument.cpp index 72a62b6e0f..1c07d144b0 100644 --- a/dom/xul/XULDocument.cpp +++ b/dom/xul/XULDocument.cpp @@ -88,6 +88,7 @@ #include "mozilla/Preferences.h" #include "nsTextNode.h" #include "nsJSUtils.h" +#include "js/SourceBufferHolder.h" #include "mozilla/dom/URL.h" #include "nsIContentPolicy.h" #include "mozAutoDocUpdate.h" diff --git a/dom/xul/nsXULElement.cpp b/dom/xul/nsXULElement.cpp index 961de20ee3..08df34436c 100644 --- a/dom/xul/nsXULElement.cpp +++ b/dom/xul/nsXULElement.cpp @@ -26,6 +26,7 @@ #include "mozilla/EventListenerManager.h" #include "mozilla/EventStateManager.h" #include "mozilla/EventStates.h" +#include "js/SourceBufferHolder.h" #include "nsFocusManager.h" #include "nsHTMLStyleSheet.h" #include "nsNameSpaceManager.h" diff --git a/ipc/testshell/XPCShellEnvironment.cpp b/ipc/testshell/XPCShellEnvironment.cpp index c97be68a52..7a1e03fd90 100644 --- a/ipc/testshell/XPCShellEnvironment.cpp +++ b/ipc/testshell/XPCShellEnvironment.cpp @@ -15,6 +15,7 @@ #include "base/basictypes.h" #include "jsapi.h" +#include "js/SourceBufferHolder.h" #include "xpcpublic.h" diff --git a/js/src/NamespaceImports.h b/js/src/NamespaceImports.h index dd940dc808..ed02054622 100644 --- a/js/src/NamespaceImports.h +++ b/js/src/NamespaceImports.h @@ -113,7 +113,6 @@ using JS::IsAcceptableThis; using JS::NativeImpl; using JS::OwningCompileOptions; using JS::ReadOnlyCompileOptions; -using JS::SourceBufferHolder; using JS::TransitiveCompileOptions; using JS::Rooted; diff --git a/js/src/builtin/Eval.cpp b/js/src/builtin/Eval.cpp index b60330b516..7be704d9bc 100644 --- a/js/src/builtin/Eval.cpp +++ b/js/src/builtin/Eval.cpp @@ -12,6 +12,7 @@ #include "jshashutil.h" #include "frontend/BytecodeCompiler.h" +#include "js/SourceBufferHolder.h" #include "vm/Debugger.h" #include "vm/GlobalObject.h" #include "vm/JSONParser.h" @@ -25,6 +26,7 @@ using mozilla::HashString; using mozilla::RangedPtr; using JS::AutoCheckCannotGC; +using JS::SourceBufferHolder; // We should be able to assert this for *any* fp->environmentChain(). static void diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index cdb386f249..2a2c8e0597 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -16,6 +16,7 @@ #include "frontend/FoldConstants.h" #include "frontend/NameFunctions.h" #include "frontend/Parser.h" +#include "js/SourceBufferHolder.h" #include "vm/GlobalObject.h" #include "vm/TraceLogging.h" #include "wasm/AsmJS.h" @@ -27,9 +28,12 @@ using namespace js; using namespace js::frontend; + using mozilla::Maybe; using mozilla::Nothing; +using JS::SourceBufferHolder; + class MOZ_STACK_CLASS AutoCompilationTraceLogger { public: diff --git a/js/src/frontend/BytecodeCompiler.h b/js/src/frontend/BytecodeCompiler.h index 471e9e36d9..f87e260b1a 100644 --- a/js/src/frontend/BytecodeCompiler.h +++ b/js/src/frontend/BytecodeCompiler.h @@ -28,7 +28,7 @@ namespace frontend { JSScript* CompileGlobalScript(ExclusiveContext* cx, LifoAlloc& alloc, ScopeKind scopeKind, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, + JS::SourceBufferHolder& srcBuf, SourceCompressionTask* extraSct = nullptr, ScriptSourceObject** sourceObjectOut = nullptr); @@ -36,17 +36,17 @@ JSScript* CompileEvalScript(ExclusiveContext* cx, LifoAlloc& alloc, HandleObject scopeChain, HandleScope enclosingScope, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, + JS::SourceBufferHolder& srcBuf, SourceCompressionTask* extraSct = nullptr, ScriptSourceObject** sourceObjectOut = nullptr); ModuleObject* CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf); + JS::SourceBufferHolder& srcBuf); ModuleObject* CompileModule(ExclusiveContext* cx, const ReadOnlyCompileOptions& options, - SourceBufferHolder& srcBuf, LifoAlloc& alloc, + JS::SourceBufferHolder& srcBuf, LifoAlloc& alloc, ScriptSourceObject** sourceObjectOut = nullptr); MOZ_MUST_USE bool diff --git a/js/src/jsapi-tests/testJSEvaluateScript.cpp b/js/src/jsapi-tests/testJSEvaluateScript.cpp index 579503a829..e546b38785 100644 --- a/js/src/jsapi-tests/testJSEvaluateScript.cpp +++ b/js/src/jsapi-tests/testJSEvaluateScript.cpp @@ -1,6 +1,7 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +#include "js/SourceBufferHolder.h" #include "jsapi-tests/tests.h" using mozilla::ArrayLength; diff --git a/js/src/jsapi-tests/testMutedErrors.cpp b/js/src/jsapi-tests/testMutedErrors.cpp index da91afb2af..ad49e30c02 100644 --- a/js/src/jsapi-tests/testMutedErrors.cpp +++ b/js/src/jsapi-tests/testMutedErrors.cpp @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "jsfriendapi.h" +#include "js/SourceBufferHolder.h" #include "jsapi-tests/tests.h" BEGIN_TEST(testMutedErrors) diff --git a/js/src/jsapi-tests/testScriptObject.cpp b/js/src/jsapi-tests/testScriptObject.cpp index 9c865dae11..501268073e 100644 --- a/js/src/jsapi-tests/testScriptObject.cpp +++ b/js/src/jsapi-tests/testScriptObject.cpp @@ -4,6 +4,7 @@ * 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/. */ +#include "js/SourceBufferHolder.h" #include "jsapi-tests/tests.h" struct ScriptObjectFixture : public JSAPITest { diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 74d54aae64..2bea8b8be7 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -63,6 +63,7 @@ #include "js/Initialization.h" #include "js/Proxy.h" #include "js/SliceBudget.h" +#include "js/SourceBufferHolder.h" #include "js/StructuredClone.h" #include "js/Utility.h" #include "vm/AsyncFunction.h" @@ -106,6 +107,7 @@ using mozilla::PodZero; using mozilla::Some; using JS::AutoGCRooter; +using JS::SourceBufferHolder; using JS::ToInt32; using JS::ToInteger; using JS::ToUint32; diff --git a/js/src/jsapi.h b/js/src/jsapi.h index ac7610f5f8..cae2297ae4 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -38,7 +38,6 @@ #include "js/Principals.h" #include "js/Realm.h" #include "js/RootingAPI.h" -#include "js/SourceBufferHolder.h" #include "js/Stream.h" #include "js/TracingAPI.h" #include "js/Transcoding.h" diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index ad2e1fcd95..9d2a819ca6 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -39,6 +39,7 @@ #include "jit/JitFrameIterator.h" #include "js/CallNonGenericMethod.h" #include "js/Proxy.h" +#include "js/SourceBufferHolder.h" #include "vm/AsyncFunction.h" #include "vm/AsyncIteration.h" #include "vm/Debugger.h" @@ -67,6 +68,7 @@ using mozilla::PodCopy; using mozilla::RangedPtr; using mozilla::Some; +using JS::SourceBufferHolder; static bool fun_enumerate(JSContext* cx, HandleObject obj) { diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index a438f051c9..0fcdb57eb8 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -41,6 +41,7 @@ #include "jit/Ion.h" #include "jit/IonCode.h" #include "js/MemoryMetrics.h" +#include "js/SourceBufferHolder.h" #include "js/Utility.h" #include "vm/ArgumentsObject.h" #include "vm/Compression.h" @@ -68,6 +69,8 @@ using mozilla::PodCopy; using mozilla::PodZero; using mozilla::RotateLeft; +using JS::SourceBufferHolder; + template bool js::XDRScriptConst(XDRState* xdr, MutableHandleValue vp) diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index f844913e4d..d4e0a5065e 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -74,6 +74,7 @@ #include "js/Equality.h" // JS::SameValue #include "js/GCAPI.h" #include "js/Initialization.h" +#include "js/SourceBufferHolder.h" #include "js/StructuredClone.h" #include "js/TrackedOptimizationInfo.h" #include "perf/jsperf.h" @@ -4062,8 +4063,8 @@ ParseModule(JSContext* cx, unsigned argc, Value* vp) return false; const char16_t* chars = stableChars.twoByteRange().begin().get(); - SourceBufferHolder srcBuf(chars, scriptContents->length(), - SourceBufferHolder::NoOwnership); + JS::SourceBufferHolder srcBuf(chars, scriptContents->length(), + SourceBufferHolder::NoOwnership); RootedObject module(cx, frontend::CompileModule(cx, options, srcBuf)); if (!module) diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 574dd1ba5e..e1416a8908 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -27,6 +27,7 @@ #include "jit/BaselineJIT.h" #include "js/Date.h" #include "js/GCAPI.h" +#include "js/SourceBufferHolder.h" #include "js/UbiNodeBreadthFirst.h" #include "js/Vector.h" #include "proxy/ScriptedProxyHandler.h" @@ -51,6 +52,7 @@ using namespace js; using JS::dbg::AutoEntryMonitor; using JS::dbg::Builder; using js::frontend::IsIdentifier; +using JS::SourceBufferHolder; using mozilla::ArrayLength; using mozilla::DebugOnly; using mozilla::MakeScopeExit; diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp index 4ce8728ace..488522c987 100644 --- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -10,6 +10,7 @@ #include "jsnativestack.h" #include "jsnum.h" // For FIX_FPU() +#include "js/SourceBufferHolder.h" #include "builtin/Promise.h" #include "frontend/BytecodeCompiler.h" @@ -33,6 +34,8 @@ using mozilla::DebugOnly; using mozilla::Unused; using mozilla::TimeDuration; +using JS::SourceBufferHolder; + namespace js { GlobalHelperThreadState* gHelperThreadState = nullptr; diff --git a/js/src/vm/HelperThreads.h b/js/src/vm/HelperThreads.h index 51a18a8060..48c638e34e 100644 --- a/js/src/vm/HelperThreads.h +++ b/js/src/vm/HelperThreads.h @@ -21,6 +21,7 @@ #include "frontend/TokenStream.h" #include "jit/Ion.h" +#include "js/SourceBufferHolder.h" #include "threading/ConditionVariable.h" #include "vm/MutexIDs.h" diff --git a/js/src/wasm/AsmJS.cpp b/js/src/wasm/AsmJS.cpp index 69788a852b..e7c956d972 100644 --- a/js/src/wasm/AsmJS.cpp +++ b/js/src/wasm/AsmJS.cpp @@ -33,6 +33,7 @@ #include "frontend/Parser.h" #include "gc/Policy.h" #include "js/MemoryMetrics.h" +#include "js/SourceBufferHolder.h" #include "vm/SelfHosting.h" #include "vm/StringBuffer.h" #include "vm/Time.h" @@ -67,6 +68,7 @@ using mozilla::PodZero; using mozilla::PositiveInfinity; using JS::AsmJSOption; using JS::GenericNaN; +using JS::SourceBufferHolder; /*****************************************************************************/ diff --git a/js/xpconnect/loader/mozJSComponentLoader.cpp b/js/xpconnect/loader/mozJSComponentLoader.cpp index 5b9e09a0a1..ddb7491466 100644 --- a/js/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/xpconnect/loader/mozJSComponentLoader.cpp @@ -17,6 +17,7 @@ #endif #include "jsapi.h" +#include "js/SourceBufferHolder.h" #include "nsCOMPtr.h" #include "nsAutoPtr.h" #include "nsIComponentManager.h" diff --git a/js/xpconnect/loader/mozJSSubScriptLoader.cpp b/js/xpconnect/loader/mozJSSubScriptLoader.cpp index 8844a1d929..fc3b496f73 100644 --- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp +++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp @@ -19,6 +19,7 @@ #include "jsapi.h" #include "jsfriendapi.h" +#include "js/SourceBufferHolder.h" #include "nsJSPrincipals.h" #include "xpcprivate.h" // For xpc::OptionsBase #include "jswrapper.h" diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index 6ce1104179..6808e655a5 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -10,6 +10,7 @@ #include "AccessCheck.h" #include "jsfriendapi.h" #include "js/Proxy.h" +#include "js/SourceBufferHolder.h" #include "js/StructuredClone.h" #include "nsContentUtils.h" #include "nsGlobalWindow.h" From 5fd304507d5633a61b0aac9e1cf2e24614c244b2 Mon Sep 17 00:00:00 2001 From: Moonchild Date: Wed, 5 Mar 2025 04:09:03 +0100 Subject: [PATCH 7/8] Issue #2692 - Part 7: De-globalize {*}CompileOptions. Make all users of the various *CompileOptions classes #include "js/CompileOptions.h" so that nothing but that file has to know about these classes having a JS_PUBLIC_API on them, that would have to be present in forward-declarations. --- js/public/CompileOptions.h | 2 ++ js/src/NamespaceImports.h | 4 ---- js/src/builtin/Eval.cpp | 1 + js/src/builtin/ReflectParse.cpp | 1 + js/src/builtin/RegExp.cpp | 1 + js/src/frontend/BytecodeCompiler.cpp | 14 ++++++++------ js/src/frontend/BytecodeCompiler.h | 21 +++++++++++---------- js/src/frontend/BytecodeEmitter.cpp | 5 +++-- js/src/frontend/Parser.cpp | 1 + js/src/frontend/Parser.h | 7 ++++--- js/src/frontend/TokenStream.cpp | 2 +- js/src/frontend/TokenStream.h | 7 ++++--- js/src/gdb/tests/test-unwind.cpp | 20 +++++++++++++------- js/src/jsapi-tests/testCloneScript.cpp | 8 ++++++++ js/src/jsapi.cpp | 3 +++ js/src/jsfun.cpp | 3 +++ js/src/jspubtd.h | 4 ---- js/src/jsscript.cpp | 2 ++ js/src/jsscript.h | 5 +++-- js/src/shell/js.cpp | 3 +++ js/src/vm/Debugger.cpp | 1 + js/src/vm/HelperThreads.cpp | 2 ++ js/src/vm/HelperThreads.h | 11 ++++++----- js/src/vm/RegExpObject.cpp | 1 + js/src/vm/SelfHosting.cpp | 1 + js/src/vm/Xdr.h | 9 +++++---- js/src/wasm/AsmJS.cpp | 2 +- 27 files changed, 89 insertions(+), 52 deletions(-) diff --git a/js/public/CompileOptions.h b/js/public/CompileOptions.h index 39472705fb..cfc2118d5c 100644 --- a/js/public/CompileOptions.h +++ b/js/public/CompileOptions.h @@ -162,6 +162,8 @@ class JS_FRIEND_API(TransitiveCompileOptions) void operator=(const TransitiveCompileOptions&) = delete; }; +class JS_PUBLIC_API(CompileOptions); + /** * The class representing a full set of compile options. * diff --git a/js/src/NamespaceImports.h b/js/src/NamespaceImports.h index ed02054622..fee0284b1c 100644 --- a/js/src/NamespaceImports.h +++ b/js/src/NamespaceImports.h @@ -108,12 +108,8 @@ using JS::GCHashSet; using JS::CallArgs; using JS::CallNonGenericMethod; -using JS::CompileOptions; using JS::IsAcceptableThis; using JS::NativeImpl; -using JS::OwningCompileOptions; -using JS::ReadOnlyCompileOptions; -using JS::TransitiveCompileOptions; using JS::Rooted; using JS::RootedFunction; diff --git a/js/src/builtin/Eval.cpp b/js/src/builtin/Eval.cpp index 7be704d9bc..83ef32f8f6 100644 --- a/js/src/builtin/Eval.cpp +++ b/js/src/builtin/Eval.cpp @@ -26,6 +26,7 @@ using mozilla::HashString; using mozilla::RangedPtr; using JS::AutoCheckCannotGC; +using JS::CompileOptions; using JS::SourceBufferHolder; // We should be able to assert this for *any* fp->environmentChain(). diff --git a/js/src/builtin/ReflectParse.cpp b/js/src/builtin/ReflectParse.cpp index a8dd93aab2..9e16daa3f3 100644 --- a/js/src/builtin/ReflectParse.cpp +++ b/js/src/builtin/ReflectParse.cpp @@ -31,6 +31,7 @@ using namespace js; using namespace js::frontend; using JS::AutoValueArray; +using JS::CompileOptions; using mozilla::ArrayLength; using mozilla::DebugOnly; using mozilla::Forward; diff --git a/js/src/builtin/RegExp.cpp b/js/src/builtin/RegExp.cpp index 61382e6aac..ef5f629249 100644 --- a/js/src/builtin/RegExp.cpp +++ b/js/src/builtin/RegExp.cpp @@ -31,6 +31,7 @@ using mozilla::Maybe; using CapturesVector = GCVector; +using JS::CompileOptions; // Allocate an object for the |.groups| or |.indices.groups| property // of a regexp match result. diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index 2a2c8e0597..f986a4abb2 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -32,6 +32,8 @@ using namespace js::frontend; using mozilla::Maybe; using mozilla::Nothing; +using JS::CompileOptions; +using JS::ReadOnlyCompileOptions; using JS::SourceBufferHolder; class MOZ_STACK_CLASS AutoCompilationTraceLogger @@ -597,7 +599,7 @@ frontend::CompileEvalScript(ExclusiveContext* cx, LifoAlloc& alloc, } ModuleObject* -frontend::CompileModule(ExclusiveContext* cx, const ReadOnlyCompileOptions& optionsInput, +frontend::CompileModule(ExclusiveContext* cx, const JS::ReadOnlyCompileOptions& optionsInput, SourceBufferHolder& srcBuf, LifoAlloc& alloc, ScriptSourceObject** sourceObjectOut /* = nullptr */) { @@ -640,7 +642,7 @@ frontend::CompileLazyFunction(JSContext* cx, Handle lazy, const cha { MOZ_ASSERT(cx->compartment() == lazy->functionNonDelazifying()->compartment()); - CompileOptions options(cx, lazy->version()); + JS::CompileOptions options(cx, lazy->version()); options.setMutedErrors(lazy->mutedErrors()) .setFileAndLine(lazy->filename(), lazy->lineno()) .setColumn(lazy->column()) @@ -706,7 +708,7 @@ frontend::CompileLazyFunction(JSContext* cx, Handle lazy, const cha bool frontend::CompileStandaloneFunction(JSContext* cx, MutableHandleFunction fun, - const ReadOnlyCompileOptions& options, + const JS::ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf, Maybe parameterListEnd, HandleScope enclosingScope /* = nullptr */) @@ -722,7 +724,7 @@ frontend::CompileStandaloneFunction(JSContext* cx, MutableHandleFunction fun, bool frontend::CompileStandaloneGenerator(JSContext* cx, MutableHandleFunction fun, - const ReadOnlyCompileOptions& options, + const JS::ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf, Maybe parameterListEnd) { @@ -735,7 +737,7 @@ frontend::CompileStandaloneGenerator(JSContext* cx, MutableHandleFunction fun, bool frontend::CompileStandaloneAsyncFunction(JSContext* cx, MutableHandleFunction fun, - const ReadOnlyCompileOptions& options, + const JS::ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf, Maybe parameterListEnd) { @@ -748,7 +750,7 @@ frontend::CompileStandaloneAsyncFunction(JSContext* cx, MutableHandleFunction fu bool frontend::CompileStandaloneAsyncGenerator(JSContext* cx, MutableHandleFunction fun, - const ReadOnlyCompileOptions& options, + const JS::ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf, Maybe parameterListEnd) { diff --git a/js/src/frontend/BytecodeCompiler.h b/js/src/frontend/BytecodeCompiler.h index f87e260b1a..439a0175e4 100644 --- a/js/src/frontend/BytecodeCompiler.h +++ b/js/src/frontend/BytecodeCompiler.h @@ -10,6 +10,7 @@ #include "NamespaceImports.h" +#include "js/CompileOptions.h" #include "vm/Scope.h" #include "vm/String.h" @@ -27,7 +28,7 @@ namespace frontend { JSScript* CompileGlobalScript(ExclusiveContext* cx, LifoAlloc& alloc, ScopeKind scopeKind, - const ReadOnlyCompileOptions& options, + const JS::ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf, SourceCompressionTask* extraSct = nullptr, ScriptSourceObject** sourceObjectOut = nullptr); @@ -35,17 +36,17 @@ CompileGlobalScript(ExclusiveContext* cx, LifoAlloc& alloc, ScopeKind scopeKind, JSScript* CompileEvalScript(ExclusiveContext* cx, LifoAlloc& alloc, HandleObject scopeChain, HandleScope enclosingScope, - const ReadOnlyCompileOptions& options, + const JS::ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf, SourceCompressionTask* extraSct = nullptr, ScriptSourceObject** sourceObjectOut = nullptr); ModuleObject* -CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options, +CompileModule(JSContext* cx, const JS::ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf); ModuleObject* -CompileModule(ExclusiveContext* cx, const ReadOnlyCompileOptions& options, +CompileModule(ExclusiveContext* cx, const JS::ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf, LifoAlloc& alloc, ScriptSourceObject** sourceObjectOut = nullptr); @@ -66,36 +67,36 @@ CompileLazyFunction(JSContext* cx, Handle lazy, const char16_t* cha // MOZ_MUST_USE bool CompileStandaloneFunction(JSContext* cx, MutableHandleFunction fun, - const ReadOnlyCompileOptions& options, + const JS::ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf, mozilla::Maybe parameterListEnd, HandleScope enclosingScope = nullptr); MOZ_MUST_USE bool CompileStandaloneGenerator(JSContext* cx, MutableHandleFunction fun, - const ReadOnlyCompileOptions& options, + const JS::ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf, mozilla::Maybe parameterListEnd); MOZ_MUST_USE bool CompileStandaloneAsyncFunction(JSContext* cx, MutableHandleFunction fun, - const ReadOnlyCompileOptions& options, + const JS::ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf, mozilla::Maybe parameterListEnd); MOZ_MUST_USE bool CompileStandaloneAsyncGenerator(JSContext* cx, MutableHandleFunction fun, - const ReadOnlyCompileOptions& options, + const JS::ReadOnlyCompileOptions& options, JS::SourceBufferHolder& srcBuf, mozilla::Maybe parameterListEnd); MOZ_MUST_USE bool CompileAsyncFunctionBody(JSContext* cx, MutableHandleFunction fun, - const ReadOnlyCompileOptions& options, + const JS::ReadOnlyCompileOptions& options, Handle formals, JS::SourceBufferHolder& srcBuf); ScriptSourceObject* -CreateScriptSourceObject(ExclusiveContext* cx, const ReadOnlyCompileOptions& options, +CreateScriptSourceObject(ExclusiveContext* cx, const JS::ReadOnlyCompileOptions& options, mozilla::Maybe parameterListEnd = mozilla::Nothing()); /* diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 7680411f07..27fbfec3a3 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -45,6 +45,7 @@ #include "frontend/TDZCheckCache.h" #include "frontend/TokenStream.h" #include "frontend/TryEmitter.h" +#include "js/CompileOptions.h" #include "vm/Debugger.h" #include "vm/GeneratorObject.h" #include "vm/Stack.h" @@ -5975,8 +5976,8 @@ BytecodeEmitter::emitFunction(FunctionNode* funNode, bool needsProto /* = false Rooted parent(cx, script); MOZ_ASSERT(parent->getVersion() == parser->options().version); MOZ_ASSERT(parent->mutedErrors() == parser->options().mutedErrors()); - const TransitiveCompileOptions& transitiveOptions = parser->options(); - CompileOptions options(cx, transitiveOptions); + const JS::TransitiveCompileOptions& transitiveOptions = parser->options(); + JS::CompileOptions options(cx, transitiveOptions); Rooted sourceObject(cx, script->sourceObject()); Rooted script(cx, JSScript::Create(cx, options, sourceObject, diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 0deed9131e..52b7f298fc 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -56,6 +56,7 @@ using mozilla::PodZero; using mozilla::Some; using JS::AutoGCRooter; +using JS::ReadOnlyCompileOptions; namespace js { namespace frontend { diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h index b1a9bf83c5..6a17f31a32 100644 --- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -22,6 +22,7 @@ #include "frontend/SharedContext.h" #include "frontend/SyntaxParseHandler.h" #include "frontend/TokenStream.h" +#include "js/CompileOptions.h" namespace js { @@ -835,7 +836,7 @@ class ParserBase : public StrictModeGetter return pc->sc()->hasModuleGoal() ? ParseGoal::Module : ParseGoal::Script; } - ParserBase(ExclusiveContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options, + ParserBase(ExclusiveContext* cx, LifoAlloc& alloc, const JS::ReadOnlyCompileOptions& options, const char16_t* chars, size_t length, bool foldConstants, UsedNameTracker& usedNames, Parser* syntaxParser, LazyScript* lazyOuterFunction); @@ -860,7 +861,7 @@ class ParserBase : public StrictModeGetter return pc->sc()->setLocalStrictMode(strict); } - const ReadOnlyCompileOptions& options() const { + const JS::ReadOnlyCompileOptions& options() const { return tokenStream.options(); } @@ -1081,7 +1082,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) void freeTree(Node node) { handler.freeTree(node); } public: - Parser(ExclusiveContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options, + Parser(ExclusiveContext* cx, LifoAlloc& alloc, const JS::ReadOnlyCompileOptions& options, const char16_t* chars, size_t length, bool foldConstants, UsedNameTracker& usedNames, Parser* syntaxParser, LazyScript* lazyOuterFunction); ~Parser(); diff --git a/js/src/frontend/TokenStream.cpp b/js/src/frontend/TokenStream.cpp index 5402727cc7..15215bdca1 100644 --- a/js/src/frontend/TokenStream.cpp +++ b/js/src/frontend/TokenStream.cpp @@ -469,7 +469,7 @@ TokenStream::SourceCoords::lineNumAndColumnIndex(uint32_t offset, uint32_t* line #pragma warning(disable:4351) #endif -TokenStream::TokenStream(ExclusiveContext* cx, const ReadOnlyCompileOptions& options, +TokenStream::TokenStream(ExclusiveContext* cx, const JS::ReadOnlyCompileOptions& options, const char16_t* base, size_t length, StrictModeGetter* smg) : srcCoords(cx, options.lineno), options_(options), diff --git a/js/src/frontend/TokenStream.h b/js/src/frontend/TokenStream.h index 3d4695fdea..6382c220ac 100644 --- a/js/src/frontend/TokenStream.h +++ b/js/src/frontend/TokenStream.h @@ -22,6 +22,7 @@ #include "jspubtd.h" #include "frontend/TokenKind.h" +#include "js/CompileOptions.h" #include "js/UniquePtr.h" #include "js/Vector.h" #include "vm/RegExpObject.h" @@ -323,7 +324,7 @@ class MOZ_STACK_CLASS TokenStream public: typedef Vector CharBuffer; - TokenStream(ExclusiveContext* cx, const ReadOnlyCompileOptions& options, + TokenStream(ExclusiveContext* cx, const JS::ReadOnlyCompileOptions& options, const char16_t* base, size_t length, StrictModeGetter* smg); ~TokenStream(); @@ -864,7 +865,7 @@ class MOZ_STACK_CLASS TokenStream return cx; } - const ReadOnlyCompileOptions& options() const { + const JS::ReadOnlyCompileOptions& options() const { return options_; } @@ -1041,7 +1042,7 @@ class MOZ_STACK_CLASS TokenStream bool hasLookahead() const { return lookahead > 0; } // Options used for parsing/tokenizing. - const ReadOnlyCompileOptions& options_; + const JS::ReadOnlyCompileOptions& options_; Token tokens[ntokens]; // circular token buffer unsigned cursor; // index of last parsed token diff --git a/js/src/gdb/tests/test-unwind.cpp b/js/src/gdb/tests/test-unwind.cpp index 6c8b7b86ab..9af66692be 100644 --- a/js/src/gdb/tests/test-unwind.cpp +++ b/js/src/gdb/tests/test-unwind.cpp @@ -1,13 +1,19 @@ #include "gdb-tests.h" -#include "jsapi.h" -#include "jit/JitOptions.h" +#include "jsapi.h" // sundry symbols not moved to more-specific headers yet -#include +#include "jit/JitOptions.h" // js::jit::JitOptions +#include "js/CallArgs.h" // JS::CallArgs, JS::CallArgsFromVp +#include "js/CompileOptions.h" // JS::CompileOptions +#include "js/RootingAPI.h" // JS::Rooted +#include "js/Value.h" // JS::Value + +#include // uint32_t +#include // strlen static bool Something(JSContext* cx, unsigned argc, JS::Value* vp) { - JS::CallArgs args = CallArgsFromVp(argc, vp); + JS::CallArgs args = JS::CallArgsFromVp(argc, vp); args.rval().setInt32(23); breakpoint(); return true; @@ -43,10 +49,10 @@ FRAGMENT(unwind, simple) { "\n" "unwindFunctionOuter();\n"; - CompileOptions opts(cx); + JS::CompileOptions opts(cx); opts.setFileAndLine(__FILE__, line0 + 1); - RootedValue rval(cx); - Evaluate(cx, opts, bytes, strlen(bytes), &rval); + JS::RootedValue rval(cx); + JS::Evaluate(cx, opts, bytes, strlen(bytes), &rval); js::jit::JitOptions.baselineWarmUpThreshold = saveThreshold; } diff --git a/js/src/jsapi-tests/testCloneScript.cpp b/js/src/jsapi-tests/testCloneScript.cpp index 9718814553..877294e9a3 100644 --- a/js/src/jsapi-tests/testCloneScript.cpp +++ b/js/src/jsapi-tests/testCloneScript.cpp @@ -6,7 +6,15 @@ * 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/. */ +#include // strlen + +#include "jsapi.h" // sundry symbols not moved to more-specific headers yet #include "jsfriendapi.h" +#include "jspubtd.h" // JS::AutoObjectVector + +#include "js/CompileOptions.h" // JS::CompileOptions +#include "js/RootingAPI.h" // JS::Rooted +#include "js/TypeDecls.h" // JSFunction, JSObject #include "jsapi-tests/tests.h" BEGIN_TEST(test_cloneScript) diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 2bea8b8be7..f1627e481e 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -58,6 +58,7 @@ #include "gc/Policy.h" #include "jit/JitCommon.h" #include "js/CharacterEncoding.h" +#include "js/CompileOptions.h" #include "js/Conversions.h" #include "js/Date.h" #include "js/Initialization.h" @@ -107,6 +108,8 @@ using mozilla::PodZero; using mozilla::Some; using JS::AutoGCRooter; +using JS::CompileOptions; +using JS::ReadOnlyCompileOptions; using JS::SourceBufferHolder; using JS::ToInt32; using JS::ToInteger; diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 9d2a819ca6..d4a33549ab 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -38,6 +38,7 @@ #include "jit/Ion.h" #include "jit/JitFrameIterator.h" #include "js/CallNonGenericMethod.h" +#include "js/CompileOptions.h" #include "js/Proxy.h" #include "js/SourceBufferHolder.h" #include "vm/AsyncFunction.h" @@ -68,7 +69,9 @@ using mozilla::PodCopy; using mozilla::RangedPtr; using mozilla::Some; +using JS::CompileOptions; using JS::SourceBufferHolder; + static bool fun_enumerate(JSContext* cx, HandleObject obj) { diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index 21318af6c9..d956ae4bd9 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -34,10 +34,6 @@ class CallArgs; template class Rooted; -class JS_PUBLIC_API(CompileOptions); -class JS_PUBLIC_API(ReadOnlyCompileOptions); -class JS_PUBLIC_API(OwningCompileOptions); -class JS_PUBLIC_API(TransitiveCompileOptions); class JS_PUBLIC_API(CompartmentOptions); struct RootingContext; diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 0fcdb57eb8..ca51bb1b19 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -69,6 +69,8 @@ using mozilla::PodCopy; using mozilla::PodZero; using mozilla::RotateLeft; +using JS::CompileOptions; +using JS::ReadOnlyCompileOptions; using JS::SourceBufferHolder; template diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 41d8e18ee0..9cfebe68cb 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -22,6 +22,7 @@ #include "gc/Barrier.h" #include "gc/Rooting.h" #include "jit/IonCode.h" +#include "js/CompileOptions.h" #include "js/UbiNode.h" #include "js/UniquePtr.h" #include "vm/NativeObject.h" @@ -473,7 +474,7 @@ class ScriptSource if (--refs == 0) js_delete(this); } - bool initFromOptions(ExclusiveContext* cx, const ReadOnlyCompileOptions& options, + bool initFromOptions(ExclusiveContext* cx, const JS::ReadOnlyCompileOptions& options, mozilla::Maybe parameterListEnd = mozilla::Nothing()); bool setSourceCopy(ExclusiveContext* cx, JS::SourceBufferHolder& srcBuf, @@ -655,7 +656,7 @@ class ScriptSourceObject : public NativeObject // Initialize those properties of this ScriptSourceObject whose values // are provided by |options|, re-wrapping as necessary. static bool initFromOptions(JSContext* cx, HandleScriptSource source, - const ReadOnlyCompileOptions& options); + const JS::ReadOnlyCompileOptions& options); ScriptSource* source() const { return static_cast(getReservedSlot(SOURCE_SLOT).toPrivate()); diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index d4e0a5065e..387c78849f 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -70,6 +70,7 @@ #include "jit/Ion.h" #include "jit/JitcodeMap.h" #include "jit/OptimizationTracking.h" +#include "js/CompileOptions.h" #include "js/Debug.h" #include "js/Equality.h" // JS::SameValue #include "js/GCAPI.h" @@ -111,6 +112,8 @@ using namespace js; using namespace js::cli; using namespace js::shell; +using JS::CompileOptions; + using mozilla::ArrayLength; using mozilla::Atomic; using mozilla::MakeScopeExit; diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index e1416a8908..d76efe65c0 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -49,6 +49,7 @@ using namespace js; +using JS::CompileOptions; using JS::dbg::AutoEntryMonitor; using JS::dbg::Builder; using js::frontend::IsIdentifier; diff --git a/js/src/vm/HelperThreads.cpp b/js/src/vm/HelperThreads.cpp index 488522c987..b264b3bb9c 100644 --- a/js/src/vm/HelperThreads.cpp +++ b/js/src/vm/HelperThreads.cpp @@ -34,6 +34,8 @@ using mozilla::DebugOnly; using mozilla::Unused; using mozilla::TimeDuration; +using JS::CompileOptions; +using JS::ReadOnlyCompileOptions; using JS::SourceBufferHolder; namespace js { diff --git a/js/src/vm/HelperThreads.h b/js/src/vm/HelperThreads.h index 48c638e34e..ebd4c9b9cb 100644 --- a/js/src/vm/HelperThreads.h +++ b/js/src/vm/HelperThreads.h @@ -21,6 +21,7 @@ #include "frontend/TokenStream.h" #include "jit/Ion.h" +#include "js/CompileOptions.h" #include "js/SourceBufferHolder.h" #include "threading/ConditionVariable.h" #include "vm/MutexIDs.h" @@ -476,17 +477,17 @@ CancelOffThreadParses(JSRuntime* runtime); * alive until the compilation finishes. */ bool -StartOffThreadParseScript(JSContext* cx, const ReadOnlyCompileOptions& options, +StartOffThreadParseScript(JSContext* cx, const JS::ReadOnlyCompileOptions& options, const char16_t* chars, size_t length, JS::OffThreadCompileCallback callback, void* callbackData); bool -StartOffThreadParseModule(JSContext* cx, const ReadOnlyCompileOptions& options, +StartOffThreadParseModule(JSContext* cx, const JS::ReadOnlyCompileOptions& options, const char16_t* chars, size_t length, JS::OffThreadCompileCallback callback, void* callbackData); bool -StartOffThreadDecodeScript(JSContext* cx, const ReadOnlyCompileOptions& options, +StartOffThreadDecodeScript(JSContext* cx, const JS::ReadOnlyCompileOptions& options, JS::TranscodeBuffer& buffer, size_t cursor, JS::OffThreadCompileCallback callback, void* callbackData); @@ -541,7 +542,7 @@ struct ParseTask { ParseTaskKind kind; ExclusiveContext* cx; - OwningCompileOptions options; + JS::OwningCompileOptions options; // Anonymous union, the only correct interpretation is provided by the // ParseTaskKind value, or from the virtual parse function. union { @@ -586,7 +587,7 @@ struct ParseTask ParseTask(ParseTaskKind kind, ExclusiveContext* cx, JSObject* exclusiveContextGlobal, JSContext* initCx, JS::TranscodeBuffer& buffer, size_t cursor, JS::OffThreadCompileCallback callback, void* callbackData); - bool init(JSContext* cx, const ReadOnlyCompileOptions& options); + bool init(JSContext* cx, const JS::ReadOnlyCompileOptions& options); void activate(JSRuntime* rt); virtual void parse() = 0; diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp index c4493de28e..cc5fc98593 100644 --- a/js/src/vm/RegExpObject.cpp +++ b/js/src/vm/RegExpObject.cpp @@ -42,6 +42,7 @@ using mozilla::DebugOnly; using mozilla::Maybe; using mozilla::PodCopy; using js::frontend::TokenStream; +using JS::CompileOptions; using JS::AutoCheckCannotGC; diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index e006846752..c9f290463e 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -69,6 +69,7 @@ using namespace js; using namespace js::selfhosted; using JS::AutoCheckCannotGC; +using JS::CompileOptions; using mozilla::IsInRange; using mozilla::Maybe; using mozilla::PodMove; diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h index 483a9aeabc..e0fe0ced45 100644 --- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -9,6 +9,7 @@ #include "mozilla/EndianUtils.h" #include "mozilla/TypeTraits.h" +#include "js/CompileOptions.h" #include "js/Transcoding.h" #include "jsatom.h" #include "jsfriendapi.h" @@ -143,7 +144,7 @@ class XDRState : public XDRCoderBase virtual LifoAlloc& lifoAlloc() const; virtual bool hasOptions() const { return false; } - virtual const ReadOnlyCompileOptions& options() { + virtual const JS::ReadOnlyCompileOptions& options() { MOZ_CRASH("does not have options"); } virtual bool hasScriptSourceObjectOut() const { return false; } @@ -307,7 +308,7 @@ using XDRDecoder = XDRState; class XDROffThreadDecoder : public XDRDecoder { - const ReadOnlyCompileOptions* options_; + const JS::ReadOnlyCompileOptions* options_; ScriptSourceObject** sourceObjectOut_; LifoAlloc& alloc_; @@ -321,7 +322,7 @@ class XDROffThreadDecoder : public XDRDecoder // When providing a sourceObjectOut pointer, you have to ensure that it is // marked by the GC to avoid dangling pointers. XDROffThreadDecoder(ExclusiveContext* cx, LifoAlloc& alloc, - const ReadOnlyCompileOptions* options, + const JS::ReadOnlyCompileOptions* options, ScriptSourceObject** sourceObjectOut, JS::TranscodeBuffer& buffer, size_t cursor = 0) : XDRDecoder(cx, buffer, cursor), @@ -339,7 +340,7 @@ class XDROffThreadDecoder : public XDRDecoder } bool hasOptions() const override { return true; } - const ReadOnlyCompileOptions& options() override { + const JS::ReadOnlyCompileOptions& options() override { return *options_; } bool hasScriptSourceObjectOut() const override { return true; } diff --git a/js/src/wasm/AsmJS.cpp b/js/src/wasm/AsmJS.cpp index e7c956d972..fc0584c327 100644 --- a/js/src/wasm/AsmJS.cpp +++ b/js/src/wasm/AsmJS.cpp @@ -6319,7 +6319,7 @@ HandleInstantiationFailure(JSContext* cx, CallArgs args, const AsmJSMetadata& me if (!fun) return false; - CompileOptions options(cx); + JS::CompileOptions options(cx); options.setMutedErrors(source->mutedErrors()) .setFile(source->filename()) .setNoScriptRval(false); From d9c27beb515a1b6c3118b7cf96841a5214da018b Mon Sep 17 00:00:00 2001 From: Shadow Date: Thu, 13 Mar 2025 13:15:41 +0000 Subject: [PATCH 8/8] No Issue - Stop warning if a network request failed. Bug 1286036 --- netwerk/protocol/http/nsCORSListenerProxy.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/netwerk/protocol/http/nsCORSListenerProxy.cpp b/netwerk/protocol/http/nsCORSListenerProxy.cpp index 8d4cd487ba..add904092a 100644 --- a/netwerk/protocol/http/nsCORSListenerProxy.cpp +++ b/netwerk/protocol/http/nsCORSListenerProxy.cpp @@ -556,8 +556,13 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest) // Check if the request failed nsresult status; nsresult rv = aRequest->GetStatus(&status); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_SUCCESS(status, status); + if (NS_FAILED(rv)) { + return rv; + } + + if (NS_FAILED(status)) { + return status; + } // Test that things worked on a HTTP level nsCOMPtr http = do_QueryInterface(aRequest);