Merge remote-tracking branch 'origin/tracking' into custom

This commit is contained in:
roytam1 2025-03-13 23:05:24 +08:00
commit 2a53c574f6
49 changed files with 1080 additions and 850 deletions

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -24,6 +24,7 @@
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/SourceBufferHolder.h"
#include "nsError.h"
#include "nsContentPolicyUtils.h"
#include "nsContentUtils.h"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -15,6 +15,7 @@
#include "base/basictypes.h"
#include "jsapi.h"
#include "js/SourceBufferHolder.h"
#include "xpcpublic.h"

View file

@ -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 <stddef.h> // size_t
#include <stdio.h> // 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<GCVector<JSObject*, 8>> {
using Vec = GCVector<JSObject*, 8>;
using Base = Rooted<Vec>;
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<JSObject*> 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<JSScript*> 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 */

403
js/public/CompileOptions.h Normal file
View file

@ -0,0 +1,403 @@
/* -*- 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 <stddef.h> // size_t
#include <stdint.h> // 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;
};
class JS_PUBLIC_API(CompileOptions);
/**
* 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 */

View file

@ -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 <stddef.h> // 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<uint8_t>& 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 */

View file

@ -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<char16_t*>(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 <stddef.h> // 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<char16_t*>(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<char16_t*>(data_);
}
private:
SourceBufferHolder(SourceBufferHolder&) = delete;
SourceBufferHolder& operator=(SourceBufferHolder&) = delete;
const char16_t* data_;
size_t length_;
bool ownsChars_;
};
} // namespace JS
#endif /* js_SourceBufferHolder_h */

85
js/public/Transcoding.h Normal file
View file

@ -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 <stddef.h> // size_t
#include <stdint.h> // 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<uint8_t> TranscodeBuffer;
using TranscodeBuffer = mozilla::Vector<uint8_t>;
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 */

View file

@ -108,13 +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::SourceBufferHolder;
using JS::TransitiveCompileOptions;
using JS::Rooted;
using JS::RootedFunction;

View file

@ -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,8 @@ 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().
static void

View file

@ -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;

View file

@ -31,6 +31,7 @@ using mozilla::Maybe;
using CapturesVector = GCVector<Value, 4>;
using JS::CompileOptions;
// Allocate an object for the |.groups| or |.indices.groups| property
// of a regexp match result.

View file

