Bug 1142794 - Change 'receiver' argument to SetProperty functions and ProxyHandler::set methods to be a HandleValue. r=Waldo.

Also: Change signature of these functions and methods to all have the same arguments in the same order: (cx, obj, id, v, receiver). Also change v from MutableHandleValue to HandleValue.

There is no change in behavior.

In fact the new error message `JSMSG_SET_NON_OBJECT_RECEIVER` is
impossible to trigger from scripts for now, I think (after re-reading
the whole patch with this in mind). JS_ForwardSetPropertyTo is the only
way to get a non-object receiver into the engine, but no caller
currently does so.

We're installing new pipes here, and they should work, but for now it's
the same cold water flowing through as before. Actually hooking up the
hot water is left for another bug (one with tests, not to put too fine a
point on it).

Notes:

*   InvokeGetterOrSetter had to be split into two functions:
    InvokeGetter takes a MutableHandleValue out-param,
    InvokeSetter a HandleValue in-param.

*   Watchpoints can still tamper with values being assigned. So can
    JSSetterOps. I'm pleased we can support this craziness in a way that
    doesn't have to spread via the type system to encompass the entire
    codebase.

*   Change in GlobalObject::setIntrinsicValue is not really a change.
    Yes, it asserted before, but an exception thrown during self-hosting
    initialization is not going to go unnoticed either.

*   Since the receiver argument to js::SetProperty() is at the end now, it
    makes sense for it to be optional. Some callers look nicer.
This commit is contained in:
Jason Orendorff 2015-03-01 13:16:19 -06:00
parent 0fa4a70f2d
commit db4ac4cade
55 changed files with 418 additions and 470 deletions

View File

@ -643,9 +643,8 @@ public:
JS::Handle<jsid> id,
JS::MutableHandle<JS::Value> vp) const override;
virtual bool set(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id,
JS::MutableHandle<JS::Value> vp,
JS::Handle<jsid> id, JS::Handle<JS::Value> v,
JS::Handle<JS::Value> receiver,
JS::ObjectOpResult &result) const override;
// SpiderMonkey extensions
@ -909,9 +908,9 @@ nsOuterWindowProxy::get(JSContext *cx, JS::Handle<JSObject*> proxy,
bool
nsOuterWindowProxy::set(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id,
JS::MutableHandle<JS::Value> vp,
JS::Handle<JS::Value> v,
JS::Handle<JS::Value> receiver,
JS::ObjectOpResult &result) const
{
int32_t index = GetArrayIndexFromId(cx, id);
@ -921,7 +920,7 @@ nsOuterWindowProxy::set(JSContext *cx, JS::Handle<JSObject*> proxy,
return result.failReadOnly();
}
return js::Wrapper::set(cx, proxy, receiver, id, vp, result);
return js::Wrapper::set(cx, proxy, id, v, receiver, result);
}
bool

View File

@ -9807,7 +9807,7 @@ class CGProxySpecialOperation(CGPerSignatureCall):
false.
"""
def __init__(self, descriptor, operation, checkFound=True,
argumentMutableValue=None, resultVar=None, foundVar=None):
argumentHandleValue=None, resultVar=None, foundVar=None):
self.checkFound = checkFound
self.foundVar = foundVar or "found"
@ -9832,12 +9832,12 @@ class CGProxySpecialOperation(CGPerSignatureCall):
treatNullAs=argument.treatNullAs,
sourceDescription=("value being assigned to %s setter" %
descriptor.interface.identifier.name))
if argumentMutableValue is None:
argumentMutableValue = "desc.value()"
if argumentHandleValue is None:
argumentHandleValue = "desc.value()"
templateValues = {
"declName": argument.identifier.name,
"holderName": argument.identifier.name + "_holder",
"val": argumentMutableValue,
"val": argumentHandleValue,
"obj": "obj",
"passedToJSImpl": "false"
}
@ -9882,10 +9882,10 @@ class CGProxyIndexedOperation(CGProxySpecialOperation):
foundVar: See the docstring for CGProxySpecialOperation.
"""
def __init__(self, descriptor, name, doUnwrap=True, checkFound=True,
argumentMutableValue=None, resultVar=None, foundVar=None):
argumentHandleValue=None, resultVar=None, foundVar=None):
self.doUnwrap = doUnwrap
CGProxySpecialOperation.__init__(self, descriptor, name, checkFound,
argumentMutableValue=argumentMutableValue,
argumentHandleValue=argumentHandleValue,
resultVar=resultVar,
foundVar=foundVar)
@ -9943,9 +9943,9 @@ class CGProxyIndexedSetter(CGProxyIndexedOperation):
"""
Class to generate a call to an indexed setter.
"""
def __init__(self, descriptor, argumentMutableValue=None):
def __init__(self, descriptor, argumentHandleValue=None):
CGProxyIndexedOperation.__init__(self, descriptor, 'IndexedSetter',
argumentMutableValue=argumentMutableValue)
argumentHandleValue=argumentHandleValue)
class CGProxyIndexedDeleter(CGProxyIndexedOperation):
@ -9973,10 +9973,10 @@ class CGProxyNamedOperation(CGProxySpecialOperation):
foundVar: See the docstring for CGProxySpecialOperation.
"""
def __init__(self, descriptor, name, value=None, argumentMutableValue=None,
def __init__(self, descriptor, name, value=None, argumentHandleValue=None,
resultVar=None, foundVar=None):
CGProxySpecialOperation.__init__(self, descriptor, name,
argumentMutableValue=argumentMutableValue,
argumentHandleValue=argumentHandleValue,
resultVar=resultVar,
foundVar=foundVar)
self.value = value
@ -10074,9 +10074,9 @@ class CGProxyNamedSetter(CGProxyNamedOperation):
"""
Class to generate a call to a named setter.
"""
def __init__(self, descriptor, argumentMutableValue=None):
def __init__(self, descriptor, argumentHandleValue=None):
CGProxyNamedOperation.__init__(self, descriptor, 'NamedSetter',
argumentMutableValue=argumentMutableValue)
argumentHandleValue=argumentHandleValue)
class CGProxyNamedDeleter(CGProxyNamedOperation):
@ -10693,7 +10693,7 @@ class CGDOMJSProxyHandler_setCustom(ClassMethod):
args = [Argument('JSContext*', 'cx'),
Argument('JS::Handle<JSObject*>', 'proxy'),
Argument('JS::Handle<jsid>', 'id'),
Argument('JS::MutableHandle<JS::Value>', 'vp'),
Argument('JS::Handle<JS::Value>', 'v'),
Argument('bool*', 'done')]
ClassMethod.__init__(self, "setCustom", "bool", args, virtual=True, override=True, const=True)
self.descriptor = descriptor
@ -10718,7 +10718,7 @@ class CGDOMJSProxyHandler_setCustom(ClassMethod):
raise ValueError("In interface " + self.descriptor.name + ": " +
"Can't cope with [OverrideBuiltins] and unforgeable members")
callSetter = CGProxyNamedSetter(self.descriptor, argumentMutableValue="vp")
callSetter = CGProxyNamedSetter(self.descriptor, argumentHandleValue="v")
return (assertion +
callSetter.define() +
"*done = true;\n"
@ -10743,7 +10743,7 @@ class CGDOMJSProxyHandler_setCustom(ClassMethod):
""",
callSetter=CGProxyIndexedSetter(self.descriptor,
argumentMutableValue="vp").define())
argumentHandleValue="v").define())
else:
setIndexed = ""

View File

@ -219,13 +219,14 @@ DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::
}
bool
DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<JSObject*> receiver,
Handle<jsid> id, MutableHandle<JS::Value> vp, ObjectOpResult &result) const
DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<jsid> id,
Handle<JS::Value> v, Handle<JS::Value> receiver,
ObjectOpResult &result) const
{
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
"Should not have a XrayWrapper here");
bool done;
if (!setCustom(cx, proxy, id, vp, &done)) {
if (!setCustom(cx, proxy, id, v, &done)) {
return false;
}
if (done) {
@ -252,7 +253,7 @@ DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<JSObject*> r
}
}
return js::SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, desc, result);
return js::SetPropertyIgnoringNamedGetter(cx, proxy, id, v, receiver, desc, result);
}
bool
@ -350,7 +351,7 @@ IdToInt32(JSContext* cx, JS::Handle<jsid> id)
bool
DOMProxyHandler::setCustom(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::MutableHandle<JS::Value> vp, bool *done) const
JS::Handle<JS::Value> v, bool *done) const
{
*done = false;
return true;

View File

@ -122,8 +122,8 @@ public:
const override;
bool has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
bool* bp) const override;
bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp, JS::ObjectOpResult &result)
bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver, JS::ObjectOpResult &result)
const override;
/*
@ -132,7 +132,7 @@ public:
* *done to false.
*/
virtual bool setCustom(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::MutableHandle<JS::Value> vp, bool *done) const;
JS::Handle<JS::Value> v, bool *done) const;
static JSObject* GetExpandoObject(JSObject* obj);

View File

