mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1169639 - Make intrinsicsHolder-accesses fallible, now that it's possible to access it without having previously gone through intrinsics-object creation code to ensure its existence. r=shu
This commit is contained in:
parent
c848a1cba8
commit
2d503d3ff8
@ -1128,39 +1128,25 @@ CreateObjectPrototype(JSContext* cx, JSProtoKey key)
|
||||
static bool
|
||||
FinishObjectClassInit(JSContext* cx, JS::HandleObject ctor, JS::HandleObject proto)
|
||||
{
|
||||
Rooted<GlobalObject*> self(cx, cx->global());
|
||||
Rooted<GlobalObject*> global(cx, cx->global());
|
||||
|
||||
/* ES5 15.1.2.1. */
|
||||
RootedId evalId(cx, NameToId(cx->names().eval));
|
||||
JSObject* evalobj = DefineFunction(cx, self, evalId, IndirectEval, 1,
|
||||
JSObject* evalobj = DefineFunction(cx, global, evalId, IndirectEval, 1,
|
||||
JSFUN_STUB_GSOPS | JSPROP_RESOLVING);
|
||||
if (!evalobj)
|
||||
return false;
|
||||
self->setOriginalEval(evalobj);
|
||||
global->setOriginalEval(evalobj);
|
||||
|
||||
RootedObject intrinsicsHolder(cx);
|
||||
bool isSelfHostingGlobal = cx->runtime()->isSelfHostingGlobal(self);
|
||||
if (isSelfHostingGlobal) {
|
||||
intrinsicsHolder = self;
|
||||
} else {
|
||||
intrinsicsHolder = NewObjectWithGivenProto<PlainObject>(cx, proto, TenuredObject);
|
||||
if (!intrinsicsHolder)
|
||||
return false;
|
||||
}
|
||||
self->setIntrinsicsHolder(intrinsicsHolder);
|
||||
/* Define a property 'global' with the current global as its value. */
|
||||
RootedValue global(cx, ObjectValue(*self));
|
||||
if (!DefineProperty(cx, intrinsicsHolder, cx->names().global, global,
|
||||
nullptr, nullptr, JSPROP_PERMANENT | JSPROP_READONLY))
|
||||
{
|
||||
Rooted<NativeObject*> holder(cx, GlobalObject::getIntrinsicsHolder(cx, global));
|
||||
if (!holder)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Define self-hosted functions after setting the intrinsics holder
|
||||
* (which is needed to define self-hosted functions)
|
||||
*/
|
||||
if (!isSelfHostingGlobal) {
|
||||
if (!cx->runtime()->isSelfHostingGlobal(global)) {
|
||||
if (!JS_DefineFunctions(cx, ctor, object_static_methods, OnlyDefineLateProperties))
|
||||
return false;
|
||||
if (!JS_DefineFunctions(cx, proto, object_methods, OnlyDefineLateProperties))
|
||||
@ -1176,8 +1162,10 @@ FinishObjectClassInit(JSContext* cx, JS::HandleObject ctor, JS::HandleObject pro
|
||||
* only set the [[Prototype]] if it hasn't already been set.
|
||||
*/
|
||||
Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
|
||||
if (self->shouldSplicePrototype(cx) && !self->splicePrototype(cx, self->getClass(), tagged))
|
||||
return false;
|
||||
if (global->shouldSplicePrototype(cx)) {
|
||||
if (!global->splicePrototype(cx, global->getClass(), tagged))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -100,3 +100,8 @@ function primitiveThisTests()
|
||||
if (primitiveThisSupported())
|
||||
primitiveThisTests();
|
||||
|
||||
// Ensure the internal implementation of destructuring object pattern
|
||||
// assignment -- using a self-hosted intrinsic function -- works even when lazy
|
||||
// standard class initialization hasn't occurred. Unfortunately we can't use
|
||||
// |newGlobal()| because that method eagerly initializes standard classes.
|
||||
evalcx("({} = 1);", evalcx("lazy"));
|
||||
|
@ -7663,9 +7663,10 @@ IonBuilder::jsop_intrinsic(PropertyName* name)
|
||||
return pushTypeBarrier(ins, types, BarrierKind::TypeSet);
|
||||
}
|
||||
|
||||
// Bake in the intrinsic. Make sure that TI agrees with us on the type.
|
||||
Value vp;
|
||||
JS_ALWAYS_TRUE(script()->global().maybeGetIntrinsicValue(name, &vp));
|
||||
// Bake in the intrinsic, guaranteed to exist because a non-empty typeset
|
||||
// means the intrinsic was successfully gotten in the VM call above.
|
||||
// Assert that TI agrees with us on the type.
|
||||
Value vp = script()->global().existingIntrinsicValue(name);
|
||||
MOZ_ASSERT(types->hasType(TypeSet::GetValueType(vp)));
|
||||
|
||||
pushConstant(vp);
|
||||
|
@ -2482,30 +2482,38 @@ DefineSelfHostedProperty(JSContext* cx, HandleObject obj, HandleId id,
|
||||
const char* getterName, const char* setterName,
|
||||
unsigned attrs, unsigned flags)
|
||||
{
|
||||
RootedAtom getterNameAtom(cx, Atomize(cx, getterName, strlen(getterName)));
|
||||
JSAtom* getterNameAtom = Atomize(cx, getterName, strlen(getterName));
|
||||
if (!getterNameAtom)
|
||||
return false;
|
||||
RootedPropertyName getterNameName(cx, getterNameAtom->asPropertyName());
|
||||
|
||||
RootedAtom name(cx, IdToFunctionName(cx, id));
|
||||
if (!name)
|
||||
return false;
|
||||
|
||||
RootedValue getterValue(cx);
|
||||
if (!cx->global()->getSelfHostedFunction(cx, getterNameAtom, name, 0, &getterValue))
|
||||
if (!GlobalObject::getSelfHostedFunction(cx, cx->global(), getterNameName, name, 0,
|
||||
&getterValue))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(getterValue.isObject() && getterValue.toObject().is<JSFunction>());
|
||||
RootedFunction getterFunc(cx, &getterValue.toObject().as<JSFunction>());
|
||||
JSNative getterOp = JS_DATA_TO_FUNC_PTR(JSNative, getterFunc.get());
|
||||
|
||||
RootedFunction setterFunc(cx);
|
||||
if (setterName) {
|
||||
RootedAtom setterNameAtom(cx, Atomize(cx, setterName, strlen(setterName)));
|
||||
JSAtom* setterNameAtom = Atomize(cx, setterName, strlen(setterName));
|
||||
if (!setterNameAtom)
|
||||
return false;
|
||||
RootedPropertyName setterNameName(cx, setterNameAtom->asPropertyName());
|
||||
|
||||
RootedValue setterValue(cx);
|
||||
if (!cx->global()->getSelfHostedFunction(cx, setterNameAtom, name, 0, &setterValue))
|
||||
if (!GlobalObject::getSelfHostedFunction(cx, cx->global(), setterNameName, name, 0,
|
||||
&setterValue))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(setterValue.isObject() && setterValue.toObject().is<JSFunction>());
|
||||
setterFunc = &getterValue.toObject().as<JSFunction>();
|
||||
}
|
||||
@ -3289,11 +3297,12 @@ JS::GetSelfHostedFunction(JSContext* cx, const char* selfHostedName, HandleId id
|
||||
if (!name)
|
||||
return nullptr;
|
||||
|
||||
RootedAtom shName(cx, Atomize(cx, selfHostedName, strlen(selfHostedName)));
|
||||
if (!shName)
|
||||
JSAtom* shAtom = Atomize(cx, selfHostedName, strlen(selfHostedName));
|
||||
if (!shAtom)
|
||||
return nullptr;
|
||||
RootedPropertyName shName(cx, shAtom->asPropertyName());
|
||||
RootedValue funVal(cx);
|
||||
if (!cx->global()->getSelfHostedFunction(cx, shName, name, nargs, &funVal))
|
||||
if (!GlobalObject::getSelfHostedFunction(cx, cx->global(), shName, name, nargs, &funVal))
|
||||
return nullptr;
|
||||
return &funVal.toObject().as<JSFunction>();
|
||||
}
|
||||
@ -3590,15 +3599,19 @@ JS_DefineFunctions(JSContext* cx, HandleObject obj, const JSFunctionSpec* fs,
|
||||
MOZ_ASSERT(!fs->call.op);
|
||||
MOZ_ASSERT(!fs->call.info);
|
||||
|
||||
RootedAtom shName(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName)));
|
||||
if (!shName)
|
||||
JSAtom* shAtom = Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName));
|
||||
if (!shAtom)
|
||||
return false;
|
||||
RootedPropertyName shName(cx, shAtom->asPropertyName());
|
||||
RootedAtom name(cx, IdToFunctionName(cx, id));
|
||||
if (!name)
|
||||
return false;
|
||||
RootedValue funVal(cx);
|
||||
if (!cx->global()->getSelfHostedFunction(cx, shName, name, fs->nargs, &funVal))
|
||||
if (!GlobalObject::getSelfHostedFunction(cx, cx->global(), shName, name, fs->nargs,
|
||||
&funVal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!DefineProperty(cx, obj, id, funVal, nullptr, nullptr, flags))
|
||||
return false;
|
||||
} else {
|
||||
|
@ -21,6 +21,7 @@
|
||||
macro(ArrayIteratorNext, ArrayIteratorNext, "ArrayIteratorNext") \
|
||||
macro(ArrayType, ArrayType, "ArrayType") \
|
||||
macro(ArrayValues, ArrayValues, "ArrayValues") \
|
||||
macro(ArrayValuesAt, ArrayValuesAt, "ArrayValuesAt") \
|
||||
macro(Async, Async, "Async") \
|
||||
macro(breakdown, breakdown, "breakdown") \
|
||||
macro(buffer, buffer, "buffer") \
|
||||
|
@ -170,14 +170,9 @@ ForOfIterator::materializeArrayIterator()
|
||||
{
|
||||
MOZ_ASSERT(index != NOT_ARRAY);
|
||||
|
||||
const char* nameString = "ArrayValuesAt";
|
||||
|
||||
RootedAtom name(cx_, Atomize(cx_, nameString, strlen(nameString)));
|
||||
if (!name)
|
||||
return false;
|
||||
|
||||
HandlePropertyName name = cx_->names().ArrayValuesAt;
|
||||
RootedValue val(cx_);
|
||||
if (!cx_->global()->getSelfHostedFunction(cx_, name, name, 1, &val))
|
||||
if (!GlobalObject::getSelfHostedFunction(cx_, cx_->global(), name, name, 1, &val))
|
||||
return false;
|
||||
|
||||
InvokeArgs args(cx_);
|
||||
|
@ -602,14 +602,44 @@ GlobalObject::getAlreadyCreatedRegExpStatics() const
|
||||
return static_cast<RegExpStatics*>(val.toObject().as<RegExpStaticsObject>().getPrivate(/* nfixed = */ 1));
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalObject::getSelfHostedFunction(JSContext* cx, HandleAtom selfHostedName, HandleAtom name,
|
||||
/* static */ NativeObject*
|
||||
GlobalObject::getIntrinsicsHolder(JSContext* cx, Handle<GlobalObject*> global)
|
||||
{
|
||||
Value slot = global->getReservedSlot(INTRINSICS);
|
||||
MOZ_ASSERT(slot.isUndefined() || slot.isObject());
|
||||
|
||||
if (slot.isObject())
|
||||
return &slot.toObject().as<NativeObject>();
|
||||
|
||||
Rooted<NativeObject*> intrinsicsHolder(cx);
|
||||
bool isSelfHostingGlobal = cx->runtime()->isSelfHostingGlobal(global);
|
||||
if (isSelfHostingGlobal) {
|
||||
intrinsicsHolder = global;
|
||||
} else {
|
||||
intrinsicsHolder = NewObjectWithGivenProto<PlainObject>(cx, nullptr, TenuredObject);
|
||||
if (!intrinsicsHolder)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Define a property 'global' with the current global as its value. */
|
||||
RootedValue globalValue(cx, ObjectValue(*global));
|
||||
if (!DefineProperty(cx, intrinsicsHolder, cx->names().global, globalValue,
|
||||
nullptr, nullptr, JSPROP_PERMANENT | JSPROP_READONLY))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Install the intrinsics holder in the intrinsics.
|
||||
global->setReservedSlot(INTRINSICS, ObjectValue(*intrinsicsHolder));
|
||||
return intrinsicsHolder;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
GlobalObject::getSelfHostedFunction(JSContext* cx, Handle<GlobalObject*> global,
|
||||
HandlePropertyName selfHostedName, HandleAtom name,
|
||||
unsigned nargs, MutableHandleValue funVal)
|
||||
{
|
||||
RootedId shId(cx, AtomToId(selfHostedName));
|
||||
RootedObject holder(cx, cx->global()->intrinsicsHolder());
|
||||
|
||||
if (cx->global()->maybeGetIntrinsicValue(shId, funVal.address()))
|
||||
if (GlobalObject::maybeGetIntrinsicValue(cx, global, selfHostedName, funVal))
|
||||
return true;
|
||||
|
||||
JSFunction* fun =
|
||||
@ -621,18 +651,22 @@ GlobalObject::getSelfHostedFunction(JSContext* cx, HandleAtom selfHostedName, Ha
|
||||
fun->setExtendedSlot(0, StringValue(selfHostedName));
|
||||
funVal.setObject(*fun);
|
||||
|
||||
return cx->global()->addIntrinsicValue(cx, shId, funVal);
|
||||
return GlobalObject::addIntrinsicValue(cx, global, selfHostedName, funVal);
|
||||
}
|
||||
|
||||
bool
|
||||
GlobalObject::addIntrinsicValue(JSContext* cx, HandleId id, HandleValue value)
|
||||
/* static */ bool
|
||||
GlobalObject::addIntrinsicValue(JSContext* cx, Handle<GlobalObject*> global,
|
||||
HandlePropertyName name, HandleValue value)
|
||||
{
|
||||
RootedNativeObject holder(cx, intrinsicsHolder());
|
||||
RootedNativeObject holder(cx, GlobalObject::getIntrinsicsHolder(cx, global));
|
||||
if (!holder)
|
||||
return false;
|
||||
|
||||
uint32_t slot = holder->slotSpan();
|
||||
RootedShape last(cx, holder->lastProperty());
|
||||
Rooted<UnownedBaseShape*> base(cx, last->base()->unowned());
|
||||
|
||||
RootedId id(cx, NameToId(name));
|
||||
StackShape child(base, id, slot, 0, 0);
|
||||
Shape* shape = cx->compartment()->propertyTree.getChild(cx, last, child);
|
||||
if (!shape)
|
||||
|
@ -148,11 +148,6 @@ class GlobalObject : public NativeObject
|
||||
setSlot(EVAL, ObjectValue(*evalobj));
|
||||
}
|
||||
|
||||
void setIntrinsicsHolder(JSObject* obj) {
|
||||
MOZ_ASSERT(getSlotRef(INTRINSICS).isUndefined());
|
||||
setSlot(INTRINSICS, ObjectValue(*obj));
|
||||
}
|
||||
|
||||
Value getConstructor(JSProtoKey key) const {
|
||||
MOZ_ASSERT(key <= JSProto_LIMIT);
|
||||
return getSlot(APPLICATION_SLOTS + key);
|
||||
@ -604,48 +599,61 @@ class GlobalObject : public NativeObject
|
||||
return &self->getPrototype(JSProto_DataView).toObject();
|
||||
}
|
||||
|
||||
NativeObject* intrinsicsHolder() {
|
||||
MOZ_ASSERT(!getSlot(INTRINSICS).isUndefined());
|
||||
return &getSlot(INTRINSICS).toObject().as<NativeObject>();
|
||||
static NativeObject* getIntrinsicsHolder(JSContext* cx, Handle<GlobalObject*> global);
|
||||
|
||||
Value existingIntrinsicValue(PropertyName* name) {
|
||||
Value slot = getReservedSlot(INTRINSICS);
|
||||
MOZ_ASSERT(slot.isObject(), "intrinsics holder must already exist");
|
||||
|
||||
NativeObject* holder = &slot.toObject().as<NativeObject>();
|
||||
|
||||
Shape* shape = holder->lookupPure(name);
|
||||
MOZ_ASSERT(shape, "intrinsic must already have been added to holder");
|
||||
|
||||
return holder->getSlot(shape->slot());
|
||||
}
|
||||
|
||||
bool maybeGetIntrinsicValue(jsid id, Value* vp) {
|
||||
NativeObject* holder = intrinsicsHolder();
|
||||
static bool
|
||||
maybeGetIntrinsicValue(JSContext* cx, Handle<GlobalObject*> global, Handle<PropertyName*> name,
|
||||
MutableHandleValue vp)
|
||||
{
|
||||
NativeObject* holder = getIntrinsicsHolder(cx, global);
|
||||
if (!holder)
|
||||
return false;
|
||||
|
||||
if (Shape* shape = holder->lookupPure(id)) {
|
||||
*vp = holder->getSlot(shape->slot());
|
||||
if (Shape* shape = holder->lookupPure(name)) {
|
||||
vp.set(holder->getSlot(shape->slot()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool maybeGetIntrinsicValue(PropertyName* name, Value* vp) {
|
||||
return maybeGetIntrinsicValue(NameToId(name), vp);
|
||||
}
|
||||
|
||||
static bool getIntrinsicValue(JSContext* cx, Handle<GlobalObject*> global,
|
||||
HandlePropertyName name, MutableHandleValue value)
|
||||
{
|
||||
if (global->maybeGetIntrinsicValue(name, value.address()))
|
||||
if (GlobalObject::maybeGetIntrinsicValue(cx, global, name, value))
|
||||
return true;
|
||||
if (!cx->runtime()->cloneSelfHostedValue(cx, name, value))
|
||||
return false;
|
||||
RootedId id(cx, NameToId(name));
|
||||
return global->addIntrinsicValue(cx, id, value);
|
||||
return GlobalObject::addIntrinsicValue(cx, global, name, value);
|
||||
}
|
||||
|
||||
bool addIntrinsicValue(JSContext* cx, HandleId id, HandleValue value);
|
||||
static bool addIntrinsicValue(JSContext* cx, Handle<GlobalObject*> global, HandlePropertyName name,
|
||||
HandleValue value);
|
||||
|
||||
bool setIntrinsicValue(JSContext* cx, PropertyName* name, HandleValue value) {
|
||||
#ifdef DEBUG
|
||||
RootedObject self(cx, this);
|
||||
MOZ_ASSERT(cx->runtime()->isSelfHostingGlobal(self));
|
||||
#endif
|
||||
RootedObject holder(cx, intrinsicsHolder());
|
||||
static bool setIntrinsicValue(JSContext* cx, Handle<GlobalObject*> global, PropertyName* name,
|
||||
HandleValue value)
|
||||
{
|
||||
MOZ_ASSERT(cx->runtime()->isSelfHostingGlobal(global));
|
||||
RootedObject holder(cx, GlobalObject::getIntrinsicsHolder(cx, global));
|
||||
if (!holder)
|
||||
return false;
|
||||
return SetProperty(cx, holder, name, value);
|
||||
}
|
||||
|
||||
bool getSelfHostedFunction(JSContext* cx, HandleAtom selfHostedName, HandleAtom name,
|
||||
unsigned nargs, MutableHandleValue funVal);
|
||||
static bool getSelfHostedFunction(JSContext* cx, Handle<GlobalObject*> global,
|
||||
HandlePropertyName selfHostedName, HandleAtom name,
|
||||
unsigned nargs, MutableHandleValue funVal);
|
||||
|
||||
bool hasRegExpStatics() const;
|
||||
RegExpStatics* getRegExpStatics(ExclusiveContext* cx) const;
|
||||
|
@ -246,7 +246,7 @@ inline bool
|
||||
SetIntrinsicOperation(JSContext* cx, JSScript* script, jsbytecode* pc, HandleValue val)
|
||||
{
|
||||
RootedPropertyName name(cx, script->getName(pc));
|
||||
return cx->global()->setIntrinsicValue(cx, name, val);
|
||||
return GlobalObject::setIntrinsicValue(cx, cx->global(), name, val);
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -2310,7 +2310,13 @@ CASE(JSOP_SETCONST)
|
||||
END_CASE(JSOP_SETCONST)
|
||||
|
||||
CASE(JSOP_BINDINTRINSIC)
|
||||
PUSH_OBJECT(*cx->global()->intrinsicsHolder());
|
||||
{
|
||||
NativeObject* holder = GlobalObject::getIntrinsicsHolder(cx, cx->global());
|
||||
if (!holder)
|
||||
goto error;
|
||||
|
||||
PUSH_OBJECT(*holder);
|
||||
}
|
||||
END_CASE(JSOP_BINDINTRINSIC)
|
||||
|
||||
CASE(JSOP_BINDGNAME)
|
||||
|
Loading…
Reference in New Issue
Block a user