mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
0fa4a70f2d
commit
db4ac4cade
@ -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
|
||||
|
@ -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 = ""
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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}")
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 ***************************************************/
|
||||
|
||||
|
@ -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]`.
|
||||
*/
|
||||
|
@ -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 ®Exp() { return *re_; }
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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() */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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]] **********************************************************************************/
|
||||
|
@ -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 */
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 "
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user