@ -71,10 +71,9 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
ReturnStatus *rs, JSVariant *result) {
return Answer::RecvGet(ObjectId::deserialize(objId), receiverVar, id, rs, result);
}
bool RecvSet(const uint64_t &objId, const ObjectVariant &receiverVar,
const JSIDVariant &id, const JSVariant &value, ReturnStatus *rs,
JSVariant *result) {
return Answer::RecvSet(ObjectId::deserialize(objId), receiverVar, id, value, rs, result);
bool RecvSet(const uint64_t &objId, const JSIDVariant &id, const JSVariant &value,
const JSVariant &receiverVar, ReturnStatus *rs) {
return Answer::RecvSet(ObjectId::deserialize(objId), id, value, receiverVar, rs);
}
bool RecvIsExtensible(const uint64_t &objId, ReturnStatus *rs,
@ -161,10 +160,9 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
ReturnStatus *rs, JSVariant *result) {
return Base::SendGet(objId.serialize(), receiverVar, id, rs, result);
}
bool SendSet(const ObjectId &objId, const ObjectVariant &receiverVar,
const JSIDVariant &id, const JSVariant &value, ReturnStatus *rs,
JSVariant *result) {
return Base::SendSet(objId.serialize(), receiverVar, id, value, rs, result);
bool SendSet(const ObjectId &objId, const JSIDVariant &id, const JSVariant &value,
const JSVariant &receiverVar, ReturnStatus *rs) {
return Base::SendSet(objId.serialize(), id, value, receiverVar, rs);
}
bool SendIsExtensible(const ObjectId &objId, ReturnStatus *rs,

View File

@ -33,7 +33,7 @@ both:
prio(high) sync Has(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
prio(high) sync HasOwn(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
prio(high) sync Get(uint64_t objId, ObjectVariant receiver, JSIDVariant id) returns (ReturnStatus rs, JSVariant result);
prio(high) sync Set(uint64_t objId, ObjectVariant receiver, JSIDVariant id, JSVariant value) returns (ReturnStatus rs, JSVariant result);
prio(high) sync Set(uint64_t objId, JSIDVariant id, JSVariant value, JSVariant receiver) returns (ReturnStatus rs);
prio(high) sync IsExtensible(uint64_t objId) returns (ReturnStatus rs, bool result);
prio(high) sync CallOrConstruct(uint64_t objId, JSParam[] argv, bool construct) returns (ReturnStatus rs, JSVariant result, JSParam[] outparams);

View File

@ -308,26 +308,17 @@ WrapperAnswer::RecvGet(const ObjectId &objId, const ObjectVariant &receiverVar,
}
bool
WrapperAnswer::RecvSet(const ObjectId &objId, const ObjectVariant &receiverVar,
const JSIDVariant &idVar, const JSVariant &value, ReturnStatus *rs,
JSVariant *resultValue)
WrapperAnswer::RecvSet(const ObjectId &objId, const JSIDVariant &idVar, const JSVariant &value,
const JSVariant &receiverVar, ReturnStatus *rs)
{
// We may run scripted setters.
AutoEntryScript aes(xpc::NativeGlobal(scopeForTargetObjects()));
JSContext *cx = aes.cx();
// The outparam will be written to the buffer, so it must be set even if
// the parent won't read it.
*resultValue = UndefinedVariant();
RootedObject obj(cx, findObjectById(cx, objId));
if (!obj)
return fail(cx, rs);
RootedObject receiver(cx, fromObjectVariant(cx, receiverVar));
if (!receiver)
return fail(cx, rs);
LOG("set %s[%s] = %s", ReceiverObj(objId), Identifier(idVar), InVariant(value));
RootedId id(cx);
@ -338,12 +329,12 @@ WrapperAnswer::RecvSet(const ObjectId &objId, const ObjectVariant &receiverVar,
if (!fromVariant(cx, value, &val))
return fail(cx, rs);
ObjectOpResult result;
RootedValue receiverVal(cx, ObjectValue(*receiver));
if (!JS_ForwardSetPropertyTo(cx, obj, id, val, receiverVal, result))
RootedValue receiver(cx);
if (!fromVariant(cx, receiverVar, &receiver))
return fail(cx, rs);
if (!toVariant(cx, val, resultValue))
ObjectOpResult result;
if (!JS_ForwardSetPropertyTo(cx, obj, id, val, receiver, result))
return fail(cx, rs);
return ok(rs, result);

View File

@ -37,9 +37,8 @@ class WrapperAnswer : public virtual JavaScriptShared
bool RecvGet(const ObjectId &objId, const ObjectVariant &receiverVar,
const JSIDVariant &id,
ReturnStatus *rs, JSVariant *result);
bool RecvSet(const ObjectId &objId, const ObjectVariant &receiverVar,
const JSIDVariant &id, const JSVariant &value, ReturnStatus *rs,
JSVariant *result);
bool RecvSet(const ObjectId &objId, const JSIDVariant &id, const JSVariant &value,
const JSVariant &receiverVar, ReturnStatus *rs);
bool RecvIsExtensible(const ObjectId &objId, ReturnStatus *rs,
bool *result);

View File

@ -110,9 +110,8 @@ class CPOWProxyHandler : public BaseProxyHandler
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const override;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp) const override;
virtual bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, JS::MutableHandleValue vp,
JS::ObjectOpResult &result) const override;
virtual bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue v,
JS::HandleValue receiver, JS::ObjectOpResult &result) const override;
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;
@ -517,41 +516,37 @@ WrapperOwner::get(JSContext *cx, HandleObject proxy, HandleObject receiver,
}
bool
CPOWProxyHandler::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result) const
CPOWProxyHandler::set(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue v,
JS::HandleValue receiver, JS::ObjectOpResult &result) const
{
FORWARD(set, (cx, proxy, receiver, id, vp, result));
FORWARD(set, (cx, proxy, id, v, receiver, result));
}
bool
WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result)
WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue v,
JS::HandleValue receiver, JS::ObjectOpResult &result)
{
ObjectId objId = idOf(proxy);
ObjectVariant receiverVar;
if (!toObjectVariant(cx, receiver, &receiverVar))
return false;
JSIDVariant idVar;
if (!toJSIDVariant(cx, id, &idVar))
return false;
JSVariant val;
if (!toVariant(cx, vp, &val))
if (!toVariant(cx, v, &val))
return false;
JSVariant receiverVar;
if (!toVariant(cx, receiver, &receiverVar))
return false;
ReturnStatus status;
JSVariant resultValue;
if (!SendSet(objId, receiverVar, idVar, val, &status, &resultValue))
if (!SendSet(objId, idVar, val, receiverVar, &status))
return ipcfail(cx);
LOG_STACK();
if (!ok(cx, status, result))
return false;
return fromVariant(cx, resultValue, vp);
return ok(cx, status, result);
}
bool

View File

@ -42,8 +42,8 @@ class WrapperOwner : public virtual JavaScriptShared
bool has(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, bool *bp);
bool get(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, JS::MutableHandleValue vp);
bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result);
bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue v,
JS::HandleValue receiver, JS::ObjectOpResult &result);
bool callOrConstruct(JSContext *cx, JS::HandleObject proxy, const JS::CallArgs &args,
bool construct);
@ -128,9 +128,8 @@ class WrapperOwner : public virtual JavaScriptShared
virtual bool SendGet(const ObjectId &objId, const ObjectVariant &receiverVar,
const JSIDVariant &id,
ReturnStatus *rs, JSVariant *result) = 0;
virtual bool SendSet(const ObjectId &objId, const ObjectVariant &receiverVar,
const JSIDVariant &id, const JSVariant &value,
ReturnStatus *rs, JSVariant *result) = 0;
virtual bool SendSet(const ObjectId &objId, const JSIDVariant &id, const JSVariant &value,
const JSVariant &receiverVar, ReturnStatus *rs) = 0;
virtual bool SendIsExtensible(const ObjectId &objId, ReturnStatus *rs,
bool *result) = 0;

View File

@ -342,8 +342,8 @@ typedef bool
(* GetPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
JS::MutableHandleValue vp);
typedef bool
(* SetPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
JS::MutableHandleValue vp, JS::ObjectOpResult &result);
(* SetPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v,
JS::HandleValue receiver, JS::ObjectOpResult &result);
typedef bool
(* GetOwnPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);

View File