@ -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,14 @@
using namespace js;
using namespace js::frontend;
using mozilla::Maybe;
using mozilla::Nothing;
using JS::CompileOptions;
using JS::ReadOnlyCompileOptions;
using JS::SourceBufferHolder;
class MOZ_STACK_CLASS AutoCompilationTraceLogger
{
public:
@ -593,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 */)
{
@ -636,7 +642,7 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> 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())
@ -702,7 +708,7 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha
bool
frontend::CompileStandaloneFunction(JSContext* cx, MutableHandleFunction fun,
const ReadOnlyCompileOptions& options,
const JS::ReadOnlyCompileOptions& options,
JS::SourceBufferHolder& srcBuf,
Maybe<uint32_t> parameterListEnd,
HandleScope enclosingScope /* = nullptr */)
@ -718,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<uint32_t> parameterListEnd)
{
@ -731,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<uint32_t> parameterListEnd)
{
@ -744,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<uint32_t> parameterListEnd)
{

View file

@ -10,6 +10,7 @@
#include "NamespaceImports.h"
#include "js/CompileOptions.h"
#include "vm/Scope.h"
#include "vm/String.h"
@ -27,26 +28,26 @@ namespace frontend {
JSScript*
CompileGlobalScript(ExclusiveContext* cx, LifoAlloc& alloc, ScopeKind scopeKind,
const ReadOnlyCompileOptions& options,
SourceBufferHolder& srcBuf,
const JS::ReadOnlyCompileOptions& options,
JS::SourceBufferHolder& srcBuf,
SourceCompressionTask* extraSct = nullptr,
ScriptSourceObject** sourceObjectOut = nullptr);
JSScript*
CompileEvalScript(ExclusiveContext* cx, LifoAlloc& alloc,
HandleObject scopeChain, HandleScope enclosingScope,
const ReadOnlyCompileOptions& options,
SourceBufferHolder& srcBuf,
const JS::ReadOnlyCompileOptions& options,
JS::SourceBufferHolder& srcBuf,
SourceCompressionTask* extraSct = nullptr,
ScriptSourceObject** sourceObjectOut = nullptr);
ModuleObject*
CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
SourceBufferHolder& srcBuf);
CompileModule(JSContext* cx, const JS::ReadOnlyCompileOptions& options,
JS::SourceBufferHolder& srcBuf);
ModuleObject*
CompileModule(ExclusiveContext* cx, const ReadOnlyCompileOptions& options,
SourceBufferHolder& srcBuf, LifoAlloc& alloc,
CompileModule(ExclusiveContext* cx, const JS::ReadOnlyCompileOptions& options,
JS::SourceBufferHolder& srcBuf, LifoAlloc& alloc,
ScriptSourceObject** sourceObjectOut = nullptr);
MOZ_MUST_USE bool
@ -66,36 +67,36 @@ CompileLazyFunction(JSContext* cx, Handle<LazyScript*> 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<uint32_t> 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<uint32_t> parameterListEnd);
MOZ_MUST_USE bool
CompileStandaloneAsyncFunction(JSContext* cx, MutableHandleFunction fun,
const ReadOnlyCompileOptions& options,
const JS::ReadOnlyCompileOptions& options,
JS::SourceBufferHolder& srcBuf,
mozilla::Maybe<uint32_t> parameterListEnd);
MOZ_MUST_USE bool
CompileStandaloneAsyncGenerator(JSContext* cx, MutableHandleFunction fun,
const ReadOnlyCompileOptions& options,
const JS::ReadOnlyCompileOptions& options,
JS::SourceBufferHolder& srcBuf,
mozilla::Maybe<uint32_t> parameterListEnd);
MOZ_MUST_USE bool
CompileAsyncFunctionBody(JSContext* cx, MutableHandleFunction fun,
const ReadOnlyCompileOptions& options,
const JS::ReadOnlyCompileOptions& options,
Handle<PropertyNameVector> formals, JS::SourceBufferHolder& srcBuf);
ScriptSourceObject*
CreateScriptSourceObject(ExclusiveContext* cx, const ReadOnlyCompileOptions& options,
CreateScriptSourceObject(ExclusiveContext* cx, const JS::ReadOnlyCompileOptions& options,
mozilla::Maybe<uint32_t> parameterListEnd = mozilla::Nothing());
/*

View file

@ -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<JSScript*> 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<JSObject*> sourceObject(cx, script->sourceObject());
Rooted<JSScript*> script(cx, JSScript::Create(cx, options, sourceObject,

View file

@ -56,6 +56,7 @@ using mozilla::PodZero;
using mozilla::Some;
using JS::AutoGCRooter;
using JS::ReadOnlyCompileOptions;
namespace js {
namespace frontend {

View file

@ -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<SyntaxParseHandler>* 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<SyntaxParseHandler>* syntaxParser, LazyScript* lazyOuterFunction);
~Parser();

View file

@ -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),

View file

@ -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<char16_t, 32> 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

View file

@ -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 <string.h>
#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 <stdint.h> // uint32_t
#include <string.h> // 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;
}

View file

@ -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 <string.h> // 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)

View file

@ -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;

View file

@ -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)

View file

@ -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 {

View file

@ -58,11 +58,13 @@
#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"
#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 +108,9 @@ using mozilla::PodZero;
using mozilla::Some;
using JS::AutoGCRooter;
using JS::CompileOptions;
using JS::ReadOnlyCompileOptions;
using JS::SourceBufferHolder;
using JS::ToInt32;
using JS::ToInteger;
using JS::ToUint32;

View file

@ -29,14 +29,18 @@
#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"
#include "js/Id.h"
#include "js/OffThreadScriptCompilation.h"
#include "js/Principals.h"
#include "js/Realm.h"
#include "js/RootingAPI.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"
@ -238,14 +242,6 @@ class AutoIdVector : public Rooted<GCVector<jsid, 8>> {
bool appendAll(const AutoIdVector& other) { return this->Base::appendAll(other.get()); }
};
class AutoObjectVector : public Rooted<GCVector<JSObject*, 8>> {
using Vec = GCVector<JSObject*, 8>;
using Base = Rooted<Vec>;
public:
explicit AutoObjectVector(JSContext* cx) : Base(cx, Vec(cx)) {}
explicit AutoObjectVector(js::ContextFriendFields* cx) : Base(cx, Vec(cx)) {}
};
using ValueVector = JS::GCVector<JS::Value>;
using IdVector = JS::GCVector<jsid>;
using ScriptVector = JS::GCVector<JSScript*>;
@ -750,102 +746,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<char16_t*>(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<char16_t*>(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<char16_t*>(data_);
}
private:
SourceBufferHolder(SourceBufferHolder&) = delete;
SourceBufferHolder& operator=(SourceBufferHolder&) = delete;
const char16_t* data_;
size_t length_;
bool ownsChars_;
};
} /* namespace JS */
/************************************************************************/
@ -3687,32 +3587,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<JSObject*> 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);
@ -3726,511 +3601,6 @@ JS_GetScriptBaseLineNumber(JSContext* cx, JSScript* script);
extern JS_PUBLIC_API(JSScript*)
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.
*/
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);
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<uint8_t>& 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
* 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<JSScript*> script);
@ -4238,104 +3608,8 @@ extern JS_PUBLIC_API(JSString*)
JS_DecompileFunction(JSContext* cx, JS::Handle<JSFunction*> 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<JSScript*> 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);
/**
@ -6178,63 +5452,6 @@ class MOZ_RAII AutoHideScriptedCaller
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
/*
* Encode/Decode interpreted scripts and functions to/from memory.
*/
typedef mozilla::Vector<uint8_t> 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 {

View file

@ -38,7 +38,9 @@
#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"
#include "vm/AsyncIteration.h"
#include "vm/Debugger.h"
@ -67,6 +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)
{

View file

@ -34,10 +34,6 @@ class CallArgs;
template <typename T>
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(CompartmentOptions);
struct RootingContext;
@ -150,8 +146,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()

View file

@ -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,10 @@ using mozilla::PodCopy;
using mozilla::PodZero;
using mozilla::RotateLeft;
using JS::CompileOptions;
using JS::ReadOnlyCompileOptions;
using JS::SourceBufferHolder;
template<XDRMode mode>
bool
js::XDRScriptConst(XDRState<mode>* xdr, MutableHandleValue vp)

View file

@ -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<uint32_t> 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<ScriptSource*>(getReservedSlot(SOURCE_SLOT).toPrivate());

View file

@ -67,6 +67,8 @@ EXPORTS.js += [
'../public/CallNonGenericMethod.h',
'../public/CharacterEncoding.h',
'../public/Class.h',
'../public/CompilationAndEvaluation.h',
'../public/CompileOptions.h',
'../public/Conversions.h',
'../public/Date.h',
'../public/Debug.h',
@ -83,6 +85,7 @@ EXPORTS.js += [
'../public/Initialization.h',
'../public/LegacyIntTypes.h',
'../public/MemoryMetrics.h',
'../public/OffThreadScriptCompilation.h',
'../public/Principals.h',
'../public/ProfilingFrameIterator.h',
'../public/ProfilingStack.h',
@ -92,12 +95,14 @@ EXPORTS.js += [
'../public/Result.h',
'../public/RootingAPI.h',
'../public/SliceBudget.h',
'../public/SourceBufferHolder.h',
'../public/Stream.h',
'../public/StructuredClone.h',
'../public/SweepingAPI.h',
'../public/TraceKind.h',
'../public/TracingAPI.h',
'../public/TrackedOptimizationInfo.h',
'../public/Transcoding.h',
'../public/TypeDecls.h',
'../public/UbiNode.h',
'../public/UbiNodeBreadthFirst.h',

View file

@ -70,10 +70,12 @@
#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"
#include "js/Initialization.h"
#include "js/SourceBufferHolder.h"
#include "js/StructuredClone.h"
#include "js/TrackedOptimizationInfo.h"
#include "perf/jsperf.h"
@ -110,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;
@ -4062,8 +4066,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)

View file

@ -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"
@ -48,9 +49,11 @@
using namespace js;
using JS::CompileOptions;
using JS::dbg::AutoEntryMonitor;
using JS::dbg::Builder;
using js::frontend::IsIdentifier;
using JS::SourceBufferHolder;
using mozilla::ArrayLength;
using mozilla::DebugOnly;
using mozilla::MakeScopeExit;

View file

@ -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,10 @@ using mozilla::DebugOnly;
using mozilla::Unused;
using mozilla::TimeDuration;
using JS::CompileOptions;
using JS::ReadOnlyCompileOptions;
using JS::SourceBufferHolder;
namespace js {
GlobalHelperThreadState* gHelperThreadState = nullptr;

View file

@ -21,6 +21,8 @@
#include "frontend/TokenStream.h"
#include "jit/Ion.h"
#include "js/CompileOptions.h"
#include "js/SourceBufferHolder.h"
#include "threading/ConditionVariable.h"
#include "vm/MutexIDs.h"
@ -475,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);
@ -540,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 {
@ -585,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;

View file

@ -42,6 +42,7 @@ using mozilla::DebugOnly;
using mozilla::Maybe;
using mozilla::PodCopy;
using js::frontend::TokenStream;
using JS::CompileOptions;
using JS::AutoCheckCannotGC;

View file

@ -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;

View file

@ -9,6 +9,8 @@
#include "mozilla/EndianUtils.h"
#include "mozilla/TypeTraits.h"
#include "js/CompileOptions.h"
#include "js/Transcoding.h"
#include "jsatom.h"
#include "jsfriendapi.h"
@ -142,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; }
@ -306,7 +308,7 @@ using XDRDecoder = XDRState<XDR_DECODE>;
class XDROffThreadDecoder : public XDRDecoder
{
const ReadOnlyCompileOptions* options_;
const JS::ReadOnlyCompileOptions* options_;
ScriptSourceObject** sourceObjectOut_;
LifoAlloc& alloc_;
@ -320,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),
@ -338,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; }

View file

@ -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;
/*****************************************************************************/
@ -6317,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);

View file

@ -17,6 +17,7 @@
#endif
#include "jsapi.h"
#include "js/SourceBufferHolder.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsIComponentManager.h"

View file

@ -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"

View file

@ -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"

View file

@ -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<nsIHttpChannel> http = do_QueryInterface(aRequest);