mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-11 13:48:23 +02:00
Backed out 9 changesets (bug 1142775, bug 1139683, bug 1143810, bug 1142761, bug 1142784, bug 1142794, bug 1144819) for widespread bustage
CLOSED TREE Backed out changeset 7613fc978d36 (bug 1142794) Backed out changeset e5f0cb31263d (bug 1142784) Backed out changeset dcd0af73ac84 (bug 1142784) Backed out changeset 034f9c8e79ee (bug 1142784) Backed out changeset ce0ee37e3ca9 (bug 1142775) Backed out changeset 1519b8f2bbba (bug 1142761) Backed out changeset 26fd55677841 (bug 1139683) Backed out changeset 7ebc76a450c3 (bug 1144819) Backed out changeset 92adb459d519 (bug 1143810)
This commit is contained in:
parent
735dca6f1b
commit
c4745d28b1
70 changed files with 719 additions and 862 deletions
|
|
@ -159,7 +159,7 @@ bool
|
|||
WindowNamedPropertiesHandler::defineProperty(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aProxy,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::Handle<JSPropertyDescriptor> aDesc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
ErrorResult rv;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ public:
|
|||
virtual bool
|
||||
defineProperty(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::Handle<JSPropertyDescriptor> aDesc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool
|
||||
ownPropNames(JSContext* aCx, JS::Handle<JSObject*> aProxy, unsigned flags,
|
||||
|
|
|
|||
|
|
@ -621,7 +621,7 @@ public:
|
|||
virtual bool defineProperty(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
|
|
@ -643,8 +643,9 @@ public:
|
|||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JS::Value> vp) const override;
|
||||
virtual bool set(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id, JS::Handle<JS::Value> v,
|
||||
JS::Handle<JS::Value> receiver,
|
||||
JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JS::Value> vp,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
|
||||
// SpiderMonkey extensions
|
||||
|
|
@ -781,7 +782,7 @@ bool
|
|||
nsOuterWindowProxy::defineProperty(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
int32_t index = GetArrayIndexFromId(cx, id);
|
||||
|
|
@ -908,9 +909,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::Handle<JS::Value> v,
|
||||
JS::Handle<JS::Value> receiver,
|
||||
JS::MutableHandle<JS::Value> vp,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
int32_t index = GetArrayIndexFromId(cx, id);
|
||||
|
|
@ -920,7 +921,7 @@ nsOuterWindowProxy::set(JSContext *cx, JS::Handle<JSObject*> proxy,
|
|||
return result.failReadOnly();
|
||||
}
|
||||
|
||||
return js::Wrapper::set(cx, proxy, id, v, receiver, result);
|
||||
return js::Wrapper::set(cx, proxy, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -1439,7 +1439,7 @@ XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
|||
bool
|
||||
XrayDefineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
{
|
||||
if (!js::IsProxy(obj))
|
||||
|
|
|
|||
|
|
@ -2464,7 +2464,7 @@ XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
|||
bool
|
||||
XrayDefineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result,
|
||||
bool *defined);
|
||||
|
||||
|
|
|
|||
|
|
@ -9805,7 +9805,7 @@ class CGProxySpecialOperation(CGPerSignatureCall):
|
|||
false.
|
||||
"""
|
||||
def __init__(self, descriptor, operation, checkFound=True,
|
||||
argumentHandleValue=None, resultVar=None, foundVar=None):
|
||||
argumentMutableValue=None, resultVar=None, foundVar=None):
|
||||
self.checkFound = checkFound
|
||||
self.foundVar = foundVar or "found"
|
||||
|
||||
|
|
@ -9830,12 +9830,12 @@ class CGProxySpecialOperation(CGPerSignatureCall):
|
|||
treatNullAs=argument.treatNullAs,
|
||||
sourceDescription=("value being assigned to %s setter" %
|
||||
descriptor.interface.identifier.name))
|
||||
if argumentHandleValue is None:
|
||||
argumentHandleValue = "desc.value()"
|
||||
if argumentMutableValue is None:
|
||||
argumentMutableValue = "desc.value()"
|
||||
templateValues = {
|
||||
"declName": argument.identifier.name,
|
||||
"holderName": argument.identifier.name + "_holder",
|
||||
"val": argumentHandleValue,
|
||||
"val": argumentMutableValue,
|
||||
"obj": "obj",
|
||||
"passedToJSImpl": "false"
|
||||
}
|
||||
|
|
@ -9880,10 +9880,10 @@ class CGProxyIndexedOperation(CGProxySpecialOperation):
|
|||
foundVar: See the docstring for CGProxySpecialOperation.
|
||||
"""
|
||||
def __init__(self, descriptor, name, doUnwrap=True, checkFound=True,
|
||||
argumentHandleValue=None, resultVar=None, foundVar=None):
|
||||
argumentMutableValue=None, resultVar=None, foundVar=None):
|
||||
self.doUnwrap = doUnwrap
|
||||
CGProxySpecialOperation.__init__(self, descriptor, name, checkFound,
|
||||
argumentHandleValue=argumentHandleValue,
|
||||
argumentMutableValue=argumentMutableValue,
|
||||
resultVar=resultVar,
|
||||
foundVar=foundVar)
|
||||
|
||||
|
|
@ -9941,9 +9941,9 @@ class CGProxyIndexedSetter(CGProxyIndexedOperation):
|
|||
"""
|
||||
Class to generate a call to an indexed setter.
|
||||
"""
|
||||
def __init__(self, descriptor, argumentHandleValue=None):
|
||||
def __init__(self, descriptor, argumentMutableValue=None):
|
||||
CGProxyIndexedOperation.__init__(self, descriptor, 'IndexedSetter',
|
||||
argumentHandleValue=argumentHandleValue)
|
||||
argumentMutableValue=argumentMutableValue)
|
||||
|
||||
|
||||
class CGProxyIndexedDeleter(CGProxyIndexedOperation):
|
||||
|
|
@ -9971,10 +9971,10 @@ class CGProxyNamedOperation(CGProxySpecialOperation):
|
|||
|
||||
foundVar: See the docstring for CGProxySpecialOperation.
|
||||
"""
|
||||
def __init__(self, descriptor, name, value=None, argumentHandleValue=None,
|
||||
def __init__(self, descriptor, name, value=None, argumentMutableValue=None,
|
||||
resultVar=None, foundVar=None):
|
||||
CGProxySpecialOperation.__init__(self, descriptor, name,
|
||||
argumentHandleValue=argumentHandleValue,
|
||||
argumentMutableValue=argumentMutableValue,
|
||||
resultVar=resultVar,
|
||||
foundVar=foundVar)
|
||||
self.value = value
|
||||
|
|
@ -10072,9 +10072,9 @@ class CGProxyNamedSetter(CGProxyNamedOperation):
|
|||
"""
|
||||
Class to generate a call to a named setter.
|
||||
"""
|
||||
def __init__(self, descriptor, argumentHandleValue=None):
|
||||
def __init__(self, descriptor, argumentMutableValue=None):
|
||||
CGProxyNamedOperation.__init__(self, descriptor, 'NamedSetter',
|
||||
argumentHandleValue=argumentHandleValue)
|
||||
argumentMutableValue=argumentMutableValue)
|
||||
|
||||
|
||||
class CGProxyNamedDeleter(CGProxyNamedOperation):
|
||||
|
|
@ -10244,7 +10244,7 @@ class CGDOMJSProxyHandler_defineProperty(ClassMethod):
|
|||
args = [Argument('JSContext*', 'cx'),
|
||||
Argument('JS::Handle<JSObject*>', 'proxy'),
|
||||
Argument('JS::Handle<jsid>', 'id'),
|
||||
Argument('JS::Handle<JSPropertyDescriptor>', 'desc'),
|
||||
Argument('JS::MutableHandle<JSPropertyDescriptor>', 'desc'),
|
||||
Argument('JS::ObjectOpResult&', 'opresult'),
|
||||
Argument('bool*', 'defined')]
|
||||
ClassMethod.__init__(self, "defineProperty", "bool", args, virtual=True, override=True, const=True)
|
||||
|
|
@ -10691,7 +10691,7 @@ class CGDOMJSProxyHandler_setCustom(ClassMethod):
|
|||
args = [Argument('JSContext*', 'cx'),
|
||||
Argument('JS::Handle<JSObject*>', 'proxy'),
|
||||
Argument('JS::Handle<jsid>', 'id'),
|
||||
Argument('JS::Handle<JS::Value>', 'v'),
|
||||
Argument('JS::MutableHandle<JS::Value>', 'vp'),
|
||||
Argument('bool*', 'done')]
|
||||
ClassMethod.__init__(self, "setCustom", "bool", args, virtual=True, override=True, const=True)
|
||||
self.descriptor = descriptor
|
||||
|
|
@ -10716,7 +10716,7 @@ class CGDOMJSProxyHandler_setCustom(ClassMethod):
|
|||
raise ValueError("In interface " + self.descriptor.name + ": " +
|
||||
"Can't cope with [OverrideBuiltins] and unforgeable members")
|
||||
|
||||
callSetter = CGProxyNamedSetter(self.descriptor, argumentHandleValue="v")
|
||||
callSetter = CGProxyNamedSetter(self.descriptor, argumentMutableValue="vp")
|
||||
return (assertion +
|
||||
callSetter.define() +
|
||||
"*done = true;\n"
|
||||
|
|
@ -10741,7 +10741,7 @@ class CGDOMJSProxyHandler_setCustom(ClassMethod):
|
|||
|
||||
""",
|
||||
callSetter=CGProxyIndexedSetter(self.descriptor,
|
||||
argumentHandleValue="v").define())
|
||||
argumentMutableValue="vp").define())
|
||||
else:
|
||||
setIndexed = ""
|
||||
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ BaseDOMProxyHandler::getOwnPropertyDescriptor(JSContext* cx,
|
|||
|
||||
bool
|
||||
DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result, bool *defined) const
|
||||
{
|
||||
if (desc.hasGetterObject() && desc.setter() == JS_StrictPropertyStub) {
|
||||
|
|
@ -219,14 +219,13 @@ DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::
|
|||
}
|
||||
|
||||
bool
|
||||
DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<jsid> id,
|
||||
Handle<JS::Value> v, Handle<JS::Value> receiver,
|
||||
ObjectOpResult &result) const
|
||||
DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<JSObject*> receiver,
|
||||
Handle<jsid> id, MutableHandle<JS::Value> vp, ObjectOpResult &result) const
|
||||
{
|
||||
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
|
||||
"Should not have a XrayWrapper here");
|
||||
bool done;
|
||||
if (!setCustom(cx, proxy, id, v, &done)) {
|
||||
if (!setCustom(cx, proxy, id, vp, &done)) {
|
||||
return false;
|
||||
}
|
||||
if (done) {
|
||||
|
|
@ -253,7 +252,7 @@ DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<jsid> id,
|
|||
}
|
||||
}
|
||||
|
||||
return js::SetPropertyIgnoringNamedGetter(cx, proxy, id, v, receiver, desc, result);
|
||||
return js::SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, &desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -351,7 +350,7 @@ IdToInt32(JSContext* cx, JS::Handle<jsid> id)
|
|||
|
||||
bool
|
||||
DOMProxyHandler::setCustom(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::Handle<JS::Value> v, bool *done) const
|
||||
JS::MutableHandle<JS::Value> vp, bool *done) const
|
||||
{
|
||||
*done = false;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -105,14 +105,14 @@ public:
|
|||
{}
|
||||
|
||||
bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const override
|
||||
{
|
||||
bool unused;
|
||||
return defineProperty(cx, proxy, id, desc, result, &unused);
|
||||
}
|
||||
virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result, bool *defined) const;
|
||||
bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
|
|
@ -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<jsid> id,
|
||||
JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver, JS::ObjectOpResult &result)
|
||||
bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp, 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::Handle<JS::Value> v, bool *done) const;
|
||||
JS::MutableHandle<JS::Value> vp, bool *done) const;
|
||||
|
||||
static JSObject* GetExpandoObject(JSObject* obj);
|
||||
|
||||
|
|
|
|||
|
|
@ -71,9 +71,10 @@ 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 JSIDVariant &id, const JSVariant &value,
|
||||
const JSVariant &receiverVar, ReturnStatus *rs) {
|
||||
return Answer::RecvSet(ObjectId::deserialize(objId), id, value, receiverVar, rs);
|
||||
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 RecvIsExtensible(const uint64_t &objId, ReturnStatus *rs,
|
||||
|
|
@ -160,9 +161,10 @@ 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 JSIDVariant &id, const JSVariant &value,
|
||||
const JSVariant &receiverVar, ReturnStatus *rs) {
|
||||
return Base::SendSet(objId.serialize(), id, value, receiverVar, rs);
|
||||
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 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, JSIDVariant id, JSVariant value, JSVariant receiver) returns (ReturnStatus rs);
|
||||
prio(high) sync Set(uint64_t objId, ObjectVariant receiver, JSIDVariant id, JSVariant value) returns (ReturnStatus rs, JSVariant result);
|
||||
|
||||
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,17 +308,26 @@ WrapperAnswer::RecvGet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
|||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::RecvSet(const ObjectId &objId, const JSIDVariant &idVar, const JSVariant &value,
|
||||
const JSVariant &receiverVar, ReturnStatus *rs)
|
||||
WrapperAnswer::RecvSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &idVar, const JSVariant &value, ReturnStatus *rs,
|
||||
JSVariant *resultValue)
|
||||
{
|
||||
// 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);
|
||||
|
|
@ -329,12 +338,12 @@ WrapperAnswer::RecvSet(const ObjectId &objId, const JSIDVariant &idVar, const JS
|
|||
if (!fromVariant(cx, value, &val))
|
||||
return fail(cx, rs);
|
||||
|
||||
RootedValue receiver(cx);
|
||||
if (!fromVariant(cx, receiverVar, &receiver))
|
||||
ObjectOpResult result;
|
||||
RootedValue receiverVal(cx, ObjectValue(*receiver));
|
||||
if (!JS_ForwardSetPropertyTo(cx, obj, id, val, receiverVal, result))
|
||||
return fail(cx, rs);
|
||||
|
||||
ObjectOpResult result;
|
||||
if (!JS_ForwardSetPropertyTo(cx, obj, id, val, receiver, result))
|
||||
if (!toVariant(cx, val, resultValue))
|
||||
return fail(cx, rs);
|
||||
|
||||
return ok(rs, result);
|
||||
|
|
|
|||
|
|
@ -37,8 +37,9 @@ 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 JSIDVariant &id, const JSVariant &value,
|
||||
const JSVariant &receiverVar, ReturnStatus *rs);
|
||||
bool RecvSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id, const JSVariant &value, ReturnStatus *rs,
|
||||
JSVariant *result);
|
||||
|
||||
bool RecvIsExtensible(const ObjectId &objId, ReturnStatus *rs,
|
||||
bool *result);
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class CPOWProxyHandler : public BaseProxyHandler
|
|||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const override;
|
||||
|
|
@ -110,8 +110,9 @@ 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::HandleId id, JS::HandleValue v,
|
||||
JS::HandleValue receiver, JS::ObjectOpResult &result) 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 call(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;
|
||||
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) const override;
|
||||
|
||||
|
|
@ -212,7 +213,7 @@ WrapperOwner::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, Handle
|
|||
|
||||
bool
|
||||
CPOWProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
FORWARD(defineProperty, (cx, proxy, id, desc, result));
|
||||
|
|
@ -220,7 +221,7 @@ CPOWProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
|||
|
||||
bool
|
||||
WrapperOwner::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
ObjectId objId = idOf(proxy);
|
||||
|
|
@ -516,37 +517,41 @@ WrapperOwner::get(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
|||
}
|
||||
|
||||
bool
|
||||
CPOWProxyHandler::set(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue v,
|
||||
JS::HandleValue receiver, JS::ObjectOpResult &result) const
|
||||
CPOWProxyHandler::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result) const
|
||||
{
|
||||
FORWARD(set, (cx, proxy, id, v, receiver, result));
|
||||
FORWARD(set, (cx, proxy, receiver, id, vp, result));
|
||||
}
|
||||
|
||||
bool
|
||||
WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleId id, JS::HandleValue v,
|
||||
JS::HandleValue receiver, JS::ObjectOpResult &result)
|
||||
WrapperOwner::set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp, 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, v, &val))
|
||||
return false;
|
||||
|
||||
JSVariant receiverVar;
|
||||
if (!toVariant(cx, receiver, &receiverVar))
|
||||
if (!toVariant(cx, vp, &val))
|
||||
return false;
|
||||
|
||||
ReturnStatus status;
|
||||
if (!SendSet(objId, idVar, val, receiverVar, &status))
|
||||
JSVariant resultValue;
|
||||
if (!SendSet(objId, receiverVar, idVar, val, &status, &resultValue))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
return ok(cx, status, result);
|
||||
if (!ok(cx, status, result))
|
||||
return false;
|
||||
|
||||
return fromVariant(cx, resultValue, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class WrapperOwner : public virtual JavaScriptShared
|
|||
bool getOwnPropertyDescriptor(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result);
|
||||
bool ownPropertyKeys(JSContext *cx, JS::HandleObject proxy, JS::AutoIdVector &props);
|
||||
bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
|
|
@ -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::HandleId id, JS::HandleValue v,
|
||||
JS::HandleValue receiver, JS::ObjectOpResult &result);
|
||||
bool set(JSContext *cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
bool callOrConstruct(JSContext *cx, JS::HandleObject proxy, const JS::CallArgs &args,
|
||||
bool construct);
|
||||
|
||||
|
|
@ -128,8 +128,9 @@ 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 JSIDVariant &id, const JSVariant &value,
|
||||
const JSVariant &receiverVar, ReturnStatus *rs) = 0;
|
||||
virtual bool SendSet(const ObjectId &objId, const ObjectVariant &receiverVar,
|
||||
const JSIDVariant &id, const JSVariant &value,
|
||||
ReturnStatus *rs, JSVariant *result) = 0;
|
||||
|
||||
virtual bool SendIsExtensible(const ObjectId &objId, ReturnStatus *rs,
|
||||
bool *result) = 0;
|
||||
|
|
|
|||
|
|
@ -333,8 +333,8 @@ typedef bool
|
|||
(* LookupPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::MutableHandleObject objp, JS::MutableHandle<Shape*> propp);
|
||||
typedef bool
|
||||
(* DefinePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
(* DefinePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
JS::ObjectOpResult &result);
|
||||
typedef bool
|
||||
(* HasPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *foundp);
|
||||
|
|
@ -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::HandleId id, JS::HandleValue v,
|
||||
JS::HandleValue receiver, JS::ObjectOpResult &result);
|
||||
(* SetPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
|
||||
JS::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
typedef bool
|
||||
(* GetOwnPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ namespace js {
|
|||
|
||||
using JS::AutoIdVector;
|
||||
using JS::CallArgs;
|
||||
using JS::Handle;
|
||||
using JS::HandleId;
|
||||
using JS::HandleObject;
|
||||
using JS::HandleValue;
|
||||
|
|
@ -253,7 +252,7 @@ class JS_FRIEND_API(BaseProxyHandler)
|
|||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const = 0;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const = 0;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const = 0;
|
||||
|
|
@ -295,8 +294,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, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const;
|
||||
virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const;
|
||||
|
||||
/*
|
||||
* [[Call]] and [[Construct]] are standard internal methods but according
|
||||
|
|
@ -374,7 +373,7 @@ class JS_FRIEND_API(DirectProxyHandler) : public BaseProxyHandler
|
|||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const override;
|
||||
|
|
@ -395,8 +394,9 @@ 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, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const override;
|
||||
virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp,
|
||||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -1751,8 +1751,8 @@ ReportPropertyError(JSContext *cx,
|
|||
}
|
||||
|
||||
bool
|
||||
TypedObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
TypedObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
Rooted<TypedObject *> typedObj(cx, &obj->as<TypedObject>());
|
||||
|
|
@ -1904,8 +1904,8 @@ TypedObject::obj_getArrayElement(JSContext *cx,
|
|||
}
|
||||
|
||||
bool
|
||||
TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result)
|
||||
TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
Rooted<TypedObject *> typedObj(cx, &obj->as<TypedObject>());
|
||||
|
||||
|
|
@ -1919,7 +1919,7 @@ TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, Handl
|
|||
|
||||
case type::Array: {
|
||||
if (JSID_IS_ATOM(id, cx->names().length)) {
|
||||
if (receiver.isObject() && obj == &receiver.toObject()) {
|
||||
if (obj == receiver) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage,
|
||||
nullptr, JSMSG_CANT_REDEFINE_ARRAY_LENGTH);
|
||||
return false;
|
||||
|
|
@ -1929,8 +1929,8 @@ TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, Handl
|
|||
|
||||
uint32_t index;
|
||||
if (IdIsIndex(id, &index)) {
|
||||
if (!receiver.isObject() || obj != &receiver.toObject())
|
||||
return SetPropertyByDefining(cx, obj, id, v, receiver, false, result);
|
||||
if (obj != receiver)
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result);
|
||||
|
||||
if (index >= uint32_t(typedObj->length())) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage,
|
||||
|
|
@ -1941,7 +1941,7 @@ TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, Handl
|
|||
Rooted<TypeDescr*> elementType(cx);
|
||||
elementType = &typedObj->typeDescr().as<ArrayTypeDescr>().elementType();
|
||||
size_t offset = elementType->size() * index;
|
||||
if (!ConvertAndCopyTo(cx, elementType, typedObj, offset, NullPtr(), v))
|
||||
if (!ConvertAndCopyTo(cx, elementType, typedObj, offset, NullPtr(), vp))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
|
@ -1955,19 +1955,19 @@ TypedObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, Handl
|
|||
if (!descr->fieldIndex(id, &fieldIndex))
|
||||
break;
|
||||
|
||||
if (!receiver.isObject() || obj != &receiver.toObject())
|
||||
return SetPropertyByDefining(cx, obj, id, v, receiver, false, result);
|
||||
if (obj != receiver)
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, 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, v))
|
||||
if (!ConvertAndCopyTo(cx, fieldType, typedObj, offset, fieldName, vp))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
|
||||
return SetPropertyOnProto(cx, obj, id, v, receiver, result);
|
||||
return SetPropertyOnProto(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -528,8 +528,8 @@ class TypedObject : public JSObject
|
|||
static bool obj_lookupElement(JSContext *cx, HandleObject obj, uint32_t index,
|
||||
MutableHandleObject objp, MutableHandleShape propp);
|
||||
|
||||
static bool obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
static bool obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result);
|
||||
|
||||
static bool obj_hasProperty(JSContext *cx, HandleObject obj, HandleId id, bool *foundp);
|
||||
|
|
@ -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, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result);
|
||||
static bool obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
static bool obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
|
|
|||
|
|
@ -8364,7 +8364,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -429,6 +429,7 @@ 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);
|
||||
|
|
@ -442,21 +443,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>(), id, value, receiver,
|
||||
cx, obj.as<NativeObject>(), obj.as<NativeObject>(), id,
|
||||
(op == JSOP_SETNAME || op == JSOP_STRICTSETNAME ||
|
||||
op == JSOP_SETGNAME || op == JSOP_STRICTSETGNAME)
|
||||
? Unqualified
|
||||
: Qualified,
|
||||
&v,
|
||||
result))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!SetProperty(cx, obj, id, value, receiver, result))
|
||||
if (!SetProperty(cx, obj, obj, id, &v, result))
|
||||
return false;
|
||||
}
|
||||
return result.checkStrictErrorOrWarning(cx, obj, id, strict);
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ 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, HandleId id, HandleValue v, HandleValue receiver,
|
||||
ObjectOpResult &result) const override
|
||||
bool set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const override
|
||||
{
|
||||
Rooted<JSPropertyDescriptor> desc(cx);
|
||||
if (!DirectProxyHandler::getPropertyDescriptor(cx, proxy, id, &desc))
|
||||
return false;
|
||||
return SetPropertyIgnoringNamedGetter(cx, proxy, id, v, receiver, desc, result);
|
||||
return SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, 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 || code_ == JSMSG_SET_NON_OBJECT_RECEIVER) {
|
||||
if (code_ == JSMSG_OBJECT_NOT_EXTENSIBLE) {
|
||||
RootedValue val(cx, ObjectValue(*obj));
|
||||
return ReportValueErrorFlags(cx, flags, code_, JSDVG_IGNORE_STACK, val,
|
||||
NullPtr(), nullptr, nullptr);
|
||||
|
|
@ -2205,12 +2205,10 @@ DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue val
|
|||
// it's just a plain old data property. However the JS_Define* APIs use
|
||||
// null getter and setter to mean "default to the Class getProperty and
|
||||
// setProperty ops".
|
||||
if (!(attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
|
||||
if (!getter)
|
||||
getter = obj->getClass()->getProperty;
|
||||
if (!setter)
|
||||
setter = obj->getClass()->setProperty;
|
||||
}
|
||||
if (getter == JS_PropertyStub)
|
||||
getter = nullptr;
|
||||
if (setter == JS_StrictPropertyStub)
|
||||
|
|
@ -2830,13 +2828,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, id, v, receiver, ignored);
|
||||
return SetProperty(cx, obj, obj, id, &value, ignored);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
|
@ -2847,60 +2845,66 @@ JS_ForwardSetPropertyTo(JSContext *cx, HandleObject obj, HandleId id, HandleValu
|
|||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, id, receiver);
|
||||
|
||||
return SetProperty(cx, obj, id, v, receiver, result);
|
||||
// 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);
|
||||
}
|
||||
|
||||
static bool
|
||||
SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v)
|
||||
SetElement(JSContext *cx, HandleObject obj, uint32_t index, MutableHandleValue vp)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, v);
|
||||
assertSameCompartment(cx, obj, vp);
|
||||
|
||||
RootedValue receiver(cx, ObjectValue(*obj));
|
||||
ObjectOpResult ignored;
|
||||
return SetElement(cx, obj, index, v, receiver, ignored);
|
||||
return SetElement(cx, obj, obj, index, vp, ignored);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v)
|
||||
{
|
||||
return SetElement(cx, obj, index, v);
|
||||
RootedValue value(cx, v);
|
||||
return SetElement(cx, obj, index, &value);
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -2600,18 +2600,6 @@ class MutablePropertyDescriptorOperations : public PropertyDescriptorOperations<
|
|||
value().setUndefined();
|
||||
}
|
||||
|
||||
void initFields(HandleObject obj, HandleValue v, unsigned attrs,
|
||||
JSGetterOp getterOp, JSSetterOp setterOp) {
|
||||
MOZ_ASSERT(getterOp != JS_PropertyStub);
|
||||
MOZ_ASSERT(setterOp != JS_StrictPropertyStub);
|
||||
|
||||
object().set(obj);
|
||||
value().set(v);
|
||||
setAttributes(attrs);
|
||||
setGetter(getterOp);
|
||||
setSetter(setterOp);
|
||||
}
|
||||
|
||||
void assign(JSPropertyDescriptor &other) {
|
||||
object().set(other.obj);
|
||||
setAttributes(other.attrs);
|
||||
|
|
|
|||
|
|
@ -364,7 +364,8 @@ SetArrayElement(JSContext *cx, HandleObject obj, double index, HandleValue v)
|
|||
if (!ToId(cx, index, &id))
|
||||
return false;
|
||||
|
||||
return SetProperty(cx, obj, id, v);
|
||||
RootedValue tmp(cx, v);
|
||||
return SetProperty(cx, obj, obj, id, &tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -433,7 +434,7 @@ bool
|
|||
js::SetLengthProperty(JSContext *cx, HandleObject obj, double length)
|
||||
{
|
||||
RootedValue v(cx, NumberValue(length));
|
||||
return SetProperty(cx, obj, cx->names().length, v);
|
||||
return SetProperty(cx, obj, obj, cx->names().length, &v);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1269,10 +1270,11 @@ InitArrayElements(JSContext *cx, HandleObject obj, uint32_t start, uint32_t coun
|
|||
do {
|
||||
value = *vector++;
|
||||
indexv = DoubleValue(index);
|
||||
if (!ValueToId<CanGC>(cx, indexv, &id))
|
||||
return false;
|
||||
if (!SetProperty(cx, obj, id, value))
|
||||
if (!ValueToId<CanGC>(cx, indexv, &id) ||
|
||||
!SetProperty(cx, obj, obj, id, &value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
index += 1;
|
||||
} while (vector != end);
|
||||
|
||||
|
|
|
|||
|
|
@ -332,6 +332,26 @@ CallJSDeletePropertyOp(JSContext *cx, JSDeletePropertyOp op, HandleObject receiv
|
|||
return result.succeed();
|
||||
}
|
||||
|
||||
inline bool
|
||||
CallSetter(JSContext *cx, HandleObject obj, HandleId id, SetterOp op, unsigned attrs,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
if (attrs & JSPROP_SETTER) {
|
||||
RootedValue opv(cx, CastAsObjectJsval(op));
|
||||
if (!InvokeGetterOrSetter(cx, obj, opv, 1, vp.address(), vp))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
if (attrs & JSPROP_GETTER)
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
|
||||
if (!op)
|
||||
return result.succeed();
|
||||
|
||||
return CallJSSetterOp(cx, op, obj, id, vp, result);
|
||||
}
|
||||
|
||||
inline uintptr_t
|
||||
GetNativeStackLimit(ExclusiveContext *cx)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -359,8 +359,8 @@ extern JS_FRIEND_API(bool)
|
|||
proxy_LookupProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleObject objp,
|
||||
JS::MutableHandle<Shape*> propp);
|
||||
extern JS_FRIEND_API(bool)
|
||||
proxy_DefineProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
proxy_DefineProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
JS::ObjectOpResult &result);
|
||||
extern JS_FRIEND_API(bool)
|
||||
proxy_HasProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *foundp);
|
||||
|
|
@ -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::HandleId id, JS::HandleValue bp,
|
||||
JS::HandleValue receiver, JS::ObjectOpResult &result);
|
||||
proxy_SetProperty(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
|
||||
JS::MutableHandleValue bp, JS::ObjectOpResult &result);
|
||||
extern JS_FRIEND_API(bool)
|
||||
proxy_GetOwnPropertyDescriptor(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
|
@ -2632,8 +2632,8 @@ ForwardToNative(JSContext *cx, JSNative native, const JS::CallArgs &args);
|
|||
*/
|
||||
JS_FRIEND_API(bool)
|
||||
SetPropertyIgnoringNamedGetter(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::HandleValue v, JS::HandleValue receiver,
|
||||
JS::Handle<JSPropertyDescriptor> ownDesc,
|
||||
JS::MutableHandleValue vp, JS::HandleObject receiver,
|
||||
JS::MutableHandle<JSPropertyDescriptor> ownDesc,
|
||||
JS::ObjectOpResult &result);
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
|
|
|
|||
|
|
@ -689,7 +689,7 @@ js::StandardDefineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
|||
if (obj->is<ProxyObject>()) {
|
||||
Rooted<PropertyDescriptor> pd(cx, desc);
|
||||
pd.object().set(obj);
|
||||
return Proxy::defineProperty(cx, obj, id, pd, result);
|
||||
return Proxy::defineProperty(cx, obj, id, &pd, result);
|
||||
}
|
||||
return result.fail(JSMSG_OBJECT_NOT_EXTENSIBLE);
|
||||
}
|
||||
|
|
@ -1584,26 +1584,25 @@ js::CreateThisForFunction(JSContext *cx, HandleObject callee, NewObjectKind newK
|
|||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::nonNativeSetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result)
|
||||
JSObject::nonNativeSetProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
RootedValue value(cx, v);
|
||||
if (MOZ_UNLIKELY(obj->watched())) {
|
||||
WatchpointMap *wpmap = cx->compartment()->watchpointMap;
|
||||
if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, &value))
|
||||
if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, vp))
|
||||
return false;
|
||||
}
|
||||
return obj->getOps()->setProperty(cx, obj, id, value, receiver, result);
|
||||
return obj->getOps()->setProperty(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::nonNativeSetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result)
|
||||
JSObject::nonNativeSetElement(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
uint32_t index, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
return nonNativeSetProperty(cx, obj, id, v, receiver, result);
|
||||
return nonNativeSetProperty(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
|
|
@ -3193,30 +3192,23 @@ js::GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::DefineProperty(JSContext *cx, HandleObject obj, HandleId id, Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
if (DefinePropertyOp op = obj->getOps()->defineProperty)
|
||||
return op(cx, obj, id, desc, result);
|
||||
return NativeDefineProperty(cx, obj.as<NativeObject>(), id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::DefineProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
MOZ_ASSERT(!(attrs & JSPROP_PROPOP_ACCESSORS));
|
||||
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
desc.initFields(obj, value, attrs, getter, setter);
|
||||
if (DefinePropertyOp op = obj->getOps()->defineProperty) {
|
||||
DefinePropertyOp op = obj->getOps()->defineProperty;
|
||||
if (op) {
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
return op(cx->asJSContext(), obj, id, desc, result);
|
||||
return op(cx->asJSContext(), obj, id, value, getter, setter, attrs, result);
|
||||
}
|
||||
return NativeDefineProperty(cx, obj.as<NativeObject>(), id, desc, result);
|
||||
return NativeDefineProperty(cx, obj.as<NativeObject>(), id, value, getter, setter, attrs,
|
||||
result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -3279,6 +3271,22 @@ 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 ***************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -478,12 +478,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::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 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 swap(JSContext *cx, JS::HandleObject a, JS::HandleObject b);
|
||||
|
||||
|
|
@ -768,10 +768,6 @@ extern bool
|
|||
StandardDefineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> desc);
|
||||
|
||||
extern bool
|
||||
DefineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> desc, ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
DefineProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs, ObjectOpResult &result);
|
||||
|
|
@ -853,52 +849,49 @@ inline bool
|
|||
GetElementNoGC(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp);
|
||||
|
||||
/*
|
||||
* ES6 [[Set]]. Carry out the assignment `obj[id] = v`.
|
||||
* ES6 [[Set]]. Carry out the assignment `obj[id] = vp`.
|
||||
*
|
||||
* 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
|
||||
* `ObjectValue(*obj)` as receiver. Or better, use one of the signatures that
|
||||
* doesn't have a receiver parameter.
|
||||
* try. Long story short, if you just want bog-standard assignment, pass the
|
||||
* same object as both obj and receiver.
|
||||
*
|
||||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
inline bool
|
||||
SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result);
|
||||
SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
inline bool
|
||||
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)
|
||||
SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, PropertyName *name,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return SetProperty(cx, obj, id, v, receiver, result);
|
||||
return SetProperty(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
inline bool
|
||||
SetProperty(JSContext *cx, HandleObject obj, PropertyName *name, HandleValue v)
|
||||
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)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
RootedValue receiver(cx, ObjectValue(*obj));
|
||||
ObjectOpResult result;
|
||||
return SetProperty(cx, obj, id, v, receiver, result) &&
|
||||
result.checkStrict(cx, obj, id);
|
||||
return SetProperty(cx, obj, receiver, id, vp, result) &&
|
||||
result.checkStrict(cx, receiver, id);
|
||||
}
|
||||
|
||||
inline bool
|
||||
SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result);
|
||||
extern bool
|
||||
SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandlePropertyName name,
|
||||
MutableHandleValue vp);
|
||||
|
||||
/*
|
||||
* ES6 draft rev 31 (15 Jan 2015) 7.3.3 Put (O, P, V, Throw), except that on
|
||||
|
|
@ -906,14 +899,17 @@ SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v,
|
|||
* don't bother doing.
|
||||
*/
|
||||
inline bool
|
||||
PutProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v, bool strict)
|
||||
PutProperty(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue value, bool strict)
|
||||
{
|
||||
RootedValue receiver(cx, ObjectValue(*obj));
|
||||
ObjectOpResult result;
|
||||
return SetProperty(cx, obj, id, v, receiver, result) &&
|
||||
return SetProperty(cx, obj, obj, id, value, 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]`.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -2168,7 +2168,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_, cx->names().lastIndex, zero);
|
||||
return SetProperty(cx, obj_, obj_, cx->names().lastIndex, &zero);
|
||||
}
|
||||
|
||||
RegExpShared ®Exp() { return *re_; }
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
|
|||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject wrapper,
|
||||
AutoIdVector &props) const override;
|
||||
|
|
@ -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, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const override;
|
||||
virtual bool set(JSContext *cx, HandleObject wrapper, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, 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;
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ class JS_FRIEND_API(SecurityWrapper) : public Base
|
|||
bool *bp) const override;
|
||||
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const override;
|
||||
virtual bool preventExtensions(JSContext *cx, HandleObject wrapper,
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ BaseProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
|||
return true;
|
||||
}
|
||||
if (desc.hasGetterObject())
|
||||
return InvokeGetter(cx, receiver, ObjectValue(*desc.getterObject()), vp);
|
||||
return InvokeGetterOrSetter(cx, receiver, ObjectValue(*desc.getterObject()),
|
||||
0, nullptr, vp);
|
||||
if (!desc.isShared())
|
||||
vp.set(desc.value());
|
||||
else
|
||||
|
|
@ -71,8 +72,8 @@ BaseProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
|||
}
|
||||
|
||||
bool
|
||||
BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const
|
||||
BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
|
||||
|
|
@ -87,16 +88,15 @@ BaseProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValu
|
|||
|
||||
// The rest is factored out into a separate function with a weird name.
|
||||
// This algorithm continues just below.
|
||||
return SetPropertyIgnoringNamedGetter(cx, proxy, id, v, receiver, ownDesc, result);
|
||||
return SetPropertyIgnoringNamedGetter(cx, proxy, id, vp, receiver, &ownDesc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, Handle<PropertyDescriptor> ownDesc_,
|
||||
js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleValue vp, HandleObject receiver,
|
||||
MutableHandle<PropertyDescriptor> ownDesc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
Rooted<PropertyDescriptor> ownDesc(cx, ownDesc_);
|
||||
|
||||
// Step 4.
|
||||
if (!ownDesc.object()) {
|
||||
// The spec calls this variable "parent", but that word has weird
|
||||
|
|
@ -105,33 +105,31 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id,
|
|||
if (!GetPrototype(cx, obj, &proto))
|
||||
return false;
|
||||
if (proto)
|
||||
return SetProperty(cx, proto, id, v, receiver, result);
|
||||
return SetProperty(cx, proto, receiver, id, vp, result);
|
||||
|
||||
// Step 4.d.
|
||||
ownDesc.setDataDescriptor(UndefinedHandleValue, JSPROP_ENUMERATE);
|
||||
// Change ownDesc to be a complete descriptor for a configurable,
|
||||
// writable, enumerable data property. Then fall through to step 5.
|
||||
ownDesc.clear();
|
||||
ownDesc.setAttributes(JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
if (ownDesc.isDataDescriptor()) {
|
||||
// Steps 5.a-b.
|
||||
// Steps 5.a-b, adapted to our nonstandard implementation of ES6
|
||||
// [[Set]] return values.
|
||||
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) {
|
||||
RootedValue valCopy(cx, v);
|
||||
return CallJSSetterOp(cx, setter, receiverObj, id, &valCopy, result);
|
||||
}
|
||||
if (setter && setter != JS_StrictPropertyStub)
|
||||
return CallSetter(cx, receiver, id, setter, ownDesc.attributes(), vp, result);
|
||||
|
||||
// Steps 5.c-d. Adapt for SpiderMonkey by using HasOwnProperty instead
|
||||
// of the standard [[GetOwnProperty]].
|
||||
bool existingDescriptor;
|
||||
if (!HasOwnProperty(cx, receiverObj, id, &existingDescriptor))
|
||||
if (!HasOwnProperty(cx, receiver, id, &existingDescriptor))
|
||||
return false;
|
||||
|
||||
// Steps 5.e-f.
|
||||
|
|
@ -142,10 +140,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 = receiverObj->getClass();
|
||||
const Class *clasp = receiver->getClass();
|
||||
MOZ_ASSERT(clasp->getProperty != JS_PropertyStub);
|
||||
MOZ_ASSERT(clasp->setProperty != JS_StrictPropertyStub);
|
||||
return DefineProperty(cx, receiverObj, id, v, clasp->getProperty, clasp->setProperty,
|
||||
return DefineProperty(cx, receiver, id, vp, clasp->getProperty, clasp->setProperty,
|
||||
attrs, result);
|
||||
}
|
||||
|
||||
|
|
@ -157,7 +155,7 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, HandleObject obj, HandleId id,
|
|||
if (!setter)
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
RootedValue setterValue(cx, ObjectValue(*setter));
|
||||
if (!InvokeSetter(cx, receiver, setterValue, v))
|
||||
if (!InvokeGetterOrSetter(cx, receiver, setterValue, 1, vp.address(), vp))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,13 +49,13 @@ CrossCompartmentWrapper::getOwnPropertyDescriptor(JSContext *cx, HandleObject wr
|
|||
|
||||
bool
|
||||
CrossCompartmentWrapper::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
Rooted<PropertyDescriptor> desc2(cx, desc);
|
||||
PIERCE(cx, wrapper,
|
||||
cx->compartment()->wrap(cx, &desc2),
|
||||
Wrapper::defineProperty(cx, wrapper, id, desc2, result),
|
||||
Wrapper::defineProperty(cx, wrapper, id, &desc2, result),
|
||||
NOTHING);
|
||||
}
|
||||
|
||||
|
|
@ -169,15 +169,14 @@ CrossCompartmentWrapper::get(JSContext *cx, HandleObject wrapper, HandleObject r
|
|||
}
|
||||
|
||||
bool
|
||||
CrossCompartmentWrapper::set(JSContext *cx, HandleObject wrapper, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const
|
||||
CrossCompartmentWrapper::set(JSContext *cx, HandleObject wrapper, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
RootedValue valCopy(cx, v);
|
||||
RootedValue receiverCopy(cx, receiver);
|
||||
RootedObject receiverCopy(cx, receiver);
|
||||
PIERCE(cx, wrapper,
|
||||
cx->compartment()->wrap(cx, &valCopy) &&
|
||||
cx->compartment()->wrap(cx, &receiverCopy),
|
||||
Wrapper::set(cx, wrapper, id, valCopy, receiverCopy, result),
|
||||
cx->compartment()->wrap(cx, &receiverCopy) &&
|
||||
cx->compartment()->wrap(cx, vp),
|
||||
Wrapper::set(cx, wrapper, receiverCopy, id, vp, result),
|
||||
NOTHING);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ DeadObjectProxy::getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, H
|
|||
|
||||
bool
|
||||
DeadObjectProxy::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class DeadObjectProxy : public BaseProxyHandler
|
|||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject wrapper,
|
||||
AutoIdVector &props) const override;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ DirectProxyHandler::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy,
|
|||
|
||||
bool
|
||||
DirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
|
|
@ -216,12 +216,12 @@ DirectProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObject receiver
|
|||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const
|
||||
DirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return SetProperty(cx, target, id, v, receiver, result);
|
||||
return SetProperty(cx, target, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ Proxy::getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
|||
|
||||
bool
|
||||
Proxy::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc, ObjectOpResult &result)
|
||||
MutableHandle<PropertyDescriptor> desc, ObjectOpResult &result)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
const BaseProxyHandler *handler = proxy->as<ProxyObject>().handler();
|
||||
|
|
@ -307,8 +307,8 @@ Proxy::callProp(JSContext *cx, HandleObject proxy, HandleObject receiver, Handle
|
|||
}
|
||||
|
||||
bool
|
||||
Proxy::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver,
|
||||
ObjectOpResult &result)
|
||||
Proxy::set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, 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, HandleId id, HandleValue v, Handle
|
|||
|
||||
// Special case. See the comment on BaseProxyHandler::mHasPrototype.
|
||||
if (handler->hasPrototype())
|
||||
return handler->BaseProxyHandler::set(cx, proxy, id, v, receiver, result);
|
||||
return handler->BaseProxyHandler::set(cx, proxy, receiver, id, vp, result);
|
||||
|
||||
return handler->set(cx, proxy, id, v, receiver, result);
|
||||
return handler->set(cx, proxy, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -559,11 +559,17 @@ js::proxy_LookupProperty(JSContext *cx, HandleObject obj, HandleId id,
|
|||
}
|
||||
|
||||
bool
|
||||
js::proxy_DefineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
js::proxy_DefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
return Proxy::defineProperty(cx, obj, id, desc, result);
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
desc.object().set(obj);
|
||||
desc.value().set(value);
|
||||
desc.setAttributes(attrs);
|
||||
desc.setGetter(getter);
|
||||
desc.setSetter(setter);
|
||||
return Proxy::defineProperty(cx, obj, id, &desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -580,10 +586,10 @@ js::proxy_GetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, Ha
|
|||
}
|
||||
|
||||
bool
|
||||
js::proxy_SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result)
|
||||
js::proxy_SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
return Proxy::set(cx, obj, id, v, receiver, result);
|
||||
return Proxy::set(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class Proxy
|
|||
static bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc);
|
||||
static bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc, ObjectOpResult &result);
|
||||
MutableHandle<JSPropertyDescriptor> desc, ObjectOpResult &result);
|
||||
static bool ownPropertyKeys(JSContext *cx, HandleObject proxy, AutoIdVector &props);
|
||||
static bool delete_(JSContext *cx, HandleObject proxy, HandleId id, ObjectOpResult &result);
|
||||
static bool enumerate(JSContext *cx, HandleObject proxy, MutableHandleObject objp);
|
||||
|
|
@ -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, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result);
|
||||
static bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result);
|
||||
static bool call(JSContext *cx, HandleObject proxy, const CallArgs &args);
|
||||
static bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args);
|
||||
|
||||
|
|
|
|||
|
|
@ -550,7 +550,7 @@ ScriptedDirectProxyHandler::getOwnPropertyDescriptor(JSContext *cx, HandleObject
|
|||
// ES6 draft rev 31 (15 Jan 2015) 9.5.6 Proxy.[[DefineOwnProperty]](P, Desc)
|
||||
bool
|
||||
ScriptedDirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
// steps 2-4
|
||||
|
|
@ -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, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const
|
||||
ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, 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, HandleId id,
|
|||
|
||||
// step 8
|
||||
if (trap.isUndefined())
|
||||
return SetProperty(cx, target, id, v, receiver, result);
|
||||
return SetProperty(cx, target, receiver, id, vp, result);
|
||||
|
||||
// step 9-10
|
||||
RootedValue value(cx);
|
||||
|
|
@ -949,8 +949,8 @@ ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id,
|
|||
Value argv[] = {
|
||||
ObjectOrNullValue(target),
|
||||
value,
|
||||
v.get(),
|
||||
receiver.get()
|
||||
vp.get(),
|
||||
ObjectValue(*receiver)
|
||||
};
|
||||
RootedValue trapResult(cx);
|
||||
if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult))
|
||||
|
|
@ -969,7 +969,7 @@ ScriptedDirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id,
|
|||
if (desc.object()) {
|
||||
if (desc.isDataDescriptor() && !desc.configurable() && !desc.writable()) {
|
||||
bool same;
|
||||
if (!SameValue(cx, v, desc.value(), &same))
|
||||
if (!SameValue(cx, vp, desc.value(), &same))
|
||||
return false;
|
||||
if (!same) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_SET_NW_NC);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class ScriptedDirectProxyHandler : public BaseProxyHandler {
|
|||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const override;
|
||||
|
|
@ -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, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const override;
|
||||
virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, 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;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
|
||||
#include "jscntxtinlines.h"
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
using namespace js;
|
||||
|
|
@ -197,7 +196,7 @@ ScriptedIndirectProxyHandler::getOwnPropertyDescriptor(JSContext *cx, HandleObje
|
|||
|
||||
bool
|
||||
ScriptedIndirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy));
|
||||
|
|
@ -304,55 +303,30 @@ ScriptedIndirectProxyHandler::get(JSContext *cx, HandleObject proxy, HandleObjec
|
|||
}
|
||||
|
||||
bool
|
||||
ScriptedIndirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const
|
||||
ScriptedIndirectProxyHandler::set(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, 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].set(receiver);
|
||||
argv[0].setObjectOrNull(receiver);
|
||||
argv[1].set(idv);
|
||||
argv[2].set(v);
|
||||
argv[2].set(vp);
|
||||
RootedValue fval(cx);
|
||||
if (!GetDerivedTrap(cx, handler, cx->names().set, &fval))
|
||||
return false;
|
||||
if (!IsCallable(fval))
|
||||
return derivedSet(cx, proxy, id, v, receiver, result);
|
||||
return derivedSet(cx, proxy, receiver, id, vp, result);
|
||||
if (!Trap(cx, handler, fval, 3, argv.begin(), &idv))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
static bool
|
||||
CallSetter(JSContext *cx, HandleValue receiver, HandleId id, SetterOp op, unsigned attrs,
|
||||
HandleValue v, ObjectOpResult &result)
|
||||
{
|
||||
if (attrs & JSPROP_SETTER) {
|
||||
RootedValue fval(cx, CastAsObjectJsval(op));
|
||||
if (!InvokeSetter(cx, receiver, fval, v))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
RootedValue valCopy(cx, v);
|
||||
return CallJSSetterOp(cx, op, receiverObj, id, &valCopy, result);
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptedIndirectProxyHandler::derivedSet(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
HandleValue v, HandleValue receiver,
|
||||
ScriptedIndirectProxyHandler::derivedSet(JSContext *cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
// Find an own or inherited property. The code here is strange for maximum
|
||||
|
|
@ -383,7 +357,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(), v, result))
|
||||
if (!CallSetter(cx, receiver, id, desc.setter(), desc.attributes(), vp, result))
|
||||
return false;
|
||||
if (!result)
|
||||
return true;
|
||||
|
|
@ -394,21 +368,22 @@ ScriptedIndirectProxyHandler::derivedSet(JSContext *cx, HandleObject proxy, Hand
|
|||
return result.succeed();
|
||||
}
|
||||
}
|
||||
desc.value().set(v);
|
||||
desc.value().set(vp.get());
|
||||
|
||||
if (descIsOwn) {
|
||||
MOZ_ASSERT(desc.object() == proxy);
|
||||
return this->defineProperty(cx, proxy, id, desc, result);
|
||||
return this->defineProperty(cx, proxy, id, &desc, result);
|
||||
}
|
||||
} else {
|
||||
desc.setDataDescriptor(v, JSPROP_ENUMERATE);
|
||||
return DefineProperty(cx, receiver, id, desc.value(), desc.getter(), desc.setter(),
|
||||
desc.attributes(), 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);
|
||||
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);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
|
|||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const override;
|
||||
|
|
@ -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, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const override;
|
||||
virtual bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, 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, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const;
|
||||
bool derivedSet(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result) const;
|
||||
};
|
||||
|
||||
/* Derived class to handle Proxy.createFunction() */
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ SecurityWrapper<Base>::boxedValue_unbox(JSContext *cx, HandleObject obj, Mutable
|
|||
|
||||
template <class Base>
|
||||
bool
|
||||
SecurityWrapper<Base>::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
SecurityWrapper<Base>::defineProperty(JSContext *cx, HandleObject wrapper,
|
||||
HandleId id, MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
if (desc.getter() || desc.setter()) {
|
||||
|
|
|
|||
|
|
@ -7637,7 +7637,7 @@ DebuggerEnv_setVariable(JSContext *cx, unsigned argc, Value *vp)
|
|||
}
|
||||
|
||||
/* Just set the property. */
|
||||
if (!SetProperty(cx, env, id, v))
|
||||
if (!SetProperty(cx, env, env, id, &v))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -612,7 +612,11 @@ class GlobalObject : public NativeObject
|
|||
MOZ_ASSERT(cx->runtime()->isSelfHostingGlobal(self));
|
||||
#endif
|
||||
RootedObject holder(cx, intrinsicsHolder());
|
||||
return SetProperty(cx, holder, name, value);
|
||||
RootedValue valCopy(cx, value);
|
||||
ObjectOpResult result;
|
||||
bool ok = SetProperty(cx, holder, holder, name, &valCopy, result);
|
||||
MOZ_ASSERT_IF(ok, result);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool getSelfHostedFunction(JSContext *cx, HandleAtom selfHostedName, HandleAtom name,
|
||||
|
|
|
|||
|
|
@ -308,6 +308,7 @@ 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
|
||||
|
|
@ -315,13 +316,12 @@ 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>(), id, val, receiver, Unqualified,
|
||||
result);
|
||||
ok = NativeSetProperty(cx, scope.as<NativeObject>(), scope.as<NativeObject>(), id,
|
||||
Unqualified, &valCopy, result);
|
||||
} else {
|
||||
ok = SetProperty(cx, scope, id, val, receiver, result);
|
||||
ok = SetProperty(cx, scope, scope, id, &valCopy, result);
|
||||
}
|
||||
return ok && result.checkStrictErrorOrWarning(cx, scope, id, strict);
|
||||
}
|
||||
|
|
@ -336,7 +336,8 @@ InitPropertyOperation(JSContext *cx, JSOp op, HandleObject obj, HandleId id, Han
|
|||
}
|
||||
|
||||
MOZ_ASSERT(obj->as<UnboxedPlainObject>().layout().lookup(id));
|
||||
return PutProperty(cx, obj, id, rhs, false);
|
||||
RootedValue v(cx, rhs);
|
||||
return PutProperty(cx, obj, id, &v, false);
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
|
|
|||
|
|
@ -313,20 +313,52 @@ GetNameOperation(JSContext *cx, InterpreterFrame *fp, jsbytecode *pc, MutableHan
|
|||
}
|
||||
|
||||
static bool
|
||||
SetPropertyOperation(JSContext *cx, JSOp op, HandleValue lval, HandleId id, HandleValue rval)
|
||||
SetObjectProperty(JSContext *cx, JSOp op, HandleValue lval, HandleId id, MutableHandleValue rref)
|
||||
{
|
||||
MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP);
|
||||
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());
|
||||
|
||||
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));
|
||||
ObjectOpResult result;
|
||||
return SetProperty(cx, obj, id, rval, receiver, result) &&
|
||||
result.checkStrictErrorOrWarning(cx, obj, id, op == JSOP_STRICTSETPROP);
|
||||
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);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -584,7 +616,8 @@ js::InvokeConstructor(JSContext *cx, Value fval, unsigned argc, const Value *arg
|
|||
}
|
||||
|
||||
bool
|
||||
js::InvokeGetter(JSContext *cx, JSObject *obj, Value fval, MutableHandleValue rval)
|
||||
js::InvokeGetterOrSetter(JSContext *cx, JSObject *obj, Value fval, unsigned argc,
|
||||
Value *argv, MutableHandleValue rval)
|
||||
{
|
||||
/*
|
||||
* Invoke could result in another try to get or set the same id again, see
|
||||
|
|
@ -592,16 +625,7 @@ js::InvokeGetter(JSContext *cx, JSObject *obj, Value fval, MutableHandleValue rv
|
|||
*/
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
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);
|
||||
return Invoke(cx, ObjectValue(*obj), fval, argc, argv, rval);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -1379,7 +1403,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
|
||||
|
|
@ -3861,8 +3885,7 @@ js::DefFunOperation(JSContext *cx, HandleScript script, HandleObject scopeChain,
|
|||
*/
|
||||
|
||||
/* Step 5f. */
|
||||
RootedId id(cx, NameToId(name));
|
||||
return PutProperty(cx, parent, id, rval, script->strict());
|
||||
return PutProperty(cx, parent, name, &rval, script->strict());
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -76,14 +76,12 @@ Invoke(JSContext *cx, const Value &thisv, const Value &fval, unsigned argc, cons
|
|||
MutableHandleValue rval);
|
||||
|
||||
/*
|
||||
* These helpers take care of the infinite-recursion check necessary for
|
||||
* This helper takes care of the infinite-recursion check necessary for
|
||||
* getter/setter calls.
|
||||
*/
|
||||
extern bool
|
||||
InvokeGetter(JSContext *cx, JSObject *obj, Value fval, MutableHandleValue rval);
|
||||
|
||||
extern bool
|
||||
InvokeSetter(JSContext *cx, const Value &thisv, Value fval, HandleValue v);
|
||||
InvokeGetterOrSetter(JSContext *cx, JSObject *obj, Value fval, unsigned argc, Value *argv,
|
||||
MutableHandleValue rval);
|
||||
|
||||
/*
|
||||
* InvokeConstructor implement a function call from a constructor context
|
||||
|
|
|
|||
|
|
@ -73,7 +73,8 @@ 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,7 +85,8 @@ NativeObject::setDenseElementWithType(ExclusiveContext *cx, uint32_t index, cons
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -981,59 +981,6 @@ NativeObject::addDataProperty(ExclusiveContext *cx, HandlePropertyName name,
|
|||
return addProperty(cx, self, id, nullptr, nullptr, slot, attrs, 0);
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
bool
|
||||
js::NativeLookupOwnProperty(ExclusiveContext *cx,
|
||||
typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
|
||||
typename MaybeRooted<jsid, allowGC>::HandleType id,
|
||||
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp)
|
||||
{
|
||||
bool done;
|
||||
return LookupOwnPropertyInline<allowGC>(cx, obj, id, propp, &done);
|
||||
}
|
||||
|
||||
template bool
|
||||
js::NativeLookupOwnProperty<CanGC>(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
MutableHandleShape propp);
|
||||
|
||||
template bool
|
||||
js::NativeLookupOwnProperty<NoGC>(ExclusiveContext *cx, NativeObject *obj, jsid id,
|
||||
FakeMutableHandle<Shape*> propp);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
bool
|
||||
js::NativeLookupProperty(ExclusiveContext *cx,
|
||||
typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
|
||||
typename MaybeRooted<jsid, allowGC>::HandleType id,
|
||||
typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
|
||||
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp)
|
||||
{
|
||||
return LookupPropertyInline<allowGC>(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
template bool
|
||||
js::NativeLookupProperty<CanGC>(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
MutableHandleObject objp, MutableHandleShape propp);
|
||||
|
||||
template bool
|
||||
js::NativeLookupProperty<NoGC>(ExclusiveContext *cx, NativeObject *obj, jsid id,
|
||||
FakeMutableHandle<JSObject*> objp,
|
||||
FakeMutableHandle<Shape*> propp);
|
||||
|
||||
bool
|
||||
js::NativeLookupElement(JSContext *cx, HandleNativeObject obj, uint32_t index,
|
||||
MutableHandleObject objp, MutableHandleShape propp)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
|
||||
return LookupPropertyInline<CanGC>(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
|
||||
/*** [[DefineOwnProperty]] ***********************************************************************/
|
||||
|
||||
/*
|
||||
* Backward compatibility requires allowing addProperty hooks to mutate the
|
||||
* nominal initial value of a slotful property, while GC safety wants that
|
||||
|
|
@ -1130,8 +1077,8 @@ UpdateShapeTypeAndValue(ExclusiveContext *cx, NativeObject *obj, Shape *shape, c
|
|||
}
|
||||
|
||||
static bool
|
||||
NativeSetExistingDataProperty(JSContext *cx, HandleNativeObject obj, HandleShape shape,
|
||||
HandleValue v, HandleValue receiver, ObjectOpResult &result);
|
||||
NativeSet(JSContext *cx, HandleNativeObject obj, HandleObject receiver,
|
||||
HandleShape shape, MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
static inline bool
|
||||
DefinePropertyOrElement(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
|
|
@ -1220,13 +1167,10 @@ DefinePropertyOrElement(ExclusiveContext *cx, HandleNativeObject obj, HandleId i
|
|||
return false;
|
||||
|
||||
if (callSetterAfterwards && setter) {
|
||||
MOZ_ASSERT(!(attrs & JSPROP_GETTER));
|
||||
MOZ_ASSERT(!(attrs & JSPROP_SETTER));
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
RootedValue receiver(cx, ObjectValue(*obj));
|
||||
return NativeSetExistingDataProperty(cx->asJSContext(), obj, shape, value, receiver,
|
||||
result);
|
||||
RootedValue nvalue(cx, value);
|
||||
return NativeSet(cx->asJSContext(), obj, obj, shape, &nvalue, result);
|
||||
}
|
||||
|
||||
return result.succeed();
|
||||
|
|
@ -1341,19 +1285,18 @@ CheckAccessorRedefinition(ExclusiveContext *cx, HandleObject obj, HandleShape sh
|
|||
}
|
||||
|
||||
bool
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, HandleValue value,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
GetterOp getter = desc.getter();
|
||||
SetterOp setter = desc.setter();
|
||||
unsigned attrs = desc.attributes();
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
MOZ_ASSERT(!(attrs & JSPROP_PROPOP_ACCESSORS));
|
||||
|
||||
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
|
||||
|
||||
RootedShape shape(cx);
|
||||
RootedValue updateValue(cx, desc.value());
|
||||
RootedValue updateValue(cx, value);
|
||||
bool shouldDefine = true;
|
||||
|
||||
/*
|
||||
|
|
@ -1361,7 +1304,7 @@ js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId
|
|||
* update the attributes and property ops. A getter or setter is really
|
||||
* only half of a property.
|
||||
*/
|
||||
if (desc.isAccessorDescriptor()) {
|
||||
if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
|
||||
if (!NativeLookupOwnProperty<CanGC>(cx, obj, id, &shape))
|
||||
return false;
|
||||
if (shape) {
|
||||
|
|
@ -1395,7 +1338,7 @@ js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId
|
|||
shouldDefine = false;
|
||||
}
|
||||
}
|
||||
} else if (desc.hasValue()) {
|
||||
} else if (!(attrs & JSPROP_IGNORE_VALUE)) {
|
||||
// If we did a normal lookup here, it would cause resolve hook recursion in
|
||||
// the following case. Suppose the first script we run in a lazy global is
|
||||
// |parseInt()|.
|
||||
|
|
@ -1500,20 +1443,60 @@ js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId
|
|||
return result.succeed();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
bool
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
HandleValue value, GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
js::NativeLookupOwnProperty(ExclusiveContext *cx,
|
||||
typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
|
||||
typename MaybeRooted<jsid, allowGC>::HandleType id,
|
||||
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp)
|
||||
{
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
desc.initFields(obj, value, attrs, getter, setter);
|
||||
return NativeDefineProperty(cx, obj, id, desc, result);
|
||||
bool done;
|
||||
return LookupOwnPropertyInline<allowGC>(cx, obj, id, propp, &done);
|
||||
}
|
||||
|
||||
template bool
|
||||
js::NativeLookupOwnProperty<CanGC>(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
MutableHandleShape propp);
|
||||
|
||||
template bool
|
||||
js::NativeLookupOwnProperty<NoGC>(ExclusiveContext *cx, NativeObject *obj, jsid id,
|
||||
FakeMutableHandle<Shape*> propp);
|
||||
|
||||
template <AllowGC allowGC>
|
||||
bool
|
||||
js::NativeLookupProperty(ExclusiveContext *cx,
|
||||
typename MaybeRooted<NativeObject*, allowGC>::HandleType obj,
|
||||
typename MaybeRooted<jsid, allowGC>::HandleType id,
|
||||
typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
|
||||
typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp)
|
||||
{
|
||||
return LookupPropertyInline<allowGC>(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
template bool
|
||||
js::NativeLookupProperty<CanGC>(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
MutableHandleObject objp, MutableHandleShape propp);
|
||||
|
||||
template bool
|
||||
js::NativeLookupProperty<NoGC>(ExclusiveContext *cx, NativeObject *obj, jsid id,
|
||||
FakeMutableHandle<JSObject*> objp,
|
||||
FakeMutableHandle<Shape*> propp);
|
||||
|
||||
bool
|
||||
js::NativeLookupElement(JSContext *cx, HandleNativeObject obj, uint32_t index,
|
||||
MutableHandleObject objp, MutableHandleShape propp)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
|
||||
return LookupPropertyInline<CanGC>(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyName *name,
|
||||
HandleValue value, GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
HandleValue value, GetterOp getter, SetterOp setter,
|
||||
unsigned attrs, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs, result);
|
||||
|
|
@ -1521,8 +1504,8 @@ js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyN
|
|||
|
||||
bool
|
||||
js::NativeDefineElement(ExclusiveContext *cx, HandleNativeObject obj, uint32_t index,
|
||||
HandleValue value, GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
HandleValue value, GetterOp getter, SetterOp setter,
|
||||
unsigned attrs, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (index <= JSID_INT_MAX) {
|
||||
|
|
@ -1567,7 +1550,6 @@ js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyN
|
|||
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
|
||||
/*** [[HasProperty]] *****************************************************************************/
|
||||
|
||||
// ES6 draft rev31 9.1.7.1 OrdinaryHasProperty
|
||||
|
|
@ -1620,7 +1602,6 @@ js::NativeHasProperty(JSContext *cx, HandleNativeObject obj, HandleId id, bool *
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*** [[Get]] *************************************************************************************/
|
||||
|
||||
static inline bool
|
||||
|
|
@ -1630,7 +1611,7 @@ CallGetter(JSContext* cx, HandleObject receiver, HandleShape shape, MutableHandl
|
|||
|
||||
if (shape->hasGetterValue()) {
|
||||
Value fval = shape->getterValue();
|
||||
return InvokeGetter(cx, receiver, fval, vp);
|
||||
return InvokeGetterOrSetter(cx, receiver, fval, 0, 0, vp);
|
||||
}
|
||||
|
||||
RootedId id(cx, shape->propid());
|
||||
|
|
@ -1946,7 +1927,6 @@ js::GetPropertyForNameLookup(JSContext *cx, HandleObject obj, HandleId id, Mutab
|
|||
return NativeGetPropertyInline<CanGC>(cx, obj.as<NativeObject>(), obj, id, NameLookup, vp);
|
||||
}
|
||||
|
||||
|
||||
/*** [[Set]] *************************************************************************************/
|
||||
|
||||
static bool
|
||||
|
|
@ -1978,18 +1958,13 @@ 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.b-f, but it
|
||||
* This implements ES6 draft rev 28, 9.1.9 [[Set]] steps 5.c-f, but it
|
||||
* is really old code and there are a few barnacles.
|
||||
*/
|
||||
bool
|
||||
js::SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiverValue, bool objHasOwn, ObjectOpResult &result)
|
||||
js::SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, HandleValue v, 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
|
||||
|
|
@ -2042,8 +2017,6 @@ js::SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleId id, HandleVa
|
|||
if (!receiver->is<NativeObject>())
|
||||
return DefineProperty(cx, receiver, id, v, getter, setter, attrs, result);
|
||||
|
||||
// If the receiver is native, there is one more legacy wrinkle: the class
|
||||
// JSSetterOp is called after defining the new property.
|
||||
Rooted<NativeObject*> nativeReceiver(cx, &receiver->as<NativeObject>());
|
||||
return DefinePropertyOrElement(cx, nativeReceiver, id, getter, setter, attrs, v, true, result);
|
||||
}
|
||||
|
|
@ -2051,15 +2024,15 @@ js::SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleId id, HandleVa
|
|||
// 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, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result)
|
||||
js::SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(!obj->is<ProxyObject>());
|
||||
|
||||
RootedObject proto(cx, obj->getProto());
|
||||
if (proto)
|
||||
return SetProperty(cx, proto, id, v, receiver, result);
|
||||
return SetPropertyByDefining(cx, obj, id, v, receiver, false, result);
|
||||
return SetProperty(cx, proto, receiver, id, vp, result);
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2068,20 +2041,22 @@ js::SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleId id, HandleValue
|
|||
*
|
||||
* 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, HandleId id, HandleValue v,
|
||||
HandleValue receiver, QualifiedBool qualified, ObjectOpResult &result)
|
||||
SetNonexistentProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
|
||||
QualifiedBool qualified, HandleValue v, ObjectOpResult &result)
|
||||
{
|
||||
// We should never add properties to lexical blocks.
|
||||
MOZ_ASSERT_IF(receiver.isObject(), !receiver.toObject().is<BlockObject>());
|
||||
MOZ_ASSERT(!receiver->is<BlockObject>());
|
||||
|
||||
if (!qualified && receiver.isObject() && receiver.toObject().isUnqualifiedVarObj()) {
|
||||
if (receiver->isUnqualifiedVarObj() && !qualified) {
|
||||
if (!MaybeReportUndeclaredVarAssignment(cx, JSID_TO_STRING(id)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return SetPropertyByDefining(cx, obj, id, v, receiver, false, result);
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, v, false, result);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2089,12 +2064,12 @@ SetNonexistentProperty(JSContext *cx, HandleNativeObject obj, HandleId id, Handl
|
|||
* array element.
|
||||
*/
|
||||
static bool
|
||||
SetDenseOrTypedArrayElement(JSContext *cx, HandleNativeObject obj, uint32_t index, HandleValue v,
|
||||
ObjectOpResult &result)
|
||||
SetDenseOrTypedArrayElement(JSContext *cx, HandleNativeObject obj, uint32_t index,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
if (IsAnyTypedArray(obj)) {
|
||||
double d;
|
||||
if (!ToNumber(cx, v, &d))
|
||||
if (!ToNumber(cx, vp, &d))
|
||||
return false;
|
||||
|
||||
// Silently do nothing for out-of-bounds sets, for consistency with
|
||||
|
|
@ -2116,152 +2091,128 @@ SetDenseOrTypedArrayElement(JSContext *cx, HandleNativeObject obj, uint32_t inde
|
|||
if (!obj->maybeCopyElementsForWrite(cx))
|
||||
return false;
|
||||
|
||||
obj->setDenseElementWithType(cx, index, v);
|
||||
obj->setDenseElementWithType(cx, index, vp);
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
/*
|
||||
* Finish assignment to a shapeful data property of a native object obj. This
|
||||
* Finish assignment to a shapeful property of a native object obj. This
|
||||
* conforms to no standard and there is a lot of legacy baggage here.
|
||||
*/
|
||||
static bool
|
||||
NativeSetExistingDataProperty(JSContext *cx, HandleNativeObject obj, HandleShape shape,
|
||||
HandleValue v, HandleValue receiver, ObjectOpResult &result)
|
||||
NativeSet(JSContext *cx, HandleNativeObject obj, HandleObject receiver,
|
||||
HandleShape shape, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(obj->isNative());
|
||||
MOZ_ASSERT(shape->isDataDescriptor());
|
||||
|
||||
if (shape->hasDefaultSetter()) {
|
||||
if (shape->hasSlot()) {
|
||||
// The common path. Standard data property.
|
||||
|
||||
/* If shape has a stub setter, just store vp. */
|
||||
if (shape->hasDefaultSetter()) {
|
||||
// Global properties declared with 'var' will be initially
|
||||
// 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, v, overwriting);
|
||||
obj->setSlotWithType(cx, shape, vp, overwriting);
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
|
||||
// Bizarre: shared (slotless) property that's writable but has no
|
||||
// JSSetterOp. JS code can't define such a property, but it can be done
|
||||
// through the JSAPI. Treat it as non-writable.
|
||||
if (!shape->hasSlot()) {
|
||||
/*
|
||||
* Allow API consumers to create shared properties with stub setters.
|
||||
* Such properties effectively function as data descriptors which are
|
||||
* not writable, so attempting to set such a property should do nothing
|
||||
* or throw if we're in strict mode.
|
||||
*/
|
||||
if (!shape->hasGetterValue() && shape->hasDefaultSetter())
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!obj->is<DynamicWithObject>()); // See bug 1128681.
|
||||
RootedValue ovp(cx, vp);
|
||||
|
||||
uint32_t sample = cx->runtime()->propertyRemovals;
|
||||
RootedId id(cx, shape->propid());
|
||||
RootedValue value(cx, v);
|
||||
if (!CallJSSetterOp(cx, shape->setterOp(), obj, id, &value, result))
|
||||
if (!shape->set(cx, obj, receiver, vp, result))
|
||||
return false;
|
||||
|
||||
// Update any slot for the shape with the value produced by the setter,
|
||||
// unless the setter deleted the shape.
|
||||
/*
|
||||
* Update any slot for the shape with the value produced by the setter,
|
||||
* unless the setter deleted the shape.
|
||||
*/
|
||||
if (shape->hasSlot() &&
|
||||
(MOZ_LIKELY(cx->runtime()->propertyRemovals == sample) ||
|
||||
obj->contains(cx, shape)))
|
||||
{
|
||||
obj->setSlot(shape->slot(), value);
|
||||
obj->setSlot(shape->slot(), vp);
|
||||
}
|
||||
|
||||
return true; // result is populated by CallJSSetterOp above.
|
||||
return true; // result is populated by shape->set() above.
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* Implement "the rest of" assignment to receiver[id] when an existing property
|
||||
* (shape) has been found on a native object (pobj).
|
||||
*
|
||||
* It is necessary to pass both id and shape because shape could be an implicit
|
||||
* dense or typed array element (i.e. not actually a pointer to a Shape).
|
||||
*/
|
||||
static bool
|
||||
SetExistingProperty(JSContext *cx, HandleNativeObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, HandleNativeObject pobj, HandleShape shape,
|
||||
SetExistingProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
|
||||
HandleNativeObject pobj, HandleShape shape, MutableHandleValue vp,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
// Step 5 for dense elements.
|
||||
if (IsImplicitDenseOrTypedArrayElement(shape)) {
|
||||
// Step 5.a is a no-op: all dense elements are writable.
|
||||
|
||||
// Pure optimization for the common case:
|
||||
if (receiver.isObject() && pobj == &receiver.toObject())
|
||||
return SetDenseOrTypedArrayElement(cx, pobj, JSID_TO_INT(id), v, result);
|
||||
|
||||
// Steps 5.b-f.
|
||||
return SetPropertyByDefining(cx, obj, id, v, receiver, obj == pobj, result);
|
||||
}
|
||||
|
||||
// Step 5 for all other properties.
|
||||
if (shape->isDataDescriptor()) {
|
||||
// Step 5.a.
|
||||
/* ES5 8.12.4 [[Put]] step 2, for a dense data property on pobj. */
|
||||
if (pobj == receiver)
|
||||
return SetDenseOrTypedArrayElement(cx, pobj, JSID_TO_INT(id), vp, result);
|
||||
} else {
|
||||
/* ES5 8.12.4 [[Put]] step 2. */
|
||||
if (shape->isAccessorDescriptor()) {
|
||||
if (shape->hasDefaultSetter())
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
} else {
|
||||
MOZ_ASSERT(shape->isDataDescriptor());
|
||||
if (!shape->writable())
|
||||
return result.fail(JSMSG_READ_ONLY);
|
||||
}
|
||||
|
||||
// steps 5.c-f.
|
||||
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|.
|
||||
|
||||
// Steps 5.e.i-ii.
|
||||
if (pobj == receiver) {
|
||||
if (pobj->is<ArrayObject>() && id == NameToId(cx->names().length)) {
|
||||
Rooted<ArrayObject*> arr(cx, &pobj->as<ArrayObject>());
|
||||
return ArraySetLength(cx, arr, id, shape->attributes(), v, result);
|
||||
return ArraySetLength(cx, arr, id, shape->attributes(), vp, result);
|
||||
}
|
||||
return NativeSetExistingDataProperty(cx, obj, shape, v, receiver, result);
|
||||
return NativeSet(cx, obj, receiver, shape, vp, result);
|
||||
}
|
||||
|
||||
// SpiderMonkey special case: assigning to an inherited slotless
|
||||
// property causes the setter to be called, instead of shadowing,
|
||||
// unless the existing property is JSPROP_SHADOWABLE (see bug 552432)
|
||||
// or it's the array length property.
|
||||
if (!shape->hasSlot() &&
|
||||
!shape->hasShadowable() &&
|
||||
// pobj[id] is not an own property of receiver. Call the setter or shadow it.
|
||||
if (!shape->shadowable() &&
|
||||
!(pobj->is<ArrayObject>() && id == NameToId(cx->names().length)))
|
||||
{
|
||||
// Even weirder sub-special-case: inherited slotless data property
|
||||
// with default setter. Wut.
|
||||
if (shape->hasDefaultSetter())
|
||||
// Weird special case: slotless property with default setter.
|
||||
if (shape->hasDefaultSetter() && !shape->hasGetterValue())
|
||||
return result.succeed();
|
||||
|
||||
RootedValue valCopy(cx, v);
|
||||
return CallJSSetterOp(cx, shape->setterOp(), obj, id, &valCopy, result);
|
||||
return shape->set(cx, obj, receiver, vp, result);
|
||||
}
|
||||
}
|
||||
|
||||
// Shadow pobj[id] by defining a new data property receiver[id].
|
||||
// Delegate everything to SetPropertyByDefining.
|
||||
return SetPropertyByDefining(cx, obj, id, v, receiver, obj == pobj, result);
|
||||
}
|
||||
|
||||
// Steps 6-11.
|
||||
MOZ_ASSERT(shape->isAccessorDescriptor());
|
||||
MOZ_ASSERT_IF(!shape->hasSetterObject(), shape->hasDefaultSetter());
|
||||
if (shape->hasDefaultSetter())
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
Value setter = ObjectValue(*shape->setterObject());
|
||||
if (!InvokeSetter(cx, receiver, setter, v))
|
||||
return false;
|
||||
return result.succeed();
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, obj == pobj, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleId id, HandleValue value,
|
||||
HandleValue receiver, QualifiedBool qualified, ObjectOpResult &result)
|
||||
js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
|
||||
QualifiedBool qualified, MutableHandleValue vp, 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, &v))
|
||||
if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, vp))
|
||||
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, ownDesc -> shape.
|
||||
// used in the spec: O -> pobj, P -> id, V -> *vp, ownDesc -> shape.
|
||||
RootedShape shape(cx);
|
||||
RootedNativeObject pobj(cx, obj);
|
||||
|
||||
|
|
@ -2276,7 +2227,7 @@ js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleId id, Handle
|
|||
|
||||
if (shape) {
|
||||
// Steps 5-6.
|
||||
return SetExistingProperty(cx, obj, id, v, receiver, pobj, shape, result);
|
||||
return SetExistingProperty(cx, obj, receiver, id, pobj, shape, vp, result);
|
||||
}
|
||||
|
||||
// Steps 4.a-b. The check for 'done' on this next line is tricky.
|
||||
|
|
@ -2290,7 +2241,7 @@ js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleId id, Handle
|
|||
RootedObject proto(cx, done ? nullptr : pobj->getProto());
|
||||
if (!proto) {
|
||||
// Step 4.d.i (and step 5).
|
||||
return SetNonexistentProperty(cx, obj, id, v, receiver, qualified, result);
|
||||
return SetNonexistentProperty(cx, obj, receiver, id, qualified, vp, result);
|
||||
}
|
||||
|
||||
// Step 4.c.i. If the prototype is also native, this step is a
|
||||
|
|
@ -2307,23 +2258,23 @@ js::NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleId id, Handle
|
|||
if (!HasProperty(cx, proto, id, &found))
|
||||
return false;
|
||||
if (!found)
|
||||
return SetNonexistentProperty(cx, obj, id, v, receiver, qualified, result);
|
||||
return SetNonexistentProperty(cx, obj, receiver, id, qualified, vp, result);
|
||||
}
|
||||
|
||||
return SetProperty(cx, proto, id, v, receiver, result);
|
||||
return SetProperty(cx, proto, receiver, id, vp, result);
|
||||
}
|
||||
pobj = &proto->as<NativeObject>();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeSetElement(JSContext *cx, HandleNativeObject obj, uint32_t index, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result)
|
||||
js::NativeSetElement(JSContext *cx, HandleNativeObject obj, HandleObject receiver, uint32_t index,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
return NativeSetProperty(cx, obj, id, v, receiver, Qualified, result);
|
||||
return NativeSetProperty(cx, obj, receiver, id, Qualified, vp, result);
|
||||
}
|
||||
|
||||
/*** [[Delete]] **********************************************************************************/
|
||||
|
|
|
|||
|
|
@ -1255,11 +1255,6 @@ IsObjectValueInCompartment(Value v, JSCompartment *comp)
|
|||
* (9.4.2), Strings (9.4.3), and so on.
|
||||
*/
|
||||
|
||||
extern bool
|
||||
NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
|
|
@ -1312,12 +1307,12 @@ NativeGetElement(JSContext *cx, HandleNativeObject obj, uint32_t index, MutableH
|
|||
}
|
||||
|
||||
bool
|
||||
SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, bool objHasOwn, ObjectOpResult &result);
|
||||
SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
HandleValue v, bool objHasOwn, ObjectOpResult &result);
|
||||
|
||||
bool
|
||||
SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result);
|
||||
SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
/*
|
||||
* Indicates whether an assignment operation is qualified (`x.y = 0`) or
|
||||
|
|
@ -1332,12 +1327,12 @@ enum QualifiedBool {
|
|||
};
|
||||
|
||||
extern bool
|
||||
NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, QualifiedBool qualified, ObjectOpResult &result);
|
||||
NativeSetProperty(JSContext *cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
|
||||
QualifiedBool qualified, MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
NativeSetElement(JSContext *cx, HandleNativeObject obj, uint32_t index, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result);
|
||||
NativeSetElement(JSContext *cx, HandleNativeObject obj, HandleObject receiver, uint32_t index,
|
||||
MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
NativeDeleteProperty(JSContext *cx, HandleNativeObject obj, HandleId id, ObjectOpResult &result);
|
||||
|
|
@ -1448,21 +1443,21 @@ js::GetPropertyNoGC(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, V
|
|||
}
|
||||
|
||||
inline bool
|
||||
js::SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result)
|
||||
js::SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
if (obj->getOps()->setProperty)
|
||||
return JSObject::nonNativeSetProperty(cx, obj, id, v, receiver, result);
|
||||
return NativeSetProperty(cx, obj.as<NativeObject>(), id, v, receiver, Qualified, result);
|
||||
return JSObject::nonNativeSetProperty(cx, obj, receiver, id, vp, result);
|
||||
return NativeSetProperty(cx, obj.as<NativeObject>(), receiver, id, Qualified, vp, result);
|
||||
}
|
||||
|
||||
inline bool
|
||||
js::SetElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result)
|
||||
js::SetElement(JSContext *cx, HandleObject obj, HandleObject receiver, uint32_t index,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
if (obj->getOps()->setProperty)
|
||||
return JSObject::nonNativeSetElement(cx, obj, index, v, receiver, result);
|
||||
return NativeSetElement(cx, obj.as<NativeObject>(), index, v, receiver, result);
|
||||
return JSObject::nonNativeSetElement(cx, obj, receiver, index, vp, result);
|
||||
return NativeSetElement(cx, obj.as<NativeObject>(), receiver, index, vp, result);
|
||||
}
|
||||
|
||||
#endif /* vm_NativeObject_h */
|
||||
|
|
|
|||
|
|
@ -298,7 +298,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, id, optimizedOut))
|
||||
if (!SetProperty(cx, callobj, callobj, id, &optimizedOut))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
@ -469,11 +469,12 @@ with_LookupProperty(JSContext *cx, HandleObject obj, HandleId id,
|
|||
}
|
||||
|
||||
static bool
|
||||
with_DefineProperty(JSContext *cx, HandleObject obj, HandleId id, Handle<PropertyDescriptor> desc,
|
||||
with_DefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return DefineProperty(cx, actual, id, desc, result);
|
||||
return DefineProperty(cx, actual, id, value, getter, setter, attrs, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -492,14 +493,14 @@ with_GetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleI
|
|||
}
|
||||
|
||||
static bool
|
||||
with_SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result)
|
||||
with_SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
RootedValue actualReceiver(cx, receiver);
|
||||
if (receiver.isObject() && &receiver.toObject() == obj)
|
||||
actualReceiver.setObject(*actual);
|
||||
return SetProperty(cx, actual, id, v, actualReceiver, result);
|
||||
RootedObject actualReceiver(cx, receiver);
|
||||
if (receiver == obj)
|
||||
actualReceiver = actual;
|
||||
return SetProperty(cx, actual, actualReceiver, id, vp, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -930,8 +931,8 @@ uninitialized_GetProperty(JSContext *cx, HandleObject obj, HandleObject receiver
|
|||
}
|
||||
|
||||
static bool
|
||||
uninitialized_SetProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result)
|
||||
uninitialized_SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
ReportUninitializedLexicalId(cx, id);
|
||||
return false;
|
||||
|
|
@ -1593,8 +1594,8 @@ class DebugScopeProxy : public BaseProxyHandler
|
|||
}
|
||||
}
|
||||
|
||||
bool set(JSContext *cx, HandleObject proxy, HandleId id, HandleValue v, HandleValue receiver,
|
||||
ObjectOpResult &result) const override
|
||||
bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result) const override
|
||||
{
|
||||
Rooted<DebugScopeObject*> debugScope(cx, &proxy->as<DebugScopeObject>());
|
||||
Rooted<ScopeObject*> scope(cx, &proxy->as<DebugScopeObject>().scope());
|
||||
|
|
@ -1603,25 +1604,21 @@ class DebugScopeProxy : public BaseProxyHandler
|
|||
return Throw(cx, id, JSMSG_DEBUG_CANT_SET_OPT_ENV);
|
||||
|
||||
AccessResult access;
|
||||
RootedValue valCopy(cx, v);
|
||||
if (!handleUnaliasedAccess(cx, debugScope, scope, id, SET, &valCopy, &access))
|
||||
if (!handleUnaliasedAccess(cx, debugScope, scope, id, SET, vp, &access))
|
||||
return false;
|
||||
|
||||
switch (access) {
|
||||
case ACCESS_UNALIASED:
|
||||
return result.succeed();
|
||||
case ACCESS_GENERIC:
|
||||
{
|
||||
RootedValue scopeVal(cx, ObjectValue(*scope));
|
||||
return SetProperty(cx, scope, id, v, scopeVal, result);
|
||||
}
|
||||
return SetProperty(cx, scope, scope, id, vp, result);
|
||||
default:
|
||||
MOZ_CRASH("bad AccessResult");
|
||||
}
|
||||
}
|
||||
|
||||
bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
Handle<PropertyDescriptor> desc,
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const override
|
||||
{
|
||||
Rooted<ScopeObject*> scope(cx, &proxy->as<DebugScopeObject>().scope());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
RootedValue receiver(cx, ObjectValue(*arrobj));
|
||||
if (!SetElement(cx, arrobj, idx, args[elemi], receiver, ignored))
|
||||
if (!SetElement(cx, arrobj, arrobj, idx, &tmp, ignored))
|
||||
return false;
|
||||
} else {
|
||||
MOZ_ASSERT(idx < arrobj->as<ArrayObject>().getDenseInitializedLength());
|
||||
|
|
|
|||
|
|
@ -39,6 +39,30 @@ Shape::search(ExclusiveContext *cx, jsid id)
|
|||
return search(cx, this, id, &_);
|
||||
}
|
||||
|
||||
inline bool
|
||||
Shape::set(JSContext* cx, HandleNativeObject obj, HandleObject receiver, MutableHandleValue vp,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT_IF(hasDefaultSetter(), hasGetterValue());
|
||||
MOZ_ASSERT(!obj->is<DynamicWithObject>()); // See bug 1128681.
|
||||
|
||||
if (attrs & JSPROP_SETTER) {
|
||||
Value fval = setterValue();
|
||||
if (!InvokeGetterOrSetter(cx, receiver, fval, 1, vp.address(), vp))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
if (attrs & JSPROP_GETTER)
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
|
||||
if (!setterOp())
|
||||
return result.succeed();
|
||||
|
||||
RootedId id(cx, propid());
|
||||
return CallJSSetterOp(cx, setterOp(), obj, id, vp, result);
|
||||
}
|
||||
|
||||
/* static */ inline Shape *
|
||||
Shape::search(ExclusiveContext *cx, Shape *start, jsid id, ShapeTable::Entry **pentry, bool adding)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1019,7 +1019,16 @@ class Shape : public gc::TenuredCell
|
|||
return (attrs & (JSPROP_SETTER | JSPROP_GETTER)) != 0;
|
||||
}
|
||||
|
||||
bool hasShadowable() const { return attrs & JSPROP_SHADOWABLE; }
|
||||
/*
|
||||
* For ES5 compatibility, we allow properties with SetterOp-flavored
|
||||
* setters to be shadowed when set. The "own" property thereby created in
|
||||
* the directly referenced object will have the same getter and setter as
|
||||
* the prototype property. See bug 552432.
|
||||
*/
|
||||
bool shadowable() const {
|
||||
MOZ_ASSERT_IF(isDataDescriptor(), writable());
|
||||
return hasSlot() || (attrs & JSPROP_SHADOWABLE);
|
||||
}
|
||||
|
||||
uint32_t entryCount() {
|
||||
if (hasTable())
|
||||
|
|
|
|||
|
|
@ -679,16 +679,16 @@ UnboxedPlainObject::obj_lookupProperty(JSContext *cx, HandleObject obj,
|
|||
}
|
||||
|
||||
/* static */ bool
|
||||
UnboxedPlainObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
UnboxedPlainObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
const UnboxedLayout &layout = obj->as<UnboxedPlainObject>().layout();
|
||||
|
||||
if (const UnboxedLayout::Property *property = layout.lookup(id)) {
|
||||
if (!desc.getter() && !desc.setter() && desc.attributes() == JSPROP_ENUMERATE) {
|
||||
if (!getter && !setter && attrs == JSPROP_ENUMERATE) {
|
||||
// This define is equivalent to setting an existing property.
|
||||
if (obj->as<UnboxedPlainObject>().setValue(cx, *property, desc.value()))
|
||||
if (obj->as<UnboxedPlainObject>().setValue(cx, *property, v))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -697,8 +697,7 @@ UnboxedPlainObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId
|
|||
if (!convertToNative(cx, obj))
|
||||
return false;
|
||||
|
||||
return DefineProperty(cx, obj, id, desc, result) &&
|
||||
result.checkStrict(cx, obj, id);
|
||||
return DefineProperty(cx, obj, id, v, getter, setter, attrs);
|
||||
}
|
||||
|
||||
// Define the property on the expando object.
|
||||
|
|
@ -707,9 +706,9 @@ UnboxedPlainObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId
|
|||
return false;
|
||||
|
||||
// Update property types on the unboxed object as well.
|
||||
AddTypePropertyId(cx, obj, id, desc.value());
|
||||
AddTypePropertyId(cx, obj, id, v);
|
||||
|
||||
return DefineProperty(cx, expando, id, desc, result);
|
||||
return DefineProperty(cx, expando, id, v, getter, setter, attrs, result);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
|
|
@ -758,38 +757,36 @@ UnboxedPlainObject::obj_getProperty(JSContext *cx, HandleObject obj, HandleObjec
|
|||
}
|
||||
|
||||
/* static */ bool
|
||||
UnboxedPlainObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result)
|
||||
UnboxedPlainObject::obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
const UnboxedLayout &layout = obj->as<UnboxedPlainObject>().layout();
|
||||
|
||||
if (const UnboxedLayout::Property *property = layout.lookup(id)) {
|
||||
if (receiver.isObject() && obj == &receiver.toObject()) {
|
||||
if (obj->as<UnboxedPlainObject>().setValue(cx, *property, v))
|
||||
if (obj == receiver) {
|
||||
if (obj->as<UnboxedPlainObject>().setValue(cx, *property, vp))
|
||||
return result.succeed();
|
||||
|
||||
if (!convertToNative(cx, obj))
|
||||
return false;
|
||||
return SetProperty(cx, obj, id, v, receiver, result);
|
||||
return SetProperty(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
return SetPropertyByDefining(cx, obj, id, v, receiver, false, result);
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, 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, v);
|
||||
AddTypePropertyId(cx, obj, id, vp);
|
||||
|
||||
RootedObject nexpando(cx, expando);
|
||||
RootedValue nreceiver(cx, (receiver.isObject() && obj == &receiver.toObject())
|
||||
? ObjectValue(*expando)
|
||||
: receiver);
|
||||
return SetProperty(cx, nexpando, id, v, nreceiver, result);
|
||||
RootedObject nreceiver(cx, (obj == receiver) ? expando : receiver.get());
|
||||
return SetProperty(cx, nexpando, nreceiver, id, vp, result);
|
||||
}
|
||||
}
|
||||
|
||||
return SetPropertyOnProto(cx, obj, id, v, receiver, result);
|
||||
return SetPropertyOnProto(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
|
|
|
|||
|
|
@ -192,8 +192,8 @@ class UnboxedPlainObject : public JSObject
|
|||
HandleId id, MutableHandleObject objp,
|
||||
MutableHandleShape propp);
|
||||
|
||||
static bool obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
static bool obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result);
|
||||
|
||||
static bool obj_hasProperty(JSContext *cx, HandleObject obj, HandleId id, bool *foundp);
|
||||
|
|
@ -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, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result);
|
||||
static bool obj_setProperty(JSContext *cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
static bool obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 265;
|
|||
static const uint32_t XDR_BYTECODE_VERSION =
|
||||
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
|
||||
|
||||
static_assert(JSErr_Limit == 389,
|
||||
static_assert(JSErr_Limit == 388,
|
||||
"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::Handle<Value> v,
|
||||
JS::Handle<Value> receiver,
|
||||
JS::MutableHandle<Value> vp,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
return BaseProxyHandler::set(cx, proxy, id, v, receiver, result);
|
||||
return BaseProxyHandler::set(cx, proxy, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -426,6 +426,14 @@ XPC_WN_OnlyIWrite_AddPropertyStub(JSContext *cx, HandleObject obj, HandleId id,
|
|||
return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx);
|
||||
}
|
||||
|
||||
static bool
|
||||
XPC_WN_OnlyIWrite_SetPropertyStub(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
result.succeed();
|
||||
return XPC_WN_OnlyIWrite_AddPropertyStub(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
static bool
|
||||
XPC_WN_CannotModifyPropertyStub(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleValue vp)
|
||||
|
|
@ -644,7 +652,7 @@ const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
|
|||
XPC_WN_OnlyIWrite_AddPropertyStub, // addProperty
|
||||
XPC_WN_CantDeletePropertyStub, // delProperty
|
||||
nullptr, // getProperty
|
||||
nullptr, // setProperty
|
||||
XPC_WN_OnlyIWrite_SetPropertyStub, // setProperty
|
||||
|
||||
XPC_WN_Shared_Enumerate, // enumerate
|
||||
XPC_WN_NoHelper_Resolve, // resolve
|
||||
|
|
@ -1353,6 +1361,14 @@ XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext *cx, HandleObject obj, HandleI
|
|||
return Throw(NS_ERROR_XPC_BAD_OP_ON_WN_PROTO, cx);
|
||||
}
|
||||
|
||||
static bool
|
||||
XPC_WN_OnlyIWrite_Proto_SetPropertyStub(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
result.succeed();
|
||||
return XPC_WN_OnlyIWrite_Proto_AddPropertyStub(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
static bool
|
||||
XPC_WN_NoMods_Proto_Resolve(JSContext *cx, HandleObject obj, HandleId id, bool *resolvedp)
|
||||
{
|
||||
|
|
@ -1388,7 +1404,7 @@ const js::Class XPC_WN_NoMods_WithCall_Proto_JSClass = {
|
|||
XPC_WN_OnlyIWrite_Proto_AddPropertyStub, // addProperty;
|
||||
XPC_WN_CantDeletePropertyStub, // delProperty;
|
||||
nullptr, // getProperty;
|
||||
nullptr, // setProperty;
|
||||
XPC_WN_OnlyIWrite_Proto_SetPropertyStub, // setProperty;
|
||||
XPC_WN_Shared_Proto_Enumerate, // enumerate;
|
||||
XPC_WN_NoMods_Proto_Resolve, // resolve;
|
||||
nullptr, // convert;
|
||||
|
|
@ -1413,7 +1429,7 @@ const js::Class XPC_WN_NoMods_NoCall_Proto_JSClass = {
|
|||
XPC_WN_OnlyIWrite_Proto_AddPropertyStub, // addProperty;
|
||||
XPC_WN_CantDeletePropertyStub, // delProperty;
|
||||
nullptr, // getProperty;
|
||||
nullptr, // setProperty;
|
||||
XPC_WN_OnlyIWrite_Proto_SetPropertyStub, // setProperty;
|
||||
XPC_WN_Shared_Proto_Enumerate, // enumerate;
|
||||
XPC_WN_NoMods_Proto_Resolve, // resolve;
|
||||
nullptr, // convert;
|
||||
|
|
@ -1508,7 +1524,7 @@ const js::Class XPC_WN_Tearoff_JSClass = {
|
|||
XPC_WN_OnlyIWrite_AddPropertyStub, // addProperty;
|
||||
XPC_WN_CantDeletePropertyStub, // delProperty;
|
||||
nullptr, // getProperty;
|
||||
nullptr, // setProperty;
|
||||
XPC_WN_OnlyIWrite_SetPropertyStub, // setProperty;
|
||||
XPC_WN_TearOff_Enumerate, // enumerate;
|
||||
XPC_WN_TearOff_Resolve, // resolve;
|
||||
XPC_WN_Shared_Convert, // convert;
|
||||
|
|
|
|||
|
|
@ -1,175 +0,0 @@
|
|||
// Test that it's not possible to create expando properties on XPCWNs.
|
||||
// See <https://bugzilla.mozilla.org/show_bug.cgi?id=1143810#c5>.
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
function check_throws(f) {
|
||||
try {
|
||||
f();
|
||||
} catch (exc) {
|
||||
return;
|
||||
}
|
||||
throw new TypeError("Expected exception, no exception thrown");
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that XPCWrappedNative objects do not permit expando properties to be created.
|
||||
*
|
||||
* This function is called twice. The first time, realObj is an nsITimer XPCWN
|
||||
* and accessObj === realObj.
|
||||
*
|
||||
* The second time, accessObj is a scripted proxy with realObj as its target.
|
||||
* So the second time we are testing that scripted proxies don't magically
|
||||
* bypass whatever mechanism enforces the expando policy on XPCWNs.
|
||||
*/
|
||||
function test_tamperproof(realObj, accessObj, {method, constant, attribute}) {
|
||||
// Assignment can't create an expando property.
|
||||
check_throws(function () { accessObj.expando = 14; });
|
||||
do_check_false("expando" in realObj);
|
||||
|
||||
// Strict assignment throws.
|
||||
check_throws(function () { "use strict"; accessObj.expando = 14; });
|
||||
do_check_false("expando" in realObj);
|
||||
|
||||
// Assignment to an inherited method name doesn't work either.
|
||||
check_throws(function () { accessObj.hasOwnProperty = () => "lies"; });
|
||||
check_throws(function () { "use strict"; accessObj.hasOwnProperty = () => "lies"; });
|
||||
do_check_false(realObj.hasOwnProperty("hasOwnProperty"));
|
||||
|
||||
// Assignment to a method name doesn't work either.
|
||||
let originalMethod;
|
||||
if (method) {
|
||||
originalMethod = accessObj[method];
|
||||
accessObj[method] = "nope"; // non-writable data property, no exception in non-strict code
|
||||
check_throws(function () { "use strict"; accessObj[method] = "nope"; });
|
||||
do_check_true(realObj[method] === originalMethod);
|
||||
}
|
||||
|
||||
// A constant is the same thing.
|
||||
let originalConstantValue;
|
||||
if (constant) {
|
||||
originalConstantValue = accessObj[constant];
|
||||
accessObj[constant] = "nope";
|
||||
do_check_eq(realObj[constant], originalConstantValue);
|
||||
check_throws(function () { "use strict"; accessObj[constant] = "nope"; });
|
||||
do_check_eq(realObj[constant], originalConstantValue);
|
||||
}
|
||||
|
||||
// Assignment to a readonly accessor property with no setter doesn't work either.
|
||||
let originalAttributeDesc;
|
||||
if (attribute) {
|
||||
originalAttributeDesc = Object.getOwnPropertyDescriptor(realObj, attribute);
|
||||
do_check_true("set" in originalAttributeDesc);
|
||||
do_check_true(originalAttributeDesc.set === undefined);
|
||||
|
||||
accessObj[attribute] = "nope"; // accessor property with no setter: no exception in non-strict code
|
||||
check_throws(function () { "use strict"; accessObj[attribute] = "nope"; });
|
||||
|
||||
let desc = Object.getOwnPropertyDescriptor(realObj, attribute);
|
||||
do_check_true("set" in desc);
|
||||
do_check_eq(originalAttributeDesc.get, desc.get);
|
||||
do_check_eq(undefined, desc.set);
|
||||
}
|
||||
|
||||
// Reflect.set doesn't work either.
|
||||
if (this.Reflect && this.Reflect.set)
|
||||
throw new Error("Congratulations on implementing Reflect.set! Here are some tests to uncomment.");
|
||||
/*
|
||||
if (method) {
|
||||
do_check_false(Reflect.set({}, method, "bad", accessObj));
|
||||
do_check_eq(realObj[method], originalMethod);
|
||||
}
|
||||
if (attribute) {
|
||||
do_check_false(Reflect.set({}, attribute, "bad", accessObj));
|
||||
do_check_eq(originalAttributeDesc.get, Object.getOwnPropertyDescriptor(realObj, attribute).get);
|
||||
}
|
||||
*/
|
||||
|
||||
// Object.defineProperty can't do anything either.
|
||||
let names = ["expando"];
|
||||
if (method) names.push(method);
|
||||
if (constant) names.push(constant);
|
||||
if (attribute) names.push(attribute);
|
||||
for (let name of names) {
|
||||
let originalDesc = Object.getOwnPropertyDescriptor(realObj, name);
|
||||
check_throws(function () {
|
||||
Object.defineProperty(accessObj, name, {configurable: true});
|
||||
});
|
||||
check_throws(function () {
|
||||
Object.defineProperty(accessObj, name, {writable: true});
|
||||
});
|
||||
check_throws(function () {
|
||||
Object.defineProperty(accessObj, name, {get: function () { return "lies"; }});
|
||||
});
|
||||
check_throws(function () {
|
||||
Object.defineProperty(accessObj, name, {value: "bad"});
|
||||
});
|
||||
let desc = Object.getOwnPropertyDescriptor(realObj, name);
|
||||
if (originalDesc === undefined) {
|
||||
do_check_eq(undefined, desc);
|
||||
} else {
|
||||
do_check_eq(originalDesc.configurable, desc.configurable);
|
||||
do_check_eq(originalDesc.enumerable, desc.enumerable);
|
||||
do_check_eq(originalDesc.writable, desc.writable);
|
||||
do_check_eq(originalDesc.value, desc.value);
|
||||
do_check_eq(originalDesc.get, desc.get);
|
||||
do_check_eq(originalDesc.set, desc.set);
|
||||
}
|
||||
}
|
||||
|
||||
// Existing properties can't be deleted.
|
||||
if (method) {
|
||||
do_check_false(delete accessObj[method]);
|
||||
check_throws(function () { "use strict"; delete accessObj[method]; });
|
||||
do_check_eq(realObj[method], originalMethod);
|
||||
}
|
||||
if (constant) {
|
||||
do_check_false(delete accessObj[constant]);
|
||||
check_throws(function () { "use strict"; delete accessObj[constant]; });
|
||||
do_check_eq(realObj[constant], originalConstantValue);
|
||||
}
|
||||
if (attribute) {
|
||||
do_check_false(delete accessObj[attribute]);
|
||||
check_throws(function () { "use strict"; delete accessObj[attribute]; });
|
||||
desc = Object.getOwnPropertyDescriptor(realObj, attribute);
|
||||
do_check_eq(originalAttributeDesc.get, desc.get);
|
||||
}
|
||||
}
|
||||
|
||||
function test_twice(obj, options) {
|
||||
test_tamperproof(obj, obj, options);
|
||||
|
||||
let handler = {
|
||||
getPrototypeOf(t) {
|
||||
return new Proxy(Object.getPrototypeOf(t), handler);
|
||||
}
|
||||
};
|
||||
test_tamperproof(obj, new Proxy(obj, handler), options);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
test_twice(timer, {
|
||||
method: "init",
|
||||
constant: "TYPE_ONE_SHOT",
|
||||
attribute: "callback"
|
||||
});
|
||||
|
||||
let principal = Cc["@mozilla.org/nullprincipal;1"].createInstance(Ci.nsIPrincipal);
|
||||
test_twice(principal, {});
|
||||
|
||||
test_twice(Object.getPrototypeOf(principal), {
|
||||
method: "subsumes",
|
||||
constant: "APP_STATUS_INSTALLED",
|
||||
attribute: "origin"
|
||||
});
|
||||
|
||||
// Test a tearoff object.
|
||||
Components.manager.autoRegister(do_get_file('../components/js/xpctest.manifest'));
|
||||
let b = Cc["@mozilla.org/js/xpc/test/js/TestInterfaceAll;1"].createInstance(Ci.nsIXPCTestInterfaceB);
|
||||
let tearoff = b.nsIXPCTestInterfaceA;
|
||||
test_twice(tearoff, {
|
||||
method: "QueryInterface"
|
||||
});
|
||||
}
|
||||
|
|
@ -109,6 +109,5 @@ head = head_watchdog.js
|
|||
[test_watchdog_hibernate.js]
|
||||
head = head_watchdog.js
|
||||
[test_writeToGlobalPrototype.js]
|
||||
[test_xpcwn_tamperproof.js]
|
||||
[test_xrayed_iterator.js]
|
||||
[test_xray_SavedFrame.js]
|
||||
|
|
@ -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::HandleId id, JS::HandleValue v,
|
||||
JS::HandleValue receiver, JS::ObjectOpResult &result) const
|
||||
AddonWrapper<Base>::set(JSContext *cx, JS::HandleObject wrapper, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp,
|
||||
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, id, v, receiver, result);
|
||||
return Base::set(cx, wrapper, receiver, id, vp, result);
|
||||
|
||||
if (desc.setter()) {
|
||||
MOZ_ASSERT(desc.hasSetterObject());
|
||||
JS::AutoValueVector args(cx);
|
||||
if (!args.append(v))
|
||||
if (!args.append(vp))
|
||||
return false;
|
||||
RootedValue fval(cx, ObjectValue(*desc.setterObject()));
|
||||
RootedValue ignored(cx);
|
||||
if (!JS::Call(cx, receiver, fval, args, &ignored))
|
||||
if (!JS_CallFunctionValue(cx, receiver, fval, args, vp))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
|
@ -147,8 +147,8 @@ AddonWrapper<Base>::set(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id
|
|||
template<typename Base>
|
||||
bool
|
||||
AddonWrapper<Base>::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
Rooted<JSPropertyDescriptor> interpDesc(cx);
|
||||
if (!Interpose(cx, wrapper, nullptr, id, &interpDesc))
|
||||
|
|
|
|||
|
|
@ -28,14 +28,15 @@ class AddonWrapper : public Base {
|
|||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool delete_(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
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::HandleId id, JS::HandleValue v,
|
||||
JS::HandleValue receiver, JS::ObjectOpResult &result) 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 getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const ChromeObjectWrapper ChromeObjectWrapper::singleton;
|
|||
bool
|
||||
ChromeObjectWrapper::defineProperty(JSContext *cx, HandleObject wrapper,
|
||||
HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
if (!AccessCheck::checkPassToPrivilegedCode(cx, wrapper, desc.value()))
|
||||
|
|
@ -30,12 +30,13 @@ ChromeObjectWrapper::defineProperty(JSContext *cx, HandleObject wrapper,
|
|||
}
|
||||
|
||||
bool
|
||||
ChromeObjectWrapper::set(JSContext *cx, HandleObject wrapper, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const
|
||||
ChromeObjectWrapper::set(JSContext *cx, HandleObject wrapper,
|
||||
HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
if (!AccessCheck::checkPassToPrivilegedCode(cx, wrapper, v))
|
||||
if (!AccessCheck::checkPassToPrivilegedCode(cx, wrapper, vp))
|
||||
return false;
|
||||
return ChromeObjectWrapperBase::set(cx, wrapper, id, v, receiver, result);
|
||||
return ChromeObjectWrapperBase::set(cx, wrapper, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,10 +29,11 @@ class ChromeObjectWrapper : public ChromeObjectWrapperBase
|
|||
|
||||
virtual bool defineProperty(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool set(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::HandleValue v, JS::HandleValue receiver,
|
||||
virtual bool set(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> receiver, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JS::Value> vp,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
|
||||
static const ChromeObjectWrapper singleton;
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ CrossOriginXrayWrapper::ownPropertyKeys(JSContext *cx, JS::Handle<JSObject*> wra
|
|||
bool
|
||||
CrossOriginXrayWrapper::defineProperty(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
JS_ReportError(cx, "Permission denied to define property on cross-origin object");
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ class CrossOriginXrayWrapper : public SecurityXrayDOM {
|
|||
JS::MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::AutoIdVector &props) const override;
|
||||
|
|
|
|||
|
|
@ -593,7 +593,7 @@ JSXrayTraits::delete_(JSContext *cx, HandleObject wrapper, HandleId id, ObjectOp
|
|||
|
||||
bool
|
||||
JSXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
ObjectOpResult &result,
|
||||
bool *defined)
|
||||
|
|
@ -637,10 +637,9 @@ JSXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
|||
return false;
|
||||
}
|
||||
|
||||
Rooted<JSPropertyDescriptor> wrappedDesc(cx, desc);
|
||||
JSAutoCompartment ac(cx, target);
|
||||
if (!JS_WrapPropertyDescriptor(cx, &wrappedDesc) ||
|
||||
!JS_DefinePropertyById(cx, target, id, wrappedDesc, result))
|
||||
if (!JS_WrapPropertyDescriptor(cx, desc) ||
|
||||
!JS_DefinePropertyById(cx, target, id, desc, result))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1416,7 +1415,7 @@ XPCWrappedNativeXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsW
|
|||
|
||||
bool
|
||||
XPCWrappedNativeXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
{
|
||||
|
|
@ -1577,7 +1576,7 @@ DOMXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper, Handl
|
|||
|
||||
bool
|
||||
DOMXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
{
|
||||
|
|
@ -1931,7 +1930,7 @@ XrayWrapper<Base, Traits>::getOwnPropertyDescriptor(JSContext *cx, HandleObject
|
|||
// to the content object. This is ok, because the the expando object is only
|
||||
// ever accessed by code across the compartment boundary.
|
||||
static bool
|
||||
RecreateLostWaivers(JSContext *cx, const JSPropertyDescriptor *orig,
|
||||
RecreateLostWaivers(JSContext *cx, JSPropertyDescriptor *orig,
|
||||
MutableHandle<JSPropertyDescriptor> wrapped)
|
||||
{
|
||||
// Compute whether the original objects were waived, and implicitly, whether
|
||||
|
|
@ -1976,7 +1975,7 @@ RecreateLostWaivers(JSContext *cx, const JSPropertyDescriptor *orig,
|
|||
template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::defineProperty(JSContext *cx, HandleObject wrapper,
|
||||
HandleId id, Handle<JSPropertyDescriptor> desc,
|
||||
HandleId id, MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, wrapper, id, BaseProxyHandler::SET);
|
||||
|
|
@ -2081,15 +2080,15 @@ XrayWrapper<Base, Traits>::get(JSContext *cx, HandleObject wrapper,
|
|||
|
||||
template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::set(JSContext *cx, HandleObject wrapper, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result) const
|
||||
XrayWrapper<Base, Traits>::set(JSContext *cx, HandleObject wrapper,
|
||||
HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, 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.
|
||||
RootedValue wrapperValue(cx, ObjectValue(*wrapper));
|
||||
return js::BaseProxyHandler::set(cx, wrapper, id, v, wrapperValue, result);
|
||||
return js::BaseProxyHandler::set(cx, wrapper, wrapper, id, vp, result);
|
||||
}
|
||||
|
||||
template <typename Base, typename Traits>
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ public:
|
|||
JS::HandleObject holder, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) override;
|
||||
bool defineProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined);
|
||||
virtual bool enumerateNames(JSContext *cx, JS::HandleObject wrapper, unsigned flags,
|
||||
|
|
@ -185,7 +185,7 @@ public:
|
|||
JS::HandleObject holder, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) override;
|
||||
bool defineProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined);
|
||||
virtual bool enumerateNames(JSContext *cx, JS::HandleObject wrapper, unsigned flags,
|
||||
|
|
@ -228,7 +228,7 @@ public:
|
|||
bool delete_(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, JS::ObjectOpResult &result);
|
||||
|
||||
bool defineProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined);
|
||||
|
||||
|
|
@ -346,7 +346,7 @@ public:
|
|||
JS::MutableHandle<JSPropertyDescriptor> desc) override;
|
||||
|
||||
bool defineProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
{
|
||||
|
|
@ -420,7 +420,7 @@ class XrayWrapper : public Base {
|
|||
virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::AutoIdVector &props) const override;
|
||||
|
|
@ -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<jsid> id,
|
||||
JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver,
|
||||
virtual bool set(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp,
|
||||
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<jsid> id,
|
||||
JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver,
|
||||
virtual bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
|
||||
virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
|
|
|
|||
Loading…
Reference in a new issue