@ -295,8 +295,8 @@ class JS_FRIEND_API(BaseProxyHandler)
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp) const;
virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const;
virtual bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const;
/*
* [[Call]] and [[Construct]] are standard internal methods but according
@ -395,9 +395,8 @@ class JS_FRIEND_API(DirectProxyHandler) : public BaseProxyHandler
bool *bp) const override;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp) const override;
virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp,
ObjectOpResult &result) const override;
virtual bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const override;
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;

View File

@ -1904,8 +1904,8 @@ TypedObject::obj_getArrayElement(JSContext *cx,
}
bool
TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result)
TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result)
{
Rooted<TypedObject *> typedObj(cx, &obj->as<TypedObject>());
@ -1919,7 +1919,7 @@ TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject recei
case type::Array: {
if (JSID_IS_ATOM(id, cx->names().length)) {
if (obj == receiver) {
if (receiver.isObject() && obj == &receiver.toObject()) {
JS_ReportErrorNumber(cx, GetErrorMessage,
nullptr, JSMSG_CANT_REDEFINE_ARRAY_LENGTH);
return false;
@ -1929,8 +1929,8 @@ TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject recei
uint32_t index;
if (IdIsIndex(id, &index)) {
if (obj != receiver)
return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result);
if (!receiver.isObject() || obj != &receiver.toObject())
return SetPropertyByDefining(cx, obj, id, v, receiver, false, result);
if (index >= uint32_t(typedObj->length())) {
JS_ReportErrorNumber(cx, GetErrorMessage,
@ -1941,7 +1941,7 @@ TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject recei
Rooted<TypeDescr*> elementType(cx);
elementType = &typedObj->typeDescr().as<ArrayTypeDescr>().elementType();
size_t offset = elementType->size() * index;
if (!ConvertAndCopyTo(cx, elementType, typedObj, offset, NullPtr(), vp))
if (!ConvertAndCopyTo(cx, elementType, typedObj, offset, NullPtr(), v))
return false;
return result.succeed();
}
@ -1955,19 +1955,19 @@ TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject recei
if (!descr->fieldIndex(id, &fieldIndex))
break;
if (obj != receiver)
return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result);
if (!receiver.isObject() || obj != &receiver.toObject())
return SetPropertyByDefining(cx, obj, id, v, receiver, false, result);
size_t offset = descr->fieldOffset(fieldIndex);
Rooted<TypeDescr*> fieldType(cx, &descr->fieldDescr(fieldIndex));
RootedAtom fieldName(cx, &descr->fieldName(fieldIndex));
if (!ConvertAndCopyTo(cx, fieldType, typedObj, offset, fieldName, vp))
if (!ConvertAndCopyTo(cx, fieldType, typedObj, offset, fieldName, v))
return false;
return result.succeed();
}
}
return SetPropertyOnProto(cx, obj, receiver, id, vp, result);
return SetPropertyOnProto(cx, obj, id, v, receiver, result);
}
bool

View File

@ -540,8 +540,8 @@ class TypedObject : public JSObject
static bool obj_getElement(JSContext *cx, HandleObject obj, HandleObject receiver,
uint32_t index, MutableHandleValue vp);
static bool obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result);
static bool obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result);
static bool obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc);

View File

@ -8366,7 +8366,7 @@ DoSetPropFallback(JSContext *cx, BaselineFrame *frame, ICSetProp_Fallback *stub_
MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP);
RootedValue v(cx, rhs);
if (!PutProperty(cx, obj, id, &v, op == JSOP_STRICTSETPROP))
if (!PutProperty(cx, obj, id, v, op == JSOP_STRICTSETPROP))
return false;
}

View File

@ -2218,11 +2218,11 @@ EmitObjectOpResultCheck(MacroAssembler &masm, Label *failure, bool strict,
}
static bool
ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue vp,
bool strict)
ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, bool strict)
{
RootedValue receiver(cx, ObjectValue(*proxy));
ObjectOpResult result;
return Proxy::set(cx, proxy, proxy, id, vp, result)
return Proxy::set(cx, proxy, id, v, receiver, result)
&& result.checkStrictErrorOrWarning(cx, proxy, id, strict);
}
@ -2243,12 +2243,12 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
RegisterSet regSet(RegisterSet::All());
regSet.take(AnyRegister(object));
// ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, MutableHandleValue vp,
// ProxySetProperty(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
// bool strict);
Register argJSContextReg = regSet.takeGeneral();
Register argProxyReg = regSet.takeGeneral();
Register argIdReg = regSet.takeGeneral();
Register argVpReg = regSet.takeGeneral();
Register argValueReg = regSet.takeGeneral();
Register argStrictReg = regSet.takeGeneral();
Register scratch = regSet.takeGeneral();
@ -2259,7 +2259,7 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
// Push args on stack so we can take pointers to make handles.
// Push value before touching any other registers (see WARNING above).
masm.Push(value);
masm.movePtr(StackPointer, argVpReg);
masm.movePtr(StackPointer, argValueReg);
masm.move32(Imm32(strict), argStrictReg);
@ -2283,7 +2283,7 @@ EmitCallProxySet(JSContext *cx, MacroAssembler &masm, IonCache::StubAttacher &at
masm.passABIArg(argJSContextReg);
masm.passABIArg(argProxyReg);
masm.passABIArg(argIdReg);
masm.passABIArg(argVpReg);
masm.passABIArg(argValueReg);
masm.passABIArg(argStrictReg);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ProxySetProperty));
@ -2508,7 +2508,7 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
MOZ_ASSERT(target);
// JSSetterOp: bool fn(JSContext *cx, HandleObject obj,
// HandleId id, MutableHandleValue vp, ObjectOpResult &result);
// HandleId id, HandleValue value, ObjectOpResult &result);
// First, allocate an ObjectOpResult on the stack. We push this before
// the stubCode pointer in order to match the layout of
@ -2529,11 +2529,11 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
// OK, now we can grab our remaining registers and grab the pointer to
// what we just pushed into one of them.
Register argJSContextReg = regSet.takeGeneral();
Register argVpReg = regSet.takeGeneral();
Register argValueReg = regSet.takeGeneral();
// We can just reuse the "object" register for argObjReg
Register argObjReg = object;
Register argIdReg = regSet.takeGeneral();
masm.movePtr(StackPointer, argVpReg);
masm.movePtr(StackPointer, argValueReg);
// push canonical jsid from shape instead of propertyname.
masm.Push(shape->propid(), argIdReg);
@ -2553,7 +2553,7 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
masm.passABIArg(argJSContextReg);
masm.passABIArg(argObjReg);
masm.passABIArg(argIdReg);
masm.passABIArg(argVpReg);
masm.passABIArg(argValueReg);
masm.passABIArg(argResultReg);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, target));
@ -2565,7 +2565,8 @@ GenerateCallSetter(JSContext *cx, IonScript *ion, MacroAssembler &masm,
EmitObjectOpResultCheck<IonOOLSetterOpExitFrameLayout>(masm, masm.exceptionLabel(),
strict, scratchReg,
argJSContextReg, argObjReg,
argIdReg, argVpReg, argResultReg);
argIdReg, argValueReg,
argResultReg);
// masm.leaveExitFrame & pop locals.
masm.adjustStack(IonOOLSetterOpExitFrameLayout::Size());

View File

@ -434,7 +434,6 @@ bool
SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValue value,
bool strict, jsbytecode *pc)
{
RootedValue v(cx, value);
RootedId id(cx, NameToId(name));
JSOp op = JSOp(*pc);
@ -448,21 +447,21 @@ SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValu
return true;
}
RootedValue receiver(cx, ObjectValue(*obj));
ObjectOpResult result;
if (MOZ_LIKELY(!obj->getOps()->setProperty)) {
if (!NativeSetProperty(
cx, obj.as<NativeObject>(), obj.as<NativeObject>(), id,
cx, obj.as<NativeObject>(), id, value, receiver,
(op == JSOP_SETNAME || op == JSOP_STRICTSETNAME ||
op == JSOP_SETGNAME || op == JSOP_STRICTSETGNAME)
? Unqualified
: Qualified,
&v,
result))
{
return false;
}
} else {
if (!SetProperty(cx, obj, obj, id, &v, result))
if (!SetProperty(cx, obj, id, value, receiver, result))
return false;
}
return result.checkStrictErrorOrWarning(cx, obj, id, strict);

View File

@ -82,6 +82,7 @@ MSG_DEF(JSMSG_EMPTY_ARRAY_REDUCE, 0, JSEXN_TYPEERR, "reduce of empty array
MSG_DEF(JSMSG_UNEXPECTED_TYPE, 2, JSEXN_TYPEERR, "{0} is {1}")
MSG_DEF(JSMSG_MISSING_FUN_ARG, 2, JSEXN_TYPEERR, "missing argument {0} when calling function {1}")
MSG_DEF(JSMSG_NOT_NONNULL_OBJECT, 1, JSEXN_TYPEERR, "{0} is not a non-null object")
MSG_DEF(JSMSG_SET_NON_OBJECT_RECEIVER, 1, JSEXN_TYPEERR, "can't assign to properties of {0}: not an object")
MSG_DEF(JSMSG_INVALID_DESCRIPTOR, 0, JSEXN_TYPEERR, "property descriptors must not specify a value or be writable when a getter or setter has been specified")
MSG_DEF(JSMSG_OBJECT_NOT_EXTENSIBLE, 1, JSEXN_TYPEERR, "{0} is not extensible")
MSG_DEF(JSMSG_CANT_REDEFINE_PROP, 1, JSEXN_TYPEERR, "can't redefine non-configurable property {0}")

View File

@ -27,13 +27,13 @@ class CustomProxyHandler : public DirectProxyHandler {
return impl(cx, proxy, id, desc, true);
}
bool set(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const override
bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver,
ObjectOpResult &result) const override
{
Rooted<JSPropertyDescriptor> desc(cx);
if (!DirectProxyHandler::getPropertyDescriptor(cx, proxy, id, &desc))
return false;
return SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, desc, result);
return SetPropertyIgnoringNamedGetter(cx, proxy, id, v, receiver, desc, result);
}
private:

View File

@ -147,7 +147,7 @@ JS::ObjectOpResult::reportStrictErrorOrWarning(JSContext *cx, HandleObject obj,
MOZ_ASSERT(!ok());
unsigned flags = strict ? JSREPORT_ERROR : (JSREPORT_WARNING | JSREPORT_STRICT);
if (code_ == JSMSG_OBJECT_NOT_EXTENSIBLE) {
if (code_ == JSMSG_OBJECT_NOT_EXTENSIBLE || code_ == JSMSG_SET_NON_OBJECT_RECEIVER) {
RootedValue val(cx, ObjectValue(*obj));
return ReportValueErrorFlags(cx, flags, code_, JSDVG_IGNORE_STACK, val,
NullPtr(), nullptr, nullptr);
@ -2818,13 +2818,13 @@ JS_GetUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t n
JS_PUBLIC_API(bool)
JS_SetPropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue v)
{
RootedValue value(cx, v);
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, id);
RootedValue receiver(cx, ObjectValue(*obj));
ObjectOpResult ignored;
return SetProperty(cx, obj, obj, id, &value, ignored);
return SetProperty(cx, obj, id, v, receiver, ignored);
}
JS_PUBLIC_API(bool)
@ -2835,66 +2835,60 @@ JS_ForwardSetPropertyTo(JSContext *cx, HandleObject obj, HandleId id, HandleValu
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, id, receiver);
// XXX Bug 603201 will eliminate this ToObject.
RootedObject receiverObj(cx, ToObject(cx, receiver));
if (!receiverObj)
return false;
RootedValue value(cx, v);
return SetProperty(cx, obj, receiverObj, id, &value, result);
return SetProperty(cx, obj, id, v, receiver, result);
}
static bool
SetElement(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleValue vp)
SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, vp);
assertSameCompartment(cx, obj, v);
RootedValue receiver(cx, ObjectValue(*obj));
ObjectOpResult ignored;
return SetElement(cx, obj, obj, index, vp, ignored);
return SetElement(cx, obj, index, v, receiver, ignored);
}
JS_PUBLIC_API(bool)
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v)
{
RootedValue value(cx, v);
return SetElement(cx, obj, index, &value);
return SetElement(cx, obj, index, v);
}
JS_PUBLIC_API(bool)
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleObject v)
{
RootedValue value(cx, ObjectOrNullValue(v));
return SetElement(cx, obj, index, &value);
return SetElement(cx, obj, index, value);
}
JS_PUBLIC_API(bool)
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleString v)
{
RootedValue value(cx, StringValue(v));
return SetElement(cx, obj, index, &value);
return SetElement(cx, obj, index, value);
}
JS_PUBLIC_API(bool)
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, int32_t v)
{
RootedValue value(cx, NumberValue(v));
return SetElement(cx, obj, index, &value);
return SetElement(cx, obj, index, value);
}
JS_PUBLIC_API(bool)
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, uint32_t v)
{
RootedValue value(cx, NumberValue(v));
return SetElement(cx, obj, index, &value);
return SetElement(cx, obj, index, value);
}
JS_PUBLIC_API(bool)
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, double v)
{
RootedValue value(cx, NumberValue(v));
return SetElement(cx, obj, index, &value);
return SetElement(cx, obj, index, value);
}
JS_PUBLIC_API(bool)

View File

@ -364,8 +364,7 @@ SetArrayElement(JSContext *cx, HandleObject obj, double index, HandleValue v)
if (!ToId(cx, index, &id))
return false;
RootedValue tmp(cx, v);
return SetProperty(cx, obj, obj, id, &tmp);
return SetProperty(cx, obj, id, v);
}
/*
@ -434,7 +433,7 @@ bool
js::SetLengthProperty(JSContext *cx, HandleObject obj, double length)
{
RootedValue v(cx, NumberValue(length));
return SetProperty(cx, obj, obj, cx->names().length, &v);
return SetProperty(cx, obj, cx->names().length, v);
}
/*
@ -1270,11 +1269,10 @@ InitArrayElements(JSContext *cx, HandleObject obj, uint32_t start, uint32_t coun
do {
value = *vector++;
indexv = DoubleValue(index);
if (!ValueToId<CanGC>(cx, indexv, &id) ||
!SetProperty(cx, obj, obj, id, &value))
{
if (!ValueToId<CanGC>(cx, indexv, &id))
return false;
if (!SetProperty(cx, obj, id, value))
return false;
}
index += 1;
} while (vector != end);

View File

@ -368,8 +368,8 @@ extern JS_FRIEND_API(bool)
proxy_GetProperty(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
JS::MutableHandleValue vp);
extern JS_FRIEND_API(bool)
proxy_SetProperty(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
JS::MutableHandleValue bp, JS::ObjectOpResult &result);
proxy_SetProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue bp,
JS::HandleValue receiver, JS::ObjectOpResult &result);
extern JS_FRIEND_API(bool)
proxy_GetOwnPropertyDescriptor(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
@ -2627,7 +2627,7 @@ ForwardToNative(JSContext *cx, JSNative native, const JS::CallArgs &args);
*/
JS_FRIEND_API(bool)
SetPropertyIgnoringNamedGetter(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandleValue vp, JS::HandleObject receiver,
JS::HandleValue v, JS::HandleValue receiver,
JS::Handle<JSPropertyDescriptor> ownDesc,
JS::ObjectOpResult &result);

View File

