mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Bug 1512509 - Clone ScriptSourceObject when cloning scripts. r=tcampbell
This fixes bug 1406437. It also simplifies JSScript because it now always stores a ScriptSourceObject directly instead of a CCW for one. Differential Revision: https://phabricator.services.mozilla.com/D13974 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
a8df58f265
commit
100a324c5b
@ -806,7 +806,7 @@ void ModuleObject::init(HandleScript script) {
|
||||
initReservedSlot(ScriptSlot, PrivateGCThingValue(script));
|
||||
initReservedSlot(StatusSlot, Int32Value(MODULE_STATUS_UNINSTANTIATED));
|
||||
initReservedSlot(ScriptSourceObjectSlot,
|
||||
ObjectValue(script->scriptSourceUnwrap()));
|
||||
ObjectValue(*script->sourceObject()));
|
||||
}
|
||||
|
||||
void ModuleObject::setInitialEnvironment(
|
||||
|
@ -5527,7 +5527,7 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitFunction(CodeNode* funNode,
|
||||
const JS::TransitiveCompileOptions& transitiveOptions = parser->options();
|
||||
JS::CompileOptions options(cx, transitiveOptions);
|
||||
|
||||
Rooted<JSObject*> sourceObject(cx, script->sourceObject());
|
||||
Rooted<ScriptSourceObject*> sourceObject(cx, script->sourceObject());
|
||||
Rooted<JSScript*> script(
|
||||
cx, JSScript::Create(cx, options, sourceObject, funbox->bufStart,
|
||||
funbox->bufEnd, funbox->toStringStart,
|
||||
|
6
js/src/jit-test/tests/debug/bug1406437.js
Normal file
6
js/src/jit-test/tests/debug/bug1406437.js
Normal file
@ -0,0 +1,6 @@
|
||||
var g = newGlobal();
|
||||
g.f = function() {};
|
||||
g.eval('f = clone(f);');
|
||||
var dbg = new Debugger;
|
||||
var dg = dbg.addDebuggee(g);
|
||||
dg.getOwnPropertyDescriptor('f').value.script.source;
|
@ -3740,16 +3740,16 @@ JS_PUBLIC_API void JS::SetModulePrivate(JSObject* module,
|
||||
}
|
||||
|
||||
JS_PUBLIC_API JS::Value JS::GetModulePrivate(JSObject* module) {
|
||||
return module->as<ModuleObject>().scriptSourceObject()->getPrivate();
|
||||
return module->as<ModuleObject>().scriptSourceObject()->unwrappedPrivate();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API void JS::SetScriptPrivate(JSScript* script,
|
||||
const JS::Value& value) {
|
||||
script->scriptSourceUnwrap().setPrivate(value);
|
||||
script->sourceObject()->setPrivate(value);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API JS::Value JS::GetScriptPrivate(JSScript* script) {
|
||||
return script->scriptSourceUnwrap().getPrivate();
|
||||
return script->sourceObject()->unwrappedPrivate();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API bool JS::ModuleInstantiate(JSContext* cx,
|
||||
|
@ -536,9 +536,9 @@ JS_FRIEND_API bool js::NukeCrossCompartmentWrappers(
|
||||
continue;
|
||||
}
|
||||
|
||||
// We never nuke script source objects, since only ever used internally by
|
||||
// the JS engine, and are expected to remain valid throughout a scripts
|
||||
// lifetime.
|
||||
// We never nuke ScriptSourceObjects, since they are only ever used
|
||||
// internally by the JS engine, and are expected to remain valid
|
||||
// throughout a script's lifetime.
|
||||
if (MOZ_UNLIKELY(wrapped->is<ScriptSourceObject>())) {
|
||||
continue;
|
||||
}
|
||||
|
@ -7795,7 +7795,7 @@ static bool DebuggerSource_getDisplayURL(JSContext* cx, unsigned argc,
|
||||
struct DebuggerSourceGetElementMatcher {
|
||||
using ReturnType = JSObject*;
|
||||
ReturnType match(HandleScriptSourceObject sourceObject) {
|
||||
return sourceObject->element();
|
||||
return sourceObject->unwrappedElement();
|
||||
}
|
||||
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) { return nullptr; }
|
||||
};
|
||||
@ -7818,7 +7818,7 @@ static bool DebuggerSource_getElement(JSContext* cx, unsigned argc, Value* vp) {
|
||||
struct DebuggerSourceGetElementPropertyMatcher {
|
||||
using ReturnType = Value;
|
||||
ReturnType match(HandleScriptSourceObject sourceObject) {
|
||||
return sourceObject->elementAttributeName();
|
||||
return sourceObject->unwrappedElementAttributeName();
|
||||
}
|
||||
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
|
||||
return UndefinedValue();
|
||||
@ -7847,7 +7847,7 @@ class DebuggerSourceGetIntroductionScriptMatcher {
|
||||
using ReturnType = bool;
|
||||
|
||||
ReturnType match(HandleScriptSourceObject sourceObject) {
|
||||
RootedScript script(cx_, sourceObject->introductionScript());
|
||||
RootedScript script(cx_, sourceObject->unwrappedIntroductionScript());
|
||||
if (script) {
|
||||
RootedObject scriptDO(cx_, dbg_->wrapScript(cx_, script));
|
||||
if (!scriptDO) {
|
||||
@ -7886,7 +7886,8 @@ struct DebuggerGetIntroductionOffsetMatcher {
|
||||
// ScriptSource, only hand out the introduction offset if we also have
|
||||
// the script within which it applies.
|
||||
ScriptSource* ss = sourceObject->source();
|
||||
if (ss->hasIntroductionOffset() && sourceObject->introductionScript()) {
|
||||
if (ss->hasIntroductionOffset() &&
|
||||
sourceObject->unwrappedIntroductionScript()) {
|
||||
return Int32Value(ss->introductionOffset());
|
||||
}
|
||||
return UndefinedValue();
|
||||
|
@ -3365,14 +3365,14 @@ ModuleObject* js::GetModuleObjectForScript(JSScript* script) {
|
||||
|
||||
Value js::FindScriptOrModulePrivateForScript(JSScript* script) {
|
||||
while (script) {
|
||||
ScriptSourceObject* sso = &script->scriptSourceUnwrap();
|
||||
Value value = sso->getPrivate();
|
||||
ScriptSourceObject* sso = script->sourceObject();
|
||||
Value value = sso->unwrappedPrivate();
|
||||
if (!value.isUndefined()) {
|
||||
return value;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(sso->introductionScript() != script);
|
||||
script = sso->introductionScript();
|
||||
MOZ_ASSERT(sso->unwrappedIntroductionScript() != script);
|
||||
script = sso->unwrappedIntroductionScript();
|
||||
}
|
||||
|
||||
return UndefinedValue();
|
||||
|
@ -305,7 +305,7 @@ static XDRResult XDRRelazificationInfo(XDRState<mode>* xdr, HandleFunction fun,
|
||||
MOZ_TRY(xdr->codeUint64(&packedFields));
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
RootedScriptSourceObject sourceObject(cx, &script->scriptSourceUnwrap());
|
||||
RootedScriptSourceObject sourceObject(cx, script->sourceObject());
|
||||
lazy.set(LazyScript::CreateForXDR(
|
||||
cx, fun, script, enclosingScope, sourceObject, packedFields,
|
||||
sourceStart, sourceEnd, toStringStart, lineno, column));
|
||||
@ -528,9 +528,7 @@ XDRResult js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope,
|
||||
fun->initScript(script);
|
||||
}
|
||||
} else {
|
||||
// When encoding, we do not mutate any of the JSScript or LazyScript, so
|
||||
// we can safely unwrap it here.
|
||||
sourceObject = &script->scriptSourceUnwrap();
|
||||
sourceObject = script->sourceObject();
|
||||
}
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
@ -979,14 +977,14 @@ template XDRResult js::XDRLazyScript(XDRState<XDR_DECODE>*, HandleScope,
|
||||
HandleScriptSourceObject, HandleFunction,
|
||||
MutableHandle<LazyScript*>);
|
||||
|
||||
void JSScript::setSourceObject(JSObject* object) {
|
||||
void JSScript::setSourceObject(js::ScriptSourceObject* object) {
|
||||
MOZ_ASSERT(compartment() == object->compartment());
|
||||
sourceObject_ = object;
|
||||
}
|
||||
|
||||
void JSScript::setDefaultClassConstructorSpan(JSObject* sourceObject,
|
||||
uint32_t start, uint32_t end,
|
||||
unsigned line, unsigned column) {
|
||||
void JSScript::setDefaultClassConstructorSpan(
|
||||
js::ScriptSourceObject* sourceObject, uint32_t start, uint32_t end,
|
||||
unsigned line, unsigned column) {
|
||||
MOZ_ASSERT(isDefaultClassConstructor());
|
||||
setSourceObject(sourceObject);
|
||||
toStringStart_ = start;
|
||||
@ -1000,14 +998,8 @@ void JSScript::setDefaultClassConstructorSpan(JSObject* sourceObject,
|
||||
clearFlag(ImmutableFlags::SelfHosted);
|
||||
}
|
||||
|
||||
js::ScriptSourceObject& JSScript::scriptSourceUnwrap() const {
|
||||
// This may be called off the main thread. It's OK not to expose the source
|
||||
// object here as it doesn't escape.
|
||||
return UncheckedUnwrapWithoutExpose(sourceObject())->as<ScriptSourceObject>();
|
||||
}
|
||||
|
||||
js::ScriptSource* JSScript::scriptSource() const {
|
||||
return scriptSourceUnwrap().source();
|
||||
return sourceObject()->source();
|
||||
}
|
||||
|
||||
js::ScriptSource* JSScript::maybeForwardedScriptSource() const {
|
||||
@ -1355,32 +1347,64 @@ const Class ScriptSourceObject::class_ = {
|
||||
JSCLASS_FOREGROUND_FINALIZE,
|
||||
&ScriptSourceObjectClassOps};
|
||||
|
||||
ScriptSourceObject* ScriptSourceObject::create(JSContext* cx,
|
||||
ScriptSource* source) {
|
||||
RootedScriptSourceObject sourceObject(
|
||||
cx, NewObjectWithGivenProto<ScriptSourceObject>(cx, nullptr));
|
||||
if (!sourceObject) {
|
||||
ScriptSourceObject* ScriptSourceObject::createInternal(JSContext* cx,
|
||||
ScriptSource* source,
|
||||
HandleObject canonical) {
|
||||
ScriptSourceObject* obj =
|
||||
NewObjectWithGivenProto<ScriptSourceObject>(cx, nullptr);
|
||||
if (!obj) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
source->incref(); // The matching decref is in ScriptSourceObject::finalize.
|
||||
sourceObject->initReservedSlot(SOURCE_SLOT, PrivateValue(source));
|
||||
|
||||
// The remaining slots should eventually be populated by a call to
|
||||
// initFromOptions. Poison them until that point.
|
||||
sourceObject->initReservedSlot(ELEMENT_SLOT, MagicValue(JS_GENERIC_MAGIC));
|
||||
sourceObject->initReservedSlot(ELEMENT_PROPERTY_SLOT,
|
||||
MagicValue(JS_GENERIC_MAGIC));
|
||||
sourceObject->initReservedSlot(INTRODUCTION_SCRIPT_SLOT,
|
||||
MagicValue(JS_GENERIC_MAGIC));
|
||||
obj->initReservedSlot(SOURCE_SLOT, PrivateValue(source));
|
||||
|
||||
return sourceObject;
|
||||
if (canonical) {
|
||||
obj->initReservedSlot(CANONICAL_SLOT, ObjectValue(*canonical));
|
||||
} else {
|
||||
obj->initReservedSlot(CANONICAL_SLOT, ObjectValue(*obj));
|
||||
}
|
||||
|
||||
// The slots below should either be populated by a call to initFromOptions or,
|
||||
// if this is a non-canonical ScriptSourceObject, they are unused. Poison
|
||||
// them.
|
||||
obj->initReservedSlot(ELEMENT_SLOT, MagicValue(JS_GENERIC_MAGIC));
|
||||
obj->initReservedSlot(ELEMENT_PROPERTY_SLOT, MagicValue(JS_GENERIC_MAGIC));
|
||||
obj->initReservedSlot(INTRODUCTION_SCRIPT_SLOT, MagicValue(JS_GENERIC_MAGIC));
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
ScriptSourceObject* ScriptSourceObject::create(JSContext* cx,
|
||||
ScriptSource* source) {
|
||||
return createInternal(cx, source, nullptr);
|
||||
}
|
||||
|
||||
ScriptSourceObject* ScriptSourceObject::clone(JSContext* cx,
|
||||
HandleScriptSourceObject sso) {
|
||||
MOZ_ASSERT(cx->compartment() != sso->compartment());
|
||||
|
||||
RootedObject wrapped(cx, sso);
|
||||
if (!cx->compartment()->wrap(cx, &wrapped)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return createInternal(cx, sso->source(), wrapped);
|
||||
}
|
||||
|
||||
ScriptSourceObject* ScriptSourceObject::unwrappedCanonical() const {
|
||||
MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtimeFromAnyThread()));
|
||||
|
||||
JSObject* obj = &getReservedSlot(CANONICAL_SLOT).toObject();
|
||||
return &UncheckedUnwrap(obj)->as<ScriptSourceObject>();
|
||||
}
|
||||
|
||||
/* static */ bool ScriptSourceObject::initFromOptions(
|
||||
JSContext* cx, HandleScriptSourceObject source,
|
||||
const ReadOnlyCompileOptions& options) {
|
||||
cx->releaseCheck(source);
|
||||
MOZ_ASSERT(source->isCanonical());
|
||||
MOZ_ASSERT(source->getReservedSlot(ELEMENT_SLOT).isMagic(JS_GENERIC_MAGIC));
|
||||
MOZ_ASSERT(
|
||||
source->getReservedSlot(ELEMENT_PROPERTY_SLOT).isMagic(JS_GENERIC_MAGIC));
|
||||
@ -1411,6 +1435,8 @@ ScriptSourceObject* ScriptSourceObject::create(JSContext* cx,
|
||||
/* static */ bool ScriptSourceObject::initElementProperties(
|
||||
JSContext* cx, HandleScriptSourceObject source, HandleObject element,
|
||||
HandleString elementAttrName) {
|
||||
MOZ_ASSERT(source->isCanonical());
|
||||
|
||||
RootedValue elementValue(cx, ObjectOrNullValue(element));
|
||||
if (!cx->compartment()->wrap(cx, &elementValue)) {
|
||||
return false;
|
||||
@ -3044,7 +3070,7 @@ void PrivateScriptData::traceChildren(JSTracer* trc) {
|
||||
}
|
||||
|
||||
JSScript::JSScript(JS::Realm* realm, uint8_t* stubEntry,
|
||||
HandleObject sourceObject, uint32_t sourceStart,
|
||||
HandleScriptSourceObject sourceObject, uint32_t sourceStart,
|
||||
uint32_t sourceEnd, uint32_t toStringStart,
|
||||
uint32_t toStringEnd)
|
||||
:
|
||||
@ -3065,7 +3091,8 @@ JSScript::JSScript(JS::Realm* realm, uint8_t* stubEntry,
|
||||
setSourceObject(sourceObject);
|
||||
}
|
||||
|
||||
/* static */ JSScript* JSScript::New(JSContext* cx, HandleObject sourceObject,
|
||||
/* static */ JSScript* JSScript::New(JSContext* cx,
|
||||
HandleScriptSourceObject sourceObject,
|
||||
uint32_t sourceStart, uint32_t sourceEnd,
|
||||
uint32_t toStringStart,
|
||||
uint32_t toStringEnd) {
|
||||
@ -3087,8 +3114,8 @@ JSScript::JSScript(JS::Realm* realm, uint8_t* stubEntry,
|
||||
|
||||
/* static */ JSScript* JSScript::Create(
|
||||
JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
HandleObject sourceObject, uint32_t sourceStart, uint32_t sourceEnd,
|
||||
uint32_t toStringStart, uint32_t toStringEnd) {
|
||||
HandleScriptSourceObject sourceObject, uint32_t sourceStart,
|
||||
uint32_t sourceEnd, uint32_t toStringStart, uint32_t toStringEnd) {
|
||||
RootedScript script(cx, JSScript::New(cx, sourceObject, sourceStart,
|
||||
sourceEnd, toStringStart, toStringEnd));
|
||||
if (!script) {
|
||||
@ -4004,7 +4031,7 @@ static JSScript* CreateEmptyScriptForClone(JSContext* cx, HandleScript src) {
|
||||
* in another runtime, so lazily create a new script source object to
|
||||
* use for them.
|
||||
*/
|
||||
RootedObject sourceObject(cx);
|
||||
RootedScriptSourceObject sourceObject(cx);
|
||||
if (src->realm()->isSelfHostingRealm()) {
|
||||
if (!cx->realm()->selfHostingScriptSource) {
|
||||
CompileOptions options(cx);
|
||||
@ -4019,8 +4046,11 @@ static JSScript* CreateEmptyScriptForClone(JSContext* cx, HandleScript src) {
|
||||
sourceObject = cx->realm()->selfHostingScriptSource;
|
||||
} else {
|
||||
sourceObject = src->sourceObject();
|
||||
if (!cx->compartment()->wrap(cx, &sourceObject)) {
|
||||
return nullptr;
|
||||
if (cx->compartment() != sourceObject->compartment()) {
|
||||
sourceObject = ScriptSourceObject::clone(cx, sourceObject);
|
||||
if (!sourceObject) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1103,15 +1103,40 @@ class ScriptSourceHolder {
|
||||
ScriptSource* get() const { return ss; }
|
||||
};
|
||||
|
||||
// [SMDOC] ScriptSourceObject
|
||||
//
|
||||
// ScriptSourceObject stores the ScriptSource and GC pointers related to it.
|
||||
//
|
||||
// ScriptSourceObjects can be cloned when we clone the JSScript (in order to
|
||||
// execute the script in a different realm/compartment). In this case we create
|
||||
// a new SSO that stores (a wrapper for) the original SSO in its "canonical
|
||||
// slot". The canonical SSO is always used for the private, introductionScript,
|
||||
// element, elementAttributeName slots. This means their accessors may return an
|
||||
// object in a different compartment, hence the "unwrapped" prefix.
|
||||
//
|
||||
// We need ScriptSourceObject (instead of storing these GC pointers in the
|
||||
// ScriptSource itself) to properly account for cross-zone pointers: the
|
||||
// canonical SSO will be stored in the wrapper map if necessary so GC will do
|
||||
// the right thing.
|
||||
class ScriptSourceObject : public NativeObject {
|
||||
static const ClassOps classOps_;
|
||||
|
||||
static ScriptSourceObject* createInternal(JSContext* cx, ScriptSource* source,
|
||||
HandleObject canonical);
|
||||
|
||||
bool isCanonical() const {
|
||||
return &getReservedSlot(CANONICAL_SLOT).toObject() == this;
|
||||
}
|
||||
ScriptSourceObject* unwrappedCanonical() const;
|
||||
|
||||
public:
|
||||
static const Class class_;
|
||||
|
||||
static void trace(JSTracer* trc, JSObject* obj);
|
||||
static void finalize(FreeOp* fop, JSObject* obj);
|
||||
|
||||
static ScriptSourceObject* create(JSContext* cx, ScriptSource* source);
|
||||
static ScriptSourceObject* clone(JSContext* cx, HandleScriptSourceObject sso);
|
||||
|
||||
// Initialize those properties of this ScriptSourceObject whose values
|
||||
// are provided by |options|, re-wrapping as necessary.
|
||||
@ -1127,27 +1152,38 @@ class ScriptSourceObject : public NativeObject {
|
||||
ScriptSource* source() const {
|
||||
return static_cast<ScriptSource*>(getReservedSlot(SOURCE_SLOT).toPrivate());
|
||||
}
|
||||
JSObject* element() const {
|
||||
return getReservedSlot(ELEMENT_SLOT).toObjectOrNull();
|
||||
|
||||
JSObject* unwrappedElement() const {
|
||||
return unwrappedCanonical()->getReservedSlot(ELEMENT_SLOT).toObjectOrNull();
|
||||
}
|
||||
const Value& elementAttributeName() const {
|
||||
MOZ_ASSERT(!getReservedSlot(ELEMENT_PROPERTY_SLOT).isMagic());
|
||||
return getReservedSlot(ELEMENT_PROPERTY_SLOT);
|
||||
const Value& unwrappedElementAttributeName() const {
|
||||
const Value& v =
|
||||
unwrappedCanonical()->getReservedSlot(ELEMENT_PROPERTY_SLOT);
|
||||
MOZ_ASSERT(!v.isMagic());
|
||||
return v;
|
||||
}
|
||||
JSScript* introductionScript() const {
|
||||
Value value = getReservedSlot(INTRODUCTION_SCRIPT_SLOT);
|
||||
JSScript* unwrappedIntroductionScript() const {
|
||||
Value value =
|
||||
unwrappedCanonical()->getReservedSlot(INTRODUCTION_SCRIPT_SLOT);
|
||||
if (value.isUndefined()) {
|
||||
return nullptr;
|
||||
}
|
||||
return value.toGCThing()->as<JSScript>();
|
||||
}
|
||||
|
||||
void setPrivate(const Value& value) { setReservedSlot(PRIVATE_SLOT, value); }
|
||||
Value getPrivate() const { return getReservedSlot(PRIVATE_SLOT); }
|
||||
void setPrivate(const Value& value) {
|
||||
MOZ_ASSERT(isCanonical());
|
||||
setReservedSlot(PRIVATE_SLOT, value);
|
||||
}
|
||||
|
||||
Value unwrappedPrivate() const {
|
||||
return unwrappedCanonical()->getReservedSlot(PRIVATE_SLOT);
|
||||
}
|
||||
|
||||
private:
|
||||
enum {
|
||||
SOURCE_SLOT = 0,
|
||||
CANONICAL_SLOT,
|
||||
ELEMENT_SLOT,
|
||||
ELEMENT_PROPERTY_SLOT,
|
||||
INTRODUCTION_SCRIPT_SLOT,
|
||||
@ -1480,11 +1516,8 @@ class JSScript : public js::gc::TenuredCell {
|
||||
/* Persistent type information retained across GCs. */
|
||||
js::TypeScript* types_ = nullptr;
|
||||
|
||||
// This script's ScriptSourceObject, or a CCW thereof.
|
||||
//
|
||||
// (When we clone a JSScript into a new compartment, we don't clone its
|
||||
// source object. Instead, the clone refers to a wrapper.)
|
||||
js::GCPtrObject sourceObject_ = {};
|
||||
// This script's ScriptSourceObject.
|
||||
js::GCPtr<js::ScriptSourceObject*> sourceObject_ = {};
|
||||
|
||||
/*
|
||||
* Information attached by Ion. Nexto a valid IonScript this could be
|
||||
@ -1740,20 +1773,20 @@ class JSScript : public js::gc::TenuredCell {
|
||||
js::MutableHandle<JS::GCVector<js::Scope*>> scopes);
|
||||
|
||||
private:
|
||||
JSScript(JS::Realm* realm, uint8_t* stubEntry, js::HandleObject sourceObject,
|
||||
uint32_t sourceStart, uint32_t sourceEnd, uint32_t toStringStart,
|
||||
uint32_t toStringend);
|
||||
JSScript(JS::Realm* realm, uint8_t* stubEntry,
|
||||
js::HandleScriptSourceObject sourceObject, uint32_t sourceStart,
|
||||
uint32_t sourceEnd, uint32_t toStringStart, uint32_t toStringend);
|
||||
|
||||
static JSScript* New(JSContext* cx, js::HandleObject sourceObject,
|
||||
static JSScript* New(JSContext* cx, js::HandleScriptSourceObject sourceObject,
|
||||
uint32_t sourceStart, uint32_t sourceEnd,
|
||||
uint32_t toStringStart, uint32_t toStringEnd);
|
||||
|
||||
public:
|
||||
static JSScript* Create(JSContext* cx,
|
||||
const JS::ReadOnlyCompileOptions& options,
|
||||
js::HandleObject sourceObject, uint32_t sourceStart,
|
||||
uint32_t sourceEnd, uint32_t toStringStart,
|
||||
uint32_t toStringEnd);
|
||||
js::HandleScriptSourceObject sourceObject,
|
||||
uint32_t sourceStart, uint32_t sourceEnd,
|
||||
uint32_t toStringStart, uint32_t toStringEnd);
|
||||
|
||||
// NOTE: If you use createPrivateScriptData directly instead of via
|
||||
// fullyInitFromEmitter, you are responsible for notifying the debugger
|
||||
@ -2281,15 +2314,14 @@ class JSScript : public js::gc::TenuredCell {
|
||||
|
||||
static bool loadSource(JSContext* cx, js::ScriptSource* ss, bool* worked);
|
||||
|
||||
void setSourceObject(JSObject* object);
|
||||
JSObject* sourceObject() const { return sourceObject_; }
|
||||
js::ScriptSourceObject& scriptSourceUnwrap() const;
|
||||
void setSourceObject(js::ScriptSourceObject* object);
|
||||
js::ScriptSourceObject* sourceObject() const { return sourceObject_; }
|
||||
js::ScriptSource* scriptSource() const;
|
||||
js::ScriptSource* maybeForwardedScriptSource() const;
|
||||
|
||||
void setDefaultClassConstructorSpan(JSObject* sourceObject, uint32_t start,
|
||||
uint32_t end, unsigned line,
|
||||
unsigned column);
|
||||
void setDefaultClassConstructorSpan(js::ScriptSourceObject* sourceObject,
|
||||
uint32_t start, uint32_t end,
|
||||
unsigned line, unsigned column);
|
||||
|
||||
bool mutedErrors() const { return scriptSource()->mutedErrors(); }
|
||||
const char* filename() const { return scriptSource()->filename(); }
|
||||
@ -2787,9 +2819,8 @@ class LazyScript : public gc::TenuredCell {
|
||||
GCPtr<TenuredCell*> enclosingLazyScriptOrScope_;
|
||||
|
||||
// ScriptSourceObject. We leave this set to nullptr until we generate
|
||||
// bytecode for our immediate parent. This is never a CCW; we don't clone
|
||||
// LazyScripts into other compartments.
|
||||
GCPtrObject sourceObject_;
|
||||
// bytecode for our immediate parent.
|
||||
GCPtr<ScriptSourceObject*> sourceObject_;
|
||||
|
||||
// Heap allocated table with any free variables or inner functions.
|
||||
void* table_;
|
||||
|
Loading…
Reference in New Issue
Block a user