@ -1575,25 +1575,26 @@ js::CreateThisForFunction(JSContext *cx, HandleObject callee, NewObjectKind newK
}
/* static */ bool
JSObject::nonNativeSetProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
JSObject::nonNativeSetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result)
{
RootedValue value(cx, v);
if (MOZ_UNLIKELY(obj->watched())) {
WatchpointMap *wpmap = cx->compartment()->watchpointMap;
if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, vp))
if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, &value))
return false;
}
return obj->getOps()->setProperty(cx, obj, receiver, id, vp, result);
return obj->getOps()->setProperty(cx, obj, id, value, receiver, result);
}
/* static */ bool
JSObject::nonNativeSetElement(JSContext *cx, HandleObject obj, HandleObject receiver,
uint32_t index, MutableHandleValue vp, ObjectOpResult &result)
JSObject::nonNativeSetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v,
HandleValue receiver, ObjectOpResult &result)
{
RootedId id(cx);
if (!IndexToId(cx, index, &id))
return false;
return nonNativeSetProperty(cx, obj, receiver, id, vp, result);
return nonNativeSetProperty(cx, obj, id, v, receiver, result);
}
JS_FRIEND_API(bool)
@ -3259,22 +3260,6 @@ js::DefineElement(ExclusiveContext *cx, HandleObject obj, uint32_t index, Handle
return DefineProperty(cx, obj, id, value, getter, setter, attrs);
}
bool
js::SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandlePropertyName name,
MutableHandleValue vp)
{
RootedId id(cx, NameToId(name));
return SetProperty(cx, obj, receiver, id, vp);
}
bool
js::PutProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, MutableHandleValue value,
bool strict)
{
RootedId id(cx, NameToId(name));
return PutProperty(cx, obj, id, value, strict);
}
/*** SpiderMonkey nonstandard internal methods ***************************************************/

View File

@ -474,12 +474,12 @@ class JSObject : public js::gc::Cell
bool callMethod(JSContext *cx, js::HandleId id, unsigned argc, js::Value *argv,
js::MutableHandleValue vp);
static bool nonNativeSetProperty(JSContext *cx, js::HandleObject obj,
js::HandleObject receiver, js::HandleId id,
js::MutableHandleValue vp, JS::ObjectOpResult &result);
static bool nonNativeSetElement(JSContext *cx, js::HandleObject obj,
js::HandleObject receiver, uint32_t index,
js::MutableHandleValue vp, JS::ObjectOpResult &result);
static bool nonNativeSetProperty(JSContext *cx, js::HandleObject obj, js::HandleId id,
js::HandleValue v, js::HandleValue receiver,
JS::ObjectOpResult &result);
static bool nonNativeSetElement(JSContext *cx, js::HandleObject obj, uint32_t index,
js::HandleValue v, js::HandleValue receiver,
JS::ObjectOpResult &result);
static bool swap(JSContext *cx, JS::HandleObject a, JS::HandleObject b);
@ -849,49 +849,52 @@ inline bool
GetElementNoGC(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp);
/*
* ES6 [[Set]]. Carry out the assignment `obj[id] = vp`.
* ES6 [[Set]]. Carry out the assignment `obj[id] = v`.
*
* The `receiver` argument has to do with how [[Set]] interacts with the
* prototype chain and proxies. It's hard to explain and ES6 doesn't really
* try. Long story short, if you just want bog-standard assignment, pass the
* same object as both obj and receiver.
* try. Long story short, if you just want bog-standard assignment, pass
* `ObjectValue(*obj)` as receiver. Or better, use one of the signatures that
* doesn't have a receiver parameter.
*
* When obj != receiver, it's a reasonable guess that a proxy is involved, obj
* is the proxy's target, and the proxy is using SetProperty to finish an
* assignment that started out as `receiver[id] = vp`, by delegating it to obj.
*
* Strict errors: ES6 specifies that this method returns a boolean value
* indicating whether assignment "succeeded". We currently take a `strict`
* argument instead, but this has to change. See bug 1113369.
* Callers pass obj != receiver e.g. when a proxy is involved, obj is the
* proxy's target, and the proxy is using SetProperty to finish an assignment
* that started out as `receiver[id] = v`, by delegating it to obj.
*/
inline bool
SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result);
SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result);
inline bool
SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, PropertyName *name,
MutableHandleValue vp, ObjectOpResult &result)
SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v)
{
RootedValue receiver(cx, ObjectValue(*obj));
ObjectOpResult result;
return SetProperty(cx, obj, id, v, receiver, result) &&
result.checkStrict(cx, obj, id);
}
inline bool
SetProperty(JSContext *cx, HandleObject obj, PropertyName *name, HandleValue v,
HandleValue receiver, ObjectOpResult &result)
{
RootedId id(cx, NameToId(name));
return SetProperty(cx, obj, receiver, id, vp, result);
return SetProperty(cx, obj, id, v, receiver, result);
}
inline bool
SetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index,
MutableHandleValue vp, ObjectOpResult &result);
inline bool
SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
MutableHandleValue vp)
SetProperty(JSContext *cx, HandleObject obj, PropertyName *name, HandleValue v)
{
RootedId id(cx, NameToId(name));
RootedValue receiver(cx, ObjectValue(*obj));
ObjectOpResult result;
return SetProperty(cx, obj, receiver, id, vp, result) &&
result.checkStrict(cx, receiver, id);
return SetProperty(cx, obj, id, v, receiver, result) &&
result.checkStrict(cx, obj, id);
}
extern bool
SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandlePropertyName name,
MutableHandleValue vp);
inline bool
SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v,
HandleValue receiver, ObjectOpResult &result);
/*
* ES6 draft rev 31 (15 Jan 2015) 7.3.3 Put (O, P, V, Throw), except that on
@ -899,17 +902,14 @@ SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleProper
* don't bother doing.
*/
inline bool
PutProperty(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue value, bool strict)
PutProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, bool strict)
{
RootedValue receiver(cx, ObjectValue(*obj));
ObjectOpResult result;
return SetProperty(cx, obj, obj, id, value, result) &&
return SetProperty(cx, obj, id, v, receiver, result) &&
result.checkStrictErrorOrWarning(cx, obj, id, strict);
}
extern bool
PutProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, MutableHandleValue value,
bool strict);
/*
* ES6 [[Delete]]. Equivalent to the JS code `delete obj[id]`.
*/

View File

@ -2180,7 +2180,7 @@ class MOZ_STACK_CLASS StringRegExpGuard
// Handle everything else generically (including throwing if .lastIndex is non-writable).
RootedValue zero(cx, Int32Value(0));
return SetProperty(cx, obj_, obj_, cx->names().lastIndex, &zero);
return SetProperty(cx, obj_, cx->names().lastIndex, zero);
}
RegExpShared &regExp() { return *re_; }

View File

@ -137,8 +137,8 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
virtual bool has(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const override;
virtual bool get(JSContext *cx, HandleObject wrapper, HandleObject receiver,
HandleId id, MutableHandleValue vp) const override;
virtual bool set(JSContext *cx, HandleObject wrapper, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result) const override;
virtual bool set(JSContext *cx, HandleObject wrapper, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const override;
virtual bool call(JSContext *cx, HandleObject wrapper, const CallArgs &args) const override;
virtual bool construct(JSContext *cx, HandleObject wrapper, const CallArgs &args) const override;

View File

@ -61,8 +61,7 @@ BaseProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject receiver,
return true;
}
if (desc.hasGetterObject())
return InvokeGetterOrSetter(cx, receiver, ObjectValue(*desc.getterObject()),
0, nullptr, vp);
return InvokeGetter(cx, receiver, ObjectValue(*desc.getterObject()), vp);
if (!desc.isShared())
vp.set(desc.value());
else
@ -72,8 +71,8 @@ BaseProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject receiver,
}
bool
BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const
{
assertEnteredPolicy(cx, proxy, id, SET);
@ -88,13 +87,12 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
// The rest is factored out into a separate function with a weird name.
// This algorithm continues just below.
return SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, ownDesc, result);
return SetPropertyIgnoringNamedGetter(cx, proxy, id, v, receiver, ownDesc, result);
}
bool
js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id,
MutableHandleValue vp, HandleObject receiver,
Handle<PropertyDescriptor> ownDesc_,
js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, Handle<PropertyDescriptor> ownDesc_,
ObjectOpResult &result)
{
Rooted<PropertyDescriptor> ownDesc(cx, ownDesc_);
@ -107,7 +105,7 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id,
if (!GetPrototype(cx, obj, &proto))
return false;
if (proto)
return SetProperty(cx, proto, receiver, id, vp, result);
return SetProperty(cx, proto, id, v, receiver, result);
// Step 4.d.
ownDesc.setDataDescriptor(UndefinedHandleValue, JSPROP_ENUMERATE);
@ -118,17 +116,22 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id,
// Steps 5.a-b.
if (!ownDesc.writable())
return result.fail(JSMSG_READ_ONLY);
if (!receiver.isObject())
return result.fail(JSMSG_SET_NON_OBJECT_RECEIVER);
RootedObject receiverObj(cx, &receiver.toObject());
// Nonstandard SpiderMonkey special case: setter ops.
SetterOp setter = ownDesc.setter();
MOZ_ASSERT(setter != JS_StrictPropertyStub);
if (setter && setter != JS_StrictPropertyStub)
return CallJSSetterOp(cx, setter, receiver, id, vp, result);
if (setter && setter != JS_StrictPropertyStub) {
RootedValue valCopy(cx, v);
return CallJSSetterOp(cx, setter, receiverObj, id, &valCopy, result);
}
// Steps 5.c-d. Adapt for SpiderMonkey by using HasOwnProperty instead
// of the standard [[GetOwnProperty]].
bool existingDescriptor;
if (!HasOwnProperty(cx, receiver, id, &existingDescriptor))
if (!HasOwnProperty(cx, receiverObj, id, &existingDescriptor))
return false;
// Steps 5.e-f.
@ -139,10 +142,10 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id,
// A very old nonstandard SpiderMonkey extension: default to the Class
// getter and setter ops.
const Class *clasp = receiver->getClass();
const Class *clasp = receiverObj->getClass();
MOZ_ASSERT(clasp->getProperty != JS_PropertyStub);
MOZ_ASSERT(clasp->setProperty != JS_StrictPropertyStub);
return DefineProperty(cx, receiver, id, vp, clasp->getProperty, clasp->setProperty,
return DefineProperty(cx, receiverObj, id, v, clasp->getProperty, clasp->setProperty,
attrs, result);
}
@ -154,7 +157,7 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id,
if (!setter)
return result.fail(JSMSG_GETTER_ONLY);
RootedValue setterValue(cx, ObjectValue(*setter));
if (!InvokeGetterOrSetter(cx, receiver, setterValue, 1, vp.address(), vp))
if (!InvokeSetter(cx, receiver, setterValue, v))
return false;
return result.succeed();
}

View File

@ -169,14 +169,15 @@ CrossCompartmentWrapper::get(JSContext *cx, HandleObject wrapper, HandleObject r
}
bool
CrossCompartmentWrapper::set(JSContext *cx, HandleObject wrapper, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
CrossCompartmentWrapper::set(JSContext *cx, HandleObject wrapper, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const
{
RootedObject receiverCopy(cx, receiver);
RootedValue valCopy(cx, v);
RootedValue receiverCopy(cx, receiver);
PIERCE(cx, wrapper,
cx->compartment()->wrap(cx, &receiverCopy) &&
cx->compartment()->wrap(cx, vp),
Wrapper::set(cx, wrapper, receiverCopy, id, vp, result),
cx->compartment()->wrap(cx, &valCopy) &&
cx->compartment()->wrap(cx, &receiverCopy),
Wrapper::set(cx, wrapper, id, valCopy, receiverCopy, result),
NOTHING);
}

View File

@ -216,12 +216,12 @@ DirectProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject receiver
}
bool
DirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
DirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const
{
assertEnteredPolicy(cx, proxy, id, SET);
RootedObject target(cx, proxy->as<ProxyObject>().target());
return SetProperty(cx, target, receiver, id, vp, result);
return SetProperty(cx, target, id, v, receiver, result);
}
bool

View File

@ -307,8 +307,8 @@ Proxy::callProp(JSContext *cx, HandleObject proxy, HandleObject receiver, Handle
}
bool
Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result)
Proxy::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver,
ObjectOpResult &result)
{
JS_CHECK_RECURSION(cx, return false);
const BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
@ -321,9 +321,9 @@ Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id
// Special case. See the comment on BaseProxyHandler::mHasPrototype.
if (handler->hasPrototype())
return handler->BaseProxyHandler::set(cx, proxy, receiver, id, vp, result);
return handler->BaseProxyHandler::set(cx, proxy, id, v, receiver, result);
return handler->set(cx, proxy, receiver, id, vp, result);
return handler->set(cx, proxy, id, v, receiver, result);
}
bool
@ -580,10 +580,10 @@ js::proxy_GetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, Ha
}
bool
js::proxy_SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result)
js::proxy_SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result)
{
return Proxy::set(cx, obj, receiver, id, vp, result);
return Proxy::set(cx, obj, id, v, receiver, result);
}
bool

View File

@ -42,8 +42,8 @@ class Proxy
static bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp);
static bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp);
static bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result);
static bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result);
static bool call(JSContext *cx, HandleObject proxy, const CallArgs &args);
static bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args);

View File

@ -922,8 +922,8 @@ ScriptedDirectProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject
// ES6 draft rev 32 (2015 Feb 2) 9.5.9 Proxy.[[Set]](P, V, Receiver)
bool
ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const
{
// step 2-3 (Steps 1 and 4 are irrelevant assertions.)
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
@ -940,7 +940,7 @@ ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject
// step 8
if (trap.isUndefined())
return SetProperty(cx, target, receiver, id, vp, result);
return SetProperty(cx, target, id, v, receiver, result);
// step 9-10
RootedValue value(cx);
@ -949,8 +949,8 @@ ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject
Value argv[] = {
ObjectOrNullValue(target),
value,
vp.get(),
ObjectValue(*receiver)
v.get(),
receiver.get()
};
RootedValue trapResult(cx);
if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult))
@ -969,7 +969,7 @@ ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject
if (desc.object()) {
if (desc.isDataDescriptor() && !desc.configurable() && !desc.writable()) {
bool same;
if (!SameValue(cx, vp, desc.value(), &same))
if (!SameValue(cx, v, desc.value(), &same))
return false;
if (!same) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_SET_NW_NC);

View File

@ -46,8 +46,8 @@ class ScriptedDirectProxyHandler : public BaseProxyHandler {
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const override;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp) const override;
virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result) const override;
virtual bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const override;
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;

View File

@ -304,34 +304,34 @@ ScriptedIndirectProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObjec
}
bool
ScriptedIndirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
ScriptedIndirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const
{
RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy));
RootedValue idv(cx);
if (!IdToStringOrSymbol(cx, id, &idv))
return false;
JS::AutoValueArray<3> argv(cx);
argv[0].setObjectOrNull(receiver);
argv[0].set(receiver);
argv[1].set(idv);
argv[2].set(vp);
argv[2].set(v);
RootedValue fval(cx);
if (!GetDerivedTrap(cx, handler, cx->names().set, &fval))
return false;
if (!IsCallable(fval))
return derivedSet(cx, proxy, receiver, id, vp, result);
return derivedSet(cx, proxy, id, v, receiver, result);
if (!Trap(cx, handler, fval, 3, argv.begin(), &idv))
return false;
return result.succeed();
}
static bool
CallSetter(JSContext *cx, HandleObject obj, HandleId id, SetterOp op, unsigned attrs,
MutableHandleValue vp, ObjectOpResult &result)
CallSetter(JSContext *cx, HandleValue receiver, HandleId id, SetterOp op, unsigned attrs,
HandleValue v, ObjectOpResult &result)
{
if (attrs & JSPROP_SETTER) {
RootedValue opv(cx, CastAsObjectJsval(op));
if (!InvokeGetterOrSetter(cx, obj, opv, 1, vp.address(), vp))
RootedValue fval(cx, CastAsObjectJsval(op));
if (!InvokeSetter(cx, receiver, fval, v))
return false;
return result.succeed();
}
@ -339,15 +339,20 @@ CallSetter(JSContext *cx, HandleObject obj, HandleId id, SetterOp op, unsigned a
if (attrs & JSPROP_GETTER)
return result.fail(JSMSG_GETTER_ONLY);
if (!receiver.isObject())
return result.fail(JSMSG_SET_NON_OBJECT_RECEIVER);
RootedObject receiverObj(cx, &receiver.toObject());
if (!op)
return result.succeed();
return CallJSSetterOp(cx, op, obj, id, vp, result);
RootedValue valCopy(cx, v);
return CallJSSetterOp(cx, op, receiverObj, id, &valCopy, result);
}
bool
ScriptedIndirectProxyHandler::derivedSet(JSContext *cx, HandleObject proxy, HandleObject receiver,
HandleId id, MutableHandleValue vp,
ScriptedIndirectProxyHandler::derivedSet(JSContext *cx, HandleObject proxy, HandleId id,
HandleValue v, HandleValue receiver,
ObjectOpResult &result) const
{
// Find an own or inherited property. The code here is strange for maximum
@ -378,7 +383,7 @@ ScriptedIndirectProxyHandler::derivedSet(JSContext *cx, HandleObject proxy, Hand
return result.fail(descIsOwn ? JSMSG_READ_ONLY : JSMSG_CANT_REDEFINE_PROP);
if (desc.hasSetterObject() || desc.setter()) {
if (!CallSetter(cx, receiver, id, desc.setter(), desc.attributes(), vp, result))
if (!CallSetter(cx, receiver, id, desc.setter(), desc.attributes(), v, result))
return false;
if (!result)
return true;
@ -389,22 +394,21 @@ ScriptedIndirectProxyHandler::derivedSet(JSContext *cx, HandleObject proxy, Hand
return result.succeed();
}
}
desc.value().set(vp.get());
desc.value().set(v);
if (descIsOwn) {
MOZ_ASSERT(desc.object() == proxy);
return this->defineProperty(cx, proxy, id, desc, result);
}
return DefineProperty(cx, receiver, id, desc.value(), desc.getter(), desc.setter(),
desc.attributes(), result);
} else {
desc.setDataDescriptor(v, JSPROP_ENUMERATE);
}
desc.object().set(receiver);
desc.value().set(vp.get());
desc.setAttributes(JSPROP_ENUMERATE);
desc.setGetter(nullptr);
desc.setSetter(nullptr); // Pick up the class getter/setter.
return DefineProperty(cx, receiver, id, desc.value(), nullptr, nullptr, JSPROP_ENUMERATE,
result);
if (!receiver.isObject())
return result.fail(JSMSG_SET_NON_OBJECT_RECEIVER);
RootedObject receiverObj(cx, &receiver.toObject());
desc.object().set(receiverObj);
return DefineProperty(cx, receiverObj, id, desc, result);
}
bool

View File

@ -37,8 +37,8 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
virtual bool has(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const override;
virtual bool get(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp) const override;
virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result) const override;
virtual bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const override;
/* SpiderMonkey extensions. */
virtual bool getPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
@ -55,8 +55,8 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
static const ScriptedIndirectProxyHandler singleton;
private:
bool derivedSet(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result) const;
bool derivedSet(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const;
};
/* Derived class to handle Proxy.createFunction() */

View File

@ -7637,7 +7637,7 @@ DebuggerEnv_setVariable(JSContext *cx, unsigned argc, Value *vp)
}
/* Just set the property. */
if (!SetProperty(cx, env, env, id, &v))
if (!SetProperty(cx, env, id, v))
return false;
}

View File

@ -612,11 +612,7 @@ class GlobalObject : public NativeObject
MOZ_ASSERT(cx->runtime()->isSelfHostingGlobal(self));
#endif
RootedObject holder(cx, intrinsicsHolder());
RootedValue valCopy(cx, value);
ObjectOpResult result;
bool ok = SetProperty(cx, holder, holder, name, &valCopy, result);
MOZ_ASSERT_IF(ok, result);
return ok;
return SetProperty(cx, holder, name, value);
}
bool getSelfHostedFunction(JSContext *cx, HandleAtom selfHostedName, HandleAtom name,

View File

@ -310,7 +310,6 @@ SetNameOperation(JSContext *cx, JSScript *script, jsbytecode *pc, HandleObject s
bool strict = *pc == JSOP_STRICTSETNAME || *pc == JSOP_STRICTSETGNAME;
RootedPropertyName name(cx, script->getName(pc));
RootedValue valCopy(cx, val);
// In strict mode, assigning to an undeclared global variable is an
// error. To detect this, we call NativeSetProperty directly and pass
@ -318,12 +317,13 @@ SetNameOperation(JSContext *cx, JSScript *script, jsbytecode *pc, HandleObject s
bool ok;
ObjectOpResult result;
RootedId id(cx, NameToId(name));
RootedValue receiver(cx, ObjectValue(*scope));
if (scope->isUnqualifiedVarObj()) {
MOZ_ASSERT(!scope->getOps()->setProperty);
ok = NativeSetProperty(cx, scope.as<NativeObject>(), scope.as<NativeObject>(), id,
Unqualified, &valCopy, result);
ok = NativeSetProperty(cx, scope.as<NativeObject>(), id, val, receiver, Unqualified,
result);
} else {
ok = SetProperty(cx, scope, scope, id, &valCopy, result);
ok = SetProperty(cx, scope, id, val, receiver, result);
}
return ok && result.checkStrictErrorOrWarning(cx, scope, id, strict);
}
@ -338,8 +338,7 @@ InitPropertyOperation(JSContext *cx, JSOp op, HandleObject obj, HandleId id, Han
}
MOZ_ASSERT(obj->as<UnboxedPlainObject>().layout().lookup(id));
RootedValue v(cx, rhs);
return PutProperty(cx, obj, id, &v, false);
return PutProperty(cx, obj, id, rhs, false);
}
inline bool

View File

@ -313,52 +313,20 @@ GetNameOperation(JSContext *cx, InterpreterFrame *fp, jsbytecode *pc, MutableHan
}
static bool
SetObjectProperty(JSContext *cx, JSOp op, HandleValue lval, HandleId id, MutableHandleValue rref)
SetPropertyOperation(JSContext *cx, JSOp op, HandleValue lval, HandleId id, HandleValue rval)
{
MOZ_ASSERT(lval.isObject());
RootedObject obj(cx, &lval.toObject());
ObjectOpResult result;
if (MOZ_LIKELY(!obj->getOps()->setProperty)) {
if (!NativeSetProperty(cx, obj.as<NativeObject>(), obj.as<NativeObject>(), id,
Qualified, rref, result))
{
return false;
}
} else {
if (!SetProperty(cx, obj, obj, id, rref, result))
return false;
}
return result.checkStrictErrorOrWarning(cx, obj, id, op == JSOP_STRICTSETPROP);
}
static bool
SetPrimitiveProperty(JSContext *cx, JSOp op, HandleValue lval, HandleId id,
MutableHandleValue rref)
{
MOZ_ASSERT(lval.isPrimitive());
MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP);
RootedObject obj(cx, ToObjectFromStack(cx, lval));
if (!obj)
return false;
// Note: ES6 specifies that the value lval, not obj, is passed as receiver
// to obj's [[Set]] internal method. See bug 603201.
RootedValue receiver(cx, ObjectValue(*obj));
return SetObjectProperty(cx, op, receiver, id, rref);
}
static bool
SetPropertyOperation(JSContext *cx, JSOp op, HandleValue lval, HandleId id, HandleValue rval)
{
MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP);
RootedValue rref(cx, rval);
if (lval.isPrimitive())
return SetPrimitiveProperty(cx, op, lval, id, &rref);
return SetObjectProperty(cx, op, lval, id, &rref);
ObjectOpResult result;
return SetProperty(cx, obj, id, rval, receiver, result) &&
result.checkStrictErrorOrWarning(cx, obj, id, op == JSOP_STRICTSETPROP);
}
bool
@ -616,8 +584,7 @@ js::InvokeConstructor(JSContext *cx, Value fval, unsigned argc, const Value *arg
}
bool
js::InvokeGetterOrSetter(JSContext *cx, JSObject *obj, Value fval, unsigned argc,
Value *argv, MutableHandleValue rval)
js::InvokeGetter(JSContext *cx, JSObject *obj, Value fval, MutableHandleValue rval)
{
/*
* Invoke could result in another try to get or set the same id again, see
@ -625,7 +592,16 @@ js::InvokeGetterOrSetter(JSContext *cx, JSObject *obj, Value fval, unsigned argc
*/
JS_CHECK_RECURSION(cx, return false);
return Invoke(cx, ObjectValue(*obj), fval, argc, argv, rval);
return Invoke(cx, ObjectValue(*obj), fval, 0, nullptr, rval);
}
bool
js::InvokeSetter(JSContext *cx, const Value &thisv, Value fval, HandleValue v)
{
JS_CHECK_RECURSION(cx, return false);
RootedValue ignored(cx);
return Invoke(cx, thisv, fval, 1, v.address(), &ignored);
}
bool
@ -1403,7 +1379,7 @@ SetObjectElementOperation(JSContext *cx, Handle<JSObject*> obj, HandleId id, con
return false;
RootedValue tmp(cx, value);
return PutProperty(cx, obj, id, &tmp, strict);
return PutProperty(cx, obj, id, tmp, strict);
}
static MOZ_NEVER_INLINE bool
@ -3897,7 +3873,8 @@ js::DefFunOperation(JSContext *cx, HandleScript script, HandleObject scopeChain,
*/
/* Step 5f. */
return PutProperty(cx, parent, name, &rval, script->strict());
RootedId id(cx, NameToId(name));
return PutProperty(cx, parent, id, rval, script->strict());
}
bool

View File

@ -76,12 +76,14 @@ Invoke(JSContext *cx, const Value &thisv, const Value &fval, unsigned argc, cons
MutableHandleValue rval);
/*
* This helper takes care of the infinite-recursion check necessary for
* These helpers take care of the infinite-recursion check necessary for
* getter/setter calls.
*/
extern bool
InvokeGetterOrSetter(JSContext *cx, JSObject *obj, Value fval, unsigned argc, Value *argv,
MutableHandleValue rval);
InvokeGetter(JSContext *cx, JSObject *obj, Value fval, MutableHandleValue rval);
extern bool
InvokeSetter(JSContext *cx, const Value &thisv, Value fval, HandleValue v);
/*
* InvokeConstructor implement a function call from a constructor context

View File

@ -72,8 +72,7 @@ NativeObject::clearShouldConvertDoubleElements()
}
inline void
NativeObject::setDenseElementWithType(ExclusiveContext *cx, uint32_t index,
const Value &val)
NativeObject::setDenseElementWithType(ExclusiveContext *cx, uint32_t index, const Value &val)
{
// Avoid a slow AddTypePropertyId call if the type is the same as the type
// of the previous element.
@ -84,8 +83,7 @@ NativeObject::setDenseElementWithType(ExclusiveContext *cx, uint32_t index,
}
inline void
NativeObject::initDenseElementWithType(ExclusiveContext *cx, uint32_t index,
const Value &val)
NativeObject::initDenseElementWithType(ExclusiveContext *cx, uint32_t index, const Value &val)
{
MOZ_ASSERT(!shouldConvertDoubleElements());
AddTypePropertyId(cx, this, JSID_VOID, val);

View File

@ -1130,8 +1130,8 @@ UpdateShapeTypeAndValue(ExclusiveContext *cx, NativeObject *obj, Shape *shape, c
}
static bool
NativeSetExistingDataProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver,
HandleShape shape, MutableHandleValue vp, ObjectOpResult &result);
NativeSetExistingDataProperty(JSContext *cx, HandleNativeObject obj, HandleShape shape,
HandleValue v, HandleValue receiver, ObjectOpResult &result);
static inline bool
DefinePropertyOrElement(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
@ -1224,8 +1224,9 @@ DefinePropertyOrElement(ExclusiveContext *cx, HandleNativeObject obj, HandleId i
MOZ_ASSERT(!(attrs & JSPROP_SETTER));
if (!cx->shouldBeJSContext())
return false;
RootedValue nvalue(cx, value);
return NativeSetExistingDataProperty(cx->asJSContext(), obj, obj, shape, &nvalue, result);
RootedValue receiver(cx, ObjectValue(*obj));
return NativeSetExistingDataProperty(cx->asJSContext(), obj, shape, value, receiver,
result);
}
return result.succeed();
@ -1631,7 +1632,7 @@ CallGetter(JSContext* cx, HandleObject receiver, HandleShape shape, MutableHandl
if (shape->hasGetterValue()) {
Value fval = shape->getterValue();
return InvokeGetterOrSetter(cx, receiver, fval, 0, 0, vp);
return InvokeGetter(cx, receiver, fval, vp);
}
RootedId id(cx, shape->propid());
@ -1979,13 +1980,18 @@ MaybeReportUndeclaredVarAssignment(JSContext *cx, JSString *propname)
* or finds a writable data property on the prototype chain, we end up here.
* Finish the [[Set]] by defining a new property on receiver.
*
* This implements ES6 draft rev 28, 9.1.9 [[Set]] steps 5.c-f, but it
* This implements ES6 draft rev 28, 9.1.9 [[Set]] steps 5.b-f, but it
* is really old code and there are a few barnacles.
*/
bool
js::SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleObject receiver,
HandleId id, HandleValue v, bool objHasOwn, ObjectOpResult &result)
js::SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiverValue, bool objHasOwn, ObjectOpResult &result)
{
// Step 5.b.
if (!receiverValue.isObject())
return result.fail(JSMSG_SET_NON_OBJECT_RECEIVER);
RootedObject receiver(cx, &receiverValue.toObject());
// Step 5.c-d: Test whether receiver has an existing own property
// receiver[id]. The spec calls [[GetOwnProperty]]; js::HasOwnProperty is
// the same thing except faster in the non-proxy case. Sometimes we can
@ -2047,15 +2053,15 @@ js::SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleObject receiver
// When setting |id| for |receiver| and |obj| has no property for id, continue
// the search up the prototype chain.
bool
js::SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
js::SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result)
{
MOZ_ASSERT(!obj->is<ProxyObject>());
RootedObject proto(cx, obj->getProto());
if (proto)
return SetProperty(cx, proto, receiver, id, vp, result);
return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result);
return SetProperty(cx, proto, id, v, receiver, result);
return SetPropertyByDefining(cx, obj, id, v, receiver, false, result);
}
/*
@ -2064,22 +2070,20 @@ js::SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleObject receiver,
*
* FIXME: This should be updated to follow ES6 draft rev 28, section 9.1.9,
* steps 4.d.i and 5.
*
* Note that receiver is not necessarily native.
*/
static bool
SetNonexistentProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
QualifiedBool qualified, HandleValue v, ObjectOpResult &result)
SetNonexistentProperty(JSContext *cx, HandleNativeObject obj, HandleId id, HandleValue v,
HandleValue receiver, QualifiedBool qualified, ObjectOpResult &result)
{
// We should never add properties to lexical blocks.
MOZ_ASSERT(!receiver->is<BlockObject>());
MOZ_ASSERT_IF(receiver.isObject(), !receiver.toObject().is<BlockObject>());
if (receiver->isUnqualifiedVarObj() && !qualified) {
if (!qualified && receiver.isObject() && receiver.toObject().isUnqualifiedVarObj()) {
if (!MaybeReportUndeclaredVarAssignment(cx, JSID_TO_STRING(id)))
return false;
}
return SetPropertyByDefining(cx, obj, receiver, id, v, false, result);
return SetPropertyByDefining(cx, obj, id, v, receiver, false, result);
}
/*
@ -2087,12 +2091,12 @@ SetNonexistentProperty(JSContext *cx, HandleNativeObject obj, HandleObject recei
* array element.
*/
static bool
SetDenseOrTypedArrayElement(JSContext *cx, HandleNativeObject obj, uint32_t index,
MutableHandleValue vp, ObjectOpResult &result)
SetDenseOrTypedArrayElement(JSContext *cx, HandleNativeObject obj, uint32_t index, HandleValue v,
ObjectOpResult &result)
{
if (IsAnyTypedArray(obj)) {
double d;
if (!ToNumber(cx, vp, &d))
if (!ToNumber(cx, v, &d))
return false;
// Silently do nothing for out-of-bounds sets, for consistency with
@ -2114,7 +2118,7 @@ SetDenseOrTypedArrayElement(JSContext *cx, HandleNativeObject obj, uint32_t inde
if (!obj->maybeCopyElementsForWrite(cx))
return false;
obj->setDenseElementWithType(cx, index, vp);
obj->setDenseElementWithType(cx, index, v);
return result.succeed();
}
@ -2123,8 +2127,8 @@ SetDenseOrTypedArrayElement(JSContext *cx, HandleNativeObject obj, uint32_t inde
* conforms to no standard and there is a lot of legacy baggage here.
*/
static bool
NativeSetExistingDataProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver,
HandleShape shape, MutableHandleValue vp, ObjectOpResult &result)
NativeSetExistingDataProperty(JSContext *cx, HandleNativeObject obj, HandleShape shape,
HandleValue v, HandleValue receiver, ObjectOpResult &result)
{
MOZ_ASSERT(obj->isNative());
MOZ_ASSERT(shape->isDataDescriptor());
@ -2137,7 +2141,7 @@ NativeSetExistingDataProperty(JSContext *cx, HandleNativeObject obj, HandleObjec
// defined with an undefined value, so don't treat the initial
// assignments to such properties as overwrites.
bool overwriting = !obj->is<GlobalObject>() || !obj->getSlot(shape->slot()).isUndefined();
obj->setSlotWithType(cx, shape, vp, overwriting);
obj->setSlotWithType(cx, shape, v, overwriting);
return result.succeed();
}
@ -2151,7 +2155,8 @@ NativeSetExistingDataProperty(JSContext *cx, HandleNativeObject obj, HandleObjec
uint32_t sample = cx->runtime()->propertyRemovals;
RootedId id(cx, shape->propid());
if (!CallJSSetterOp(cx, shape->setterOp(), obj, id, vp, result))
RootedValue value(cx, v);
if (!CallJSSetterOp(cx, shape->setterOp(), obj, id, &value, result))
return false;
// Update any slot for the shape with the value produced by the setter,
@ -2160,14 +2165,14 @@ NativeSetExistingDataProperty(JSContext *cx, HandleNativeObject obj, HandleObjec
(MOZ_LIKELY(cx->runtime()->propertyRemovals == sample) ||
obj->contains(cx, shape)))
{
obj->setSlot(shape->slot(), vp);
obj->setSlot(shape->slot(), value);
}
return true; // result is populated by CallJSSetterOp above.
}
/*
* Finish the assignment `receiver[id] = vp` when an existing property (shape)
* Finish the assignment `receiver[id] = v` when an existing property (shape)
* has been found on a native object (pobj). This implements ES6 draft rev 32
* (2015 Feb 2) 9.1.9 steps 5 and 6.
*
@ -2175,21 +2180,20 @@ NativeSetExistingDataProperty(JSContext *cx, HandleNativeObject obj, HandleObjec
* dense or typed array element (i.e. not actually a pointer to a Shape).
*/
static bool
SetExistingProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
HandleNativeObject pobj, HandleShape shape, MutableHandleValue vp,
SetExistingProperty(JSContext *cx, HandleNativeObject obj, HandleId id, HandleValue v,
HandleValue receiver, HandleNativeObject pobj, HandleShape shape,
ObjectOpResult &result)
{
// Step 5 for dense elements.
if (IsImplicitDenseOrTypedArrayElement(shape)) {
// Step 5.a is a no-op: all dense elements are writable.
// Step 5.b has to do with non-object receivers, which we don't support yet.
// Pure optimization for the common case:
if (pobj == receiver)
return SetDenseOrTypedArrayElement(cx, pobj, JSID_TO_INT(id), vp, result);
if (receiver.isObject() && pobj == &receiver.toObject())
return SetDenseOrTypedArrayElement(cx, pobj, JSID_TO_INT(id), v, result);
// Steps 5.c-f.
return SetPropertyByDefining(cx, obj, receiver, id, vp, obj == pobj, result);
// Steps 5.b-f.
return SetPropertyByDefining(cx, obj, id, v, receiver, obj == pobj, result);
}
// Step 5 for all other properties.
@ -2199,7 +2203,7 @@ SetExistingProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver
return result.fail(JSMSG_READ_ONLY);
// steps 5.c-f.
if (pobj == receiver) {
if (receiver.isObject() && pobj == &receiver.toObject()) {
// Pure optimization for the common case. There's no point performing
// the lookup in step 5.c again, as our caller just did it for us. The
// result is |shape|.
@ -2207,9 +2211,9 @@ SetExistingProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver
// Steps 5.e.i-ii.
if (pobj->is<ArrayObject>() && id == NameToId(cx->names().length)) {
Rooted<ArrayObject*> arr(cx, &pobj->as<ArrayObject>());
return ArraySetLength(cx, arr, id, shape->attributes(), vp, result);
return ArraySetLength(cx, arr, id, shape->attributes(), v, result);
}
return NativeSetExistingDataProperty(cx, obj, receiver, shape, vp, result);
return NativeSetExistingDataProperty(cx, obj, shape, v, receiver, result);
}
// SpiderMonkey special case: assigning to an inherited slotless
@ -2225,12 +2229,13 @@ SetExistingProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver
if (shape->hasDefaultSetter())
return result.succeed();
return CallJSSetterOp(cx, shape->setterOp(), obj, id, vp, result);
RootedValue valCopy(cx, v);
return CallJSSetterOp(cx, shape->setterOp(), obj, id, &valCopy, result);
}
// Shadow pobj[id] by defining a new data property receiver[id].
// Delegate everything to SetPropertyByDefining.
return SetPropertyByDefining(cx, obj, receiver, id, vp, obj == pobj, result);
return SetPropertyByDefining(cx, obj, id, v, receiver, obj == pobj, result);
}
// Steps 6-11.
@ -2239,25 +2244,26 @@ SetExistingProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver
if (shape->hasDefaultSetter())
return result.fail(JSMSG_GETTER_ONLY);
Value setter = ObjectValue(*shape->setterObject());
if (!InvokeGetterOrSetter(cx, receiver, setter, 1, vp.address(), vp))
if (!InvokeSetter(cx, receiver, setter, v))
return false;
return result.succeed();
}
bool
js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
QualifiedBool qualified, MutableHandleValue vp, ObjectOpResult &result)
js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleId id, HandleValue value,
HandleValue receiver, QualifiedBool qualified, ObjectOpResult &result)
{
// Fire watchpoints, if any.
RootedValue v(cx, value);
if (MOZ_UNLIKELY(obj->watched())) {
WatchpointMap *wpmap = cx->compartment()->watchpointMap;
if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, vp))
if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, &v))
return false;
}
// Step numbers below reference ES6 rev 27 9.1.9, the [[Set]] internal
// method for ordinary objects. We substitute our own names for these names
// used in the spec: O -> pobj, P -> id, V -> *vp, ownDesc -> shape.
// used in the spec: O -> pobj, P -> id, ownDesc -> shape.
RootedShape shape(cx);
RootedNativeObject pobj(cx, obj);
@ -2272,7 +2278,7 @@ js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiv
if (shape) {
// Steps 5-6.
return SetExistingProperty(cx, obj, receiver, id, pobj, shape, vp, result);
return SetExistingProperty(cx, obj, id, v, receiver, pobj, shape, result);
}
// Steps 4.a-b. The check for 'done' on this next line is tricky.
@ -2286,7 +2292,7 @@ js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiv
RootedObject proto(cx, done ? nullptr : pobj->getProto());
if (!proto) {
// Step 4.d.i (and step 5).
return SetNonexistentProperty(cx, obj, receiver, id, qualified, vp, result);
return SetNonexistentProperty(cx, obj, id, v, receiver, qualified, result);
}
// Step 4.c.i. If the prototype is also native, this step is a
@ -2303,23 +2309,23 @@ js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiv
if (!HasProperty(cx, proto, id, &found))
return false;
if (!found)
return SetNonexistentProperty(cx, obj, receiver, id, qualified, vp, result);
return SetNonexistentProperty(cx, obj, id, v, receiver, qualified, result);
}
return SetProperty(cx, proto, receiver, id, vp, result);
return SetProperty(cx, proto, id, v, receiver, result);
}
pobj = &proto->as<NativeObject>();
}
}
bool
js::NativeSetElement(JSContext *cx, HandleNativeObject obj, HandleObject receiver, uint32_t index,
MutableHandleValue vp, ObjectOpResult &result)
js::NativeSetElement(JSContext *cx, HandleNativeObject obj, uint32_t index, HandleValue v,
HandleValue receiver, ObjectOpResult &result)
{
RootedId id(cx);
if (!IndexToId(cx, index, &id))
return false;
return NativeSetProperty(cx, obj, receiver, id, Qualified, vp, result);
return NativeSetProperty(cx, obj, id, v, receiver, Qualified, result);
}
/*** [[Delete]] **********************************************************************************/

View File

@ -1312,12 +1312,12 @@ NativeGetElement(JSContext *cx, HandleNativeObject obj, uint32_t index, MutableH
}
bool
SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
HandleValue v, bool objHasOwn, ObjectOpResult &result);
SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, bool objHasOwn, ObjectOpResult &result);
bool
SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result);
SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result);
/*
* Indicates whether an assignment operation is qualified (`x.y = 0`) or
@ -1332,12 +1332,12 @@ enum QualifiedBool {
};
extern bool
NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
QualifiedBool qualified, MutableHandleValue vp, ObjectOpResult &result);
NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleId id, HandleValue v,
HandleValue receiver, QualifiedBool qualified, ObjectOpResult &result);
extern bool
NativeSetElement(JSContext *cx, HandleNativeObject obj, HandleObject receiver, uint32_t index,
MutableHandleValue vp, ObjectOpResult &result);
NativeSetElement(JSContext *cx, HandleNativeObject obj, uint32_t index, HandleValue v,
HandleValue receiver, ObjectOpResult &result);
extern bool
NativeDeleteProperty(JSContext *cx, HandleNativeObject obj, HandleId id, ObjectOpResult &result);
@ -1448,21 +1448,21 @@ js::GetPropertyNoGC(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, V
}
inline bool
js::SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
js::SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result)
{
if (obj->getOps()->setProperty)
return JSObject::nonNativeSetProperty(cx, obj, receiver, id, vp, result);
return NativeSetProperty(cx, obj.as<NativeObject>(), receiver, id, Qualified, vp, result);
return JSObject::nonNativeSetProperty(cx, obj, id, v, receiver, result);
return NativeSetProperty(cx, obj.as<NativeObject>(), id, v, receiver, Qualified, result);
}
inline bool
js::SetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index,
MutableHandleValue vp, ObjectOpResult &result)
js::SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v,
HandleValue receiver, ObjectOpResult &result)
{
if (obj->getOps()->setProperty)
return JSObject::nonNativeSetElement(cx, obj, receiver, index, vp, result);
return NativeSetElement(cx, obj.as<NativeObject>(), receiver, index, vp, result);
return JSObject::nonNativeSetElement(cx, obj, index, v, receiver, result);
return NativeSetElement(cx, obj.as<NativeObject>(), index, v, receiver, result);
}
#endif /* vm_NativeObject_h */

View File

@ -299,7 +299,7 @@ CallObject::createHollowForDebug(JSContext *cx, HandleFunction callee)
RootedScript script(cx, callee->nonLazyScript());
for (BindingIter bi(script); !bi.done(); bi++) {
id = NameToId(bi->name());
if (!SetProperty(cx, callobj, callobj, id, &optimizedOut))
if (!SetProperty(cx, callobj, id, optimizedOut))
return nullptr;
}
@ -492,14 +492,14 @@ with_GetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleI
}
static bool
with_SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result)
with_SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result)
{
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
RootedObject actualReceiver(cx, receiver);
if (receiver == obj)
actualReceiver = actual;
return SetProperty(cx, actual, actualReceiver, id, vp, result);
RootedValue actualReceiver(cx, receiver);
if (receiver.isObject() && &receiver.toObject() == obj)
actualReceiver.setObject(*actual);
return SetProperty(cx, actual, id, v, actualReceiver, result);
}
static bool
@ -929,8 +929,8 @@ uninitialized_GetProperty(JSContext *cx, HandleObject obj, HandleObject receiver
}
static bool
uninitialized_SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result)
uninitialized_SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result)
{
ReportUninitializedLexicalId(cx, id);
return false;
@ -1592,8 +1592,8 @@ class DebugScopeProxy : public BaseProxyHandler
}
}
bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result) const override
bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver,
ObjectOpResult &result) const override
{
Rooted<DebugScopeObject*> debugScope(cx, &proxy->as<DebugScopeObject>());
Rooted<ScopeObject*> scope(cx, &proxy->as<DebugScopeObject>().scope());
@ -1602,14 +1602,18 @@ class DebugScopeProxy : public BaseProxyHandler
return Throw(cx, id, JSMSG_DEBUG_CANT_SET_OPT_ENV);
AccessResult access;
if (!handleUnaliasedAccess(cx, debugScope, scope, id, SET, vp, &access))
RootedValue valCopy(cx, v);
if (!handleUnaliasedAccess(cx, debugScope, scope, id, SET, &valCopy, &access))
return false;
switch (access) {
case ACCESS_UNALIASED:
return result.succeed();
case ACCESS_GENERIC:
return SetProperty(cx, scope, scope, id, vp, result);
{
RootedValue scopeVal(cx, ObjectValue(*scope));
return SetProperty(cx, scope, id, v, scopeVal, result);
}
default:
MOZ_CRASH("bad AccessResult");
}

View File

@ -336,10 +336,10 @@ js::intrinsic_UnsafePutElements(JSContext *cx, unsigned argc, Value *vp)
if (IsAnyTypedArray(arrobj.get()) || arrobj->is<TypedObject>()) {
MOZ_ASSERT_IF(IsAnyTypedArray(arrobj.get()), idx < AnyTypedArrayLength(arrobj.get()));
MOZ_ASSERT_IF(arrobj->is<TypedObject>(), idx < uint32_t(arrobj->as<TypedObject>().length()));
RootedValue tmp(cx, args[elemi]);
// XXX: Always non-strict.
ObjectOpResult ignored;
if (!SetElement(cx, arrobj, arrobj, idx, &tmp, ignored))
RootedValue receiver(cx, ObjectValue(*arrobj));
if (!SetElement(cx, arrobj, idx, args[elemi], receiver, ignored))
return false;
} else {
MOZ_ASSERT(idx < arrobj->as<ArrayObject>().getDenseInitializedLength());

View File

@ -759,36 +759,38 @@ UnboxedPlainObject::obj_getProperty(JSContext *cx, HandleObject obj, HandleObjec
}
/* static */ bool
UnboxedPlainObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
UnboxedPlainObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result)
{
const UnboxedLayout &layout = obj->as<UnboxedPlainObject>().layout();
if (const UnboxedLayout::Property *property = layout.lookup(id)) {
if (obj == receiver) {
if (obj->as<UnboxedPlainObject>().setValue(cx, *property, vp))
if (receiver.isObject() && obj == &receiver.toObject()) {
if (obj->as<UnboxedPlainObject>().setValue(cx, *property, v))
return result.succeed();
if (!convertToNative(cx, obj))
return false;
return SetProperty(cx, obj, receiver, id, vp, result);
return SetProperty(cx, obj, id, v, receiver, result);
}
return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result);
return SetPropertyByDefining(cx, obj, id, v, receiver, false, result);
}
if (UnboxedExpandoObject *expando = obj->as<UnboxedPlainObject>().maybeExpando()) {
if (expando->containsShapeOrElement(cx, id)) {
// Update property types on the unboxed object as well.
AddTypePropertyId(cx, obj, id, vp);
AddTypePropertyId(cx, obj, id, v);
RootedObject nexpando(cx, expando);
RootedObject nreceiver(cx, (obj == receiver) ? expando : receiver.get());
return SetProperty(cx, nexpando, nreceiver, id, vp, result);
RootedValue nreceiver(cx, (receiver.isObject() && obj == &receiver.toObject())
? ObjectValue(*expando)
: receiver);
return SetProperty(cx, nexpando, id, v, nreceiver, result);
}
}
return SetPropertyOnProto(cx, obj, receiver, id, vp, result);
return SetPropertyOnProto(cx, obj, id, v, receiver, result);
}
/* static */ bool

View File

@ -201,8 +201,8 @@ class UnboxedPlainObject : public JSObject
static bool obj_getProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
HandleId id, MutableHandleValue vp);
static bool obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
HandleId id, MutableHandleValue vp, ObjectOpResult &result);
static bool obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result);
static bool obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc);

View File

@ -29,11 +29,11 @@ namespace js {
*
* https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
*/
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 268;
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 269;
static const uint32_t XDR_BYTECODE_VERSION =
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
static_assert(JSErr_Limit == 389,
static_assert(JSErr_Limit == 390,
"GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
"removed MSG_DEFs from js.msg, you should increment "
"XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "

View File

@ -733,12 +733,12 @@ xpc::SandboxProxyHandler::get(JSContext *cx, JS::Handle<JSObject*> proxy,
bool
xpc::SandboxProxyHandler::set(JSContext *cx, JS::Handle<JSObject*> proxy,
JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id,
JS::MutableHandle<Value> vp,
JS::Handle<Value> v,
JS::Handle<Value> receiver,
JS::ObjectOpResult &result) const
{
return BaseProxyHandler::set(cx, proxy, receiver, id, vp, result);
return BaseProxyHandler::set(cx, proxy, id, v, receiver, result);
}
bool

View File

@ -119,24 +119,24 @@ AddonWrapper<Base>::get(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle
template<typename Base>
bool
AddonWrapper<Base>::set(JSContext *cx, JS::HandleObject wrapper, JS::HandleObject receiver,
JS::HandleId id, JS::MutableHandleValue vp,
JS::ObjectOpResult &result) const
AddonWrapper<Base>::set(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, JS::HandleValue v,
JS::HandleValue receiver, JS::ObjectOpResult &result) const
{
Rooted<JSPropertyDescriptor> desc(cx);
if (!Interpose(cx, wrapper, nullptr, id, &desc))
return false;
if (!desc.object())
return Base::set(cx, wrapper, receiver, id, vp, result);
return Base::set(cx, wrapper, id, v, receiver, result);
if (desc.setter()) {
MOZ_ASSERT(desc.hasSetterObject());
JS::AutoValueVector args(cx);
if (!args.append(vp))
if (!args.append(v))
return false;
RootedValue fval(cx, ObjectValue(*desc.setterObject()));
if (!JS_CallFunctionValue(cx, receiver, fval, args, vp))
RootedValue ignored(cx);
if (!JS::Call(cx, receiver, fval, args, &ignored))
return false;
return result.succeed();
}

View File

@ -34,9 +34,8 @@ class AddonWrapper : public Base {
JS::ObjectOpResult &result) const override;
virtual bool get(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
virtual bool set(JSContext *cx, JS::HandleObject wrapper, JS::HandleObject receiver,
JS::HandleId id, JS::MutableHandleValue vp,
JS::ObjectOpResult &result) const override;
virtual bool set(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, JS::HandleValue v,
JS::HandleValue receiver, JS::ObjectOpResult &result) const override;
virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::Handle<jsid> id,

View File

@ -30,13 +30,12 @@ ChromeObjectWrapper::defineProperty(JSContext *cx, HandleObject wrapper,
}
bool
ChromeObjectWrapper::set(JSContext *cx, HandleObject wrapper,
HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result) const
ChromeObjectWrapper::set(JSContext *cx, HandleObject wrapper, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const
{
if (!AccessCheck::checkPassToPrivilegedCode(cx, wrapper, vp))
if (!AccessCheck::checkPassToPrivilegedCode(cx, wrapper, v))
return false;
return ChromeObjectWrapperBase::set(cx, wrapper, receiver, id, vp, result);
return ChromeObjectWrapperBase::set(cx, wrapper, id, v, receiver, result);
}
}

View File

@ -31,9 +31,8 @@ class ChromeObjectWrapper : public ChromeObjectWrapperBase
JS::Handle<jsid> id,
JS::Handle<JSPropertyDescriptor> desc,
JS::ObjectOpResult &result) const override;
virtual bool set(JSContext *cx, JS::Handle<JSObject*> wrapper,
JS::Handle<JSObject*> receiver, JS::Handle<jsid> id,
JS::MutableHandle<JS::Value> vp,
virtual bool set(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
JS::HandleValue v, JS::HandleValue receiver,
JS::ObjectOpResult &result) const override;
static const ChromeObjectWrapper singleton;

View File

@ -2081,15 +2081,15 @@ XrayWrapper<Base, Traits>::get(JSContext *cx, HandleObject wrapper,
template <typename Base, typename Traits>
bool
XrayWrapper<Base, Traits>::set(JSContext *cx, HandleObject wrapper,
HandleObject receiver, HandleId id,
MutableHandleValue vp, ObjectOpResult &result) const
XrayWrapper<Base, Traits>::set(JSContext *cx, HandleObject wrapper, HandleId id, HandleValue v,
HandleValue receiver, ObjectOpResult &result) const
{
MOZ_ASSERT(!Traits::HasPrototype);
// Skip our Base if it isn't already BaseProxyHandler.
// NB: None of the functions we call are prepared for the receiver not
// being the wrapper, so ignore the receiver here.
return js::BaseProxyHandler::set(cx, wrapper, wrapper, id, vp, result);
RootedValue wrapperValue(cx, ObjectValue(*wrapper));
return js::BaseProxyHandler::set(cx, wrapper, id, v, wrapperValue, result);
}
template <typename Base, typename Traits>

View File

@ -441,8 +441,8 @@ class XrayWrapper : public Base {
bool *bp) const override;
virtual bool get(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
virtual bool set(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp,
virtual bool set(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver,
JS::ObjectOpResult &result) const override;
virtual bool call(JSContext *cx, JS::Handle<JSObject*> wrapper,
const JS::CallArgs &args) const override;
@ -515,8 +515,8 @@ public:
bool *bp) const override;
virtual bool get(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
virtual bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp,
virtual bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver,
JS::ObjectOpResult &result) const override;
virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> proxy,