mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 05:37:11 +00:00
import changes from rmottola/Arctic-Fox:
- Bug 1113369, part 1 - Introduce JS::ObjectOpResult and use it in js::StandardDefineProperty. (15663c476) - Bug 1113369, part 1½ - Avoid regressing error messages by adding obj to the ObjectOpResult methods that could throw a TypeError. (e063faf08) - Bug 1113369, part 2 - js::SetArrayLength ObjectOpResult support. (cf8326017) - Bug 1113369, part 3 - [[DefineOwnProperty]] ObjectOpResult support. (e16605a90) - Bug 1113369, part 4 - [[Set]] ObjectOpResult support. (6f94604d4)
This commit is contained in:
@@ -159,7 +159,8 @@ bool
|
||||
WindowNamedPropertiesHandler::defineProperty(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aProxy,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc) const
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
ErrorResult rv;
|
||||
rv.ThrowTypeError(MSG_DEFINEPROPERTY_ON_GSP);
|
||||
|
||||
@@ -28,7 +28,8 @@ public:
|
||||
virtual bool
|
||||
defineProperty(JSContext* aCx, JS::Handle<JSObject*> aProxy,
|
||||
JS::Handle<jsid> aId,
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc) const override;
|
||||
JS::MutableHandle<JSPropertyDescriptor> aDesc,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool
|
||||
ownPropNames(JSContext* aCx, JS::Handle<JSObject*> aProxy, unsigned flags,
|
||||
JS::AutoIdVector& aProps) const override;
|
||||
|
||||
@@ -1170,13 +1170,7 @@ nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * aProto)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!contentDefinedProperty && desc.object() && !desc.value().isUndefined() &&
|
||||
!JS_DefineUCProperty(cx, global, mData->mNameUTF16,
|
||||
NS_strlen(mData->mNameUTF16),
|
||||
desc.value(),
|
||||
// Descriptors never store JSNatives for accessors:
|
||||
// they have either JSFunctions or JSPropertyOps.
|
||||
desc.attributes() | JSPROP_PROPOP_ACCESSORS,
|
||||
JS_PROPERTYOP_GETTER(desc.getter()),
|
||||
JS_PROPERTYOP_SETTER(desc.setter()))) {
|
||||
NS_strlen(mData->mNameUTF16), desc)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
|
||||
+13
-15
@@ -622,8 +622,8 @@ public:
|
||||
virtual bool defineProperty(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc)
|
||||
const override;
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext *cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::AutoIdVector &props) const override;
|
||||
@@ -646,8 +646,8 @@ public:
|
||||
virtual bool set(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id,
|
||||
bool strict,
|
||||
JS::MutableHandle<JS::Value> vp) const override;
|
||||
JS::MutableHandle<JS::Value> vp,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
|
||||
// SpiderMonkey extensions
|
||||
virtual bool getPropertyDescriptor(JSContext* cx,
|
||||
@@ -783,8 +783,8 @@ bool
|
||||
nsOuterWindowProxy::defineProperty(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc)
|
||||
const
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
int32_t index = GetArrayIndexFromId(cx, id);
|
||||
if (IsArrayIndex(index)) {
|
||||
@@ -792,7 +792,7 @@ nsOuterWindowProxy::defineProperty(JSContext* cx,
|
||||
// since we have no indexed setter or indexed creator. That means
|
||||
// throwing in strict mode (FIXME: Bug 828137), doing nothing in
|
||||
// non-strict mode.
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
// For now, allow chrome code to define non-configurable properties
|
||||
@@ -803,7 +803,7 @@ nsOuterWindowProxy::defineProperty(JSContext* cx,
|
||||
return ThrowErrorMessage(cx, MSG_DEFINE_NON_CONFIGURABLE_PROP_ON_WINDOW);
|
||||
}
|
||||
|
||||
return js::Wrapper::defineProperty(cx, proxy, id, desc);
|
||||
return js::Wrapper::defineProperty(cx, proxy, id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -917,19 +917,17 @@ bool
|
||||
nsOuterWindowProxy::set(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id,
|
||||
bool strict,
|
||||
JS::MutableHandle<JS::Value> vp) const
|
||||
JS::MutableHandle<JS::Value> vp,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
int32_t index = GetArrayIndexFromId(cx, id);
|
||||
if (IsArrayIndex(index)) {
|
||||
// Reject (which means throw if and only if strict) the set.
|
||||
if (strict) {
|
||||
// XXXbz This needs to throw, but see bug 828137.
|
||||
}
|
||||
return true;
|
||||
// XXX See bug 828137.
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
return js::Wrapper::set(cx, proxy, receiver, id, strict, vp);
|
||||
return js::Wrapper::set(cx, proxy, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -1469,13 +1469,14 @@ XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
bool
|
||||
XrayDefineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc, bool* defined)
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
{
|
||||
if (!js::IsProxy(obj))
|
||||
return true;
|
||||
return true;
|
||||
|
||||
const DOMProxyHandler* handler = GetDOMProxyHandler(obj);
|
||||
return handler->defineProperty(cx, wrapper, id, desc, defined);
|
||||
return handler->defineProperty(cx, wrapper, id, desc, result, defined);
|
||||
}
|
||||
|
||||
template<typename SpecType>
|
||||
|
||||
@@ -2450,12 +2450,17 @@ XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
* wrapper is the Xray JS object.
|
||||
* obj is the target object of the Xray, a binding's instance object or a
|
||||
* interface or interface prototype object.
|
||||
* id and desc are the parameters for the property to be defined.
|
||||
* result is the out-parameter indicating success (read it only if
|
||||
* this returns true and also sets *defined to true).
|
||||
* defined will be set to true if a property was set as a result of this call.
|
||||
*/
|
||||
bool
|
||||
XrayDefineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc, bool* defined);
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result,
|
||||
bool *defined);
|
||||
|
||||
/**
|
||||
* Add to props the property keys of all indexed or named properties of obj and
|
||||
|
||||
+14
-14
@@ -7623,10 +7623,7 @@ class CGResolveHook(CGAbstractBindingMethod):
|
||||
// has already defined it on the object. Don't try to also
|
||||
// define it.
|
||||
if (!desc.value().isUndefined() &&
|
||||
!JS_DefinePropertyById(cx, obj, id, desc.value(),
|
||||
desc.attributes() | JSPROP_PROPOP_ACCESSORS,
|
||||
JS_PROPERTYOP_GETTER(desc.getter()),
|
||||
JS_PROPERTYOP_SETTER(desc.setter()))) {
|
||||
!JS_DefinePropertyById(cx, obj, id, desc)) {
|
||||
return false;
|
||||
}
|
||||
*resolvedp = true;
|
||||
@@ -9621,10 +9618,7 @@ class CGResolveOwnPropertyViaResolve(CGAbstractBindingMethod):
|
||||
// try to also define it.
|
||||
if (objDesc.object() &&
|
||||
!objDesc.value().isUndefined() &&
|
||||
!JS_DefinePropertyById(cx, obj, id, objDesc.value(),
|
||||
objDesc.attributes() | JSPROP_PROPOP_ACCESSORS,
|
||||
JS_PROPERTYOP_GETTER(objDesc.getter()),
|
||||
JS_PROPERTYOP_SETTER(objDesc.setter()))) {
|
||||
!JS_DefinePropertyById(cx, obj, id, objDesc)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -10187,10 +10181,13 @@ class CGDOMJSProxyHandler_getOwnPropDescriptor(ClassMethod):
|
||||
|
||||
class CGDOMJSProxyHandler_defineProperty(ClassMethod):
|
||||
def __init__(self, descriptor):
|
||||
# The usual convention is to name the ObjectOpResult out-parameter
|
||||
# `result`, but that name is a bit overloaded around here.
|
||||
args = [Argument('JSContext*', 'cx'),
|
||||
Argument('JS::Handle<JSObject*>', 'proxy'),
|
||||
Argument('JS::Handle<jsid>', 'id'),
|
||||
Argument('JS::MutableHandle<JSPropertyDescriptor>', 'desc'),
|
||||
Argument('JS::ObjectOpResult&', 'opresult'),
|
||||
Argument('bool*', 'defined')]
|
||||
ClassMethod.__init__(self, "defineProperty", "bool", args, virtual=True, override=True, const=True)
|
||||
self.descriptor = descriptor
|
||||
@@ -10208,7 +10205,7 @@ class CGDOMJSProxyHandler_defineProperty(ClassMethod):
|
||||
if (IsArrayIndex(index)) {
|
||||
*defined = true;
|
||||
$*{callSetter}
|
||||
return true;
|
||||
return opresult.succeed();
|
||||
}
|
||||
""",
|
||||
callSetter=CGProxyIndexedSetter(self.descriptor).define())
|
||||
@@ -10221,7 +10218,9 @@ class CGDOMJSProxyHandler_defineProperty(ClassMethod):
|
||||
set += fill(
|
||||
"""
|
||||
if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
|
||||
return js::IsInNonStrictPropertySet(cx) || ThrowErrorMessage(cx, MSG_NO_INDEXED_SETTER, "${name}");
|
||||
return js::IsInNonStrictPropertySet(cx)
|
||||
? opresult.succeed()
|
||||
: ThrowErrorMessage(cx, MSG_NO_INDEXED_SETTER, "${name}");
|
||||
}
|
||||
""",
|
||||
name=self.descriptor.name)
|
||||
@@ -10236,8 +10235,7 @@ class CGDOMJSProxyHandler_defineProperty(ClassMethod):
|
||||
"}\n"
|
||||
"if (hasUnforgeable) {\n"
|
||||
" *defined = true;\n"
|
||||
" bool unused;\n"
|
||||
" return js::DefineOwnProperty(cx, ${holder}, id, desc, &unused);\n"
|
||||
" return js::DefineOwnProperty(cx, ${holder}, id, desc, opresult);\n"
|
||||
"}\n")
|
||||
set += CallOnUnforgeableHolder(self.descriptor,
|
||||
defineOnUnforgeable,
|
||||
@@ -10254,7 +10252,7 @@ class CGDOMJSProxyHandler_defineProperty(ClassMethod):
|
||||
*defined = true;
|
||||
$*{callSetter}
|
||||
|
||||
return true;
|
||||
return opresult.succeed();
|
||||
""",
|
||||
callSetter=CGProxyNamedSetter(self.descriptor).define())
|
||||
else:
|
||||
@@ -10270,7 +10268,9 @@ class CGDOMJSProxyHandler_defineProperty(ClassMethod):
|
||||
$*{presenceChecker}
|
||||
|
||||
if (found) {
|
||||
return js::IsInNonStrictPropertySet(cx) || ThrowErrorMessage(cx, MSG_NO_NAMED_SETTER, "${name}");
|
||||
return js::IsInNonStrictPropertySet(cx)
|
||||
? opresult.succeed()
|
||||
: ThrowErrorMessage(cx, MSG_NO_NAMED_SETTER, "${name}");
|
||||
}
|
||||
""",
|
||||
presenceChecker=CGProxyNamedPresenceChecker(self.descriptor, foundVar="found").define(),
|
||||
|
||||
@@ -195,18 +195,15 @@ BaseDOMProxyHandler::getOwnPropertyDescriptor(JSContext* cx,
|
||||
|
||||
bool
|
||||
DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
MutableHandle<JSPropertyDescriptor> desc, bool* defined) const
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result, bool *defined) const
|
||||
{
|
||||
if (desc.hasGetterObject() && desc.setter() == JS_StrictPropertyStub) {
|
||||
return JS_ReportErrorFlagsAndNumber(cx,
|
||||
JSREPORT_WARNING | JSREPORT_STRICT |
|
||||
JSREPORT_STRICT_MODE_ERROR,
|
||||
js::GetErrorMessage, nullptr,
|
||||
JSMSG_GETTER_ONLY);
|
||||
return result.failGetterOnly();
|
||||
}
|
||||
|
||||
if (xpc::WrapperFactory::IsXrayWrapper(proxy)) {
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
JSObject* expando = EnsureExpandoObject(cx, proxy);
|
||||
@@ -214,13 +211,16 @@ DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dummy;
|
||||
return js::DefineOwnProperty(cx, expando, id, desc, &dummy);
|
||||
if (!js::DefineOwnProperty(cx, expando, id, desc, result)) {
|
||||
return false;
|
||||
}
|
||||
*defined = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<JSObject*> receiver,
|
||||
Handle<jsid> id, bool strict, MutableHandle<JS::Value> vp) const
|
||||
Handle<jsid> id, MutableHandle<JS::Value> vp, ObjectOpResult &result) const
|
||||
{
|
||||
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
|
||||
"Should not have a XrayWrapper here");
|
||||
@@ -229,7 +229,7 @@ DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<JSObject*> r
|
||||
return false;
|
||||
}
|
||||
if (done) {
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
// Make sure to ignore our named properties when checking for own
|
||||
@@ -254,7 +254,7 @@ DOMProxyHandler::set(JSContext *cx, Handle<JSObject*> proxy, Handle<JSObject*> r
|
||||
}
|
||||
|
||||
return js::SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id,
|
||||
&desc, descIsOwn, strict, vp);
|
||||
&desc, descIsOwn, vp, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -105,25 +105,26 @@ public:
|
||||
{}
|
||||
|
||||
bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const override
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE
|
||||
{
|
||||
bool unused;
|
||||
return defineProperty(cx, proxy, id, desc, &unused);
|
||||
return defineProperty(cx, proxy, id, desc, result, &unused);
|
||||
}
|
||||
virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc, bool* defined)
|
||||
const;
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result, bool *defined) const;
|
||||
bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id, bool* bp) const override;
|
||||
JS::Handle<jsid> id, bool* bp) const MOZ_OVERRIDE;
|
||||
bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
bool *succeeded) const override;
|
||||
bool *succeeded) const MOZ_OVERRIDE;
|
||||
bool isExtensible(JSContext *cx, JS::Handle<JSObject*> proxy, bool *extensible)
|
||||
const override;
|
||||
bool has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
bool* bp) const override;
|
||||
bool* bp) const MOZ_OVERRIDE;
|
||||
bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id, bool strict, JS::MutableHandle<JS::Value> vp)
|
||||
const override;
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp, JS::ObjectOpResult &result)
|
||||
const MOZ_OVERRIDE;
|
||||
|
||||
/*
|
||||
* If assigning to proxy[id] hits a named setter with OverrideBuiltins or
|
||||
|
||||
@@ -169,8 +169,8 @@ static bool
|
||||
NPObjWrapper_DelProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, bool *succeeded);
|
||||
|
||||
static bool
|
||||
NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, bool strict,
|
||||
JS::MutableHandle<JS::Value> vp);
|
||||
NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JS::Value> vp, JS::ObjectOpResult &result);
|
||||
|
||||
static bool
|
||||
NPObjWrapper_GetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp);
|
||||
@@ -1326,8 +1326,8 @@ NPObjWrapper_DelProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
||||
}
|
||||
|
||||
static bool
|
||||
NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, bool strict,
|
||||
JS::MutableHandle<JS::Value> vp)
|
||||
NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JS::Value> vp, JS::ObjectOpResult &result)
|
||||
{
|
||||
NPObject *npobj = GetNPObject(cx, obj);
|
||||
|
||||
@@ -1382,7 +1382,7 @@ NPObjWrapper_SetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
static bool
|
||||
|
||||
@@ -52,8 +52,7 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
|
||||
return Answer::RecvGetOwnPropertyDescriptor(ObjectId::deserialize(objId), id, rs, out);
|
||||
}
|
||||
bool RecvDefineProperty(const uint64_t& objId, const JSIDVariant& id,
|
||||
const PPropertyDescriptor& flags,
|
||||
ReturnStatus* rs) {
|
||||
const PPropertyDescriptor &flags, ReturnStatus *rs) {
|
||||
return Answer::RecvDefineProperty(ObjectId::deserialize(objId), id, flags, rs);
|
||||
}
|
||||
bool RecvDelete(const uint64_t& objId, const JSIDVariant& id,
|
||||
@@ -75,9 +74,9 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
|
||||
return Answer::RecvGet(ObjectId::deserialize(objId), receiverVar, id, rs, result);
|
||||
}
|
||||
bool RecvSet(const uint64_t& objId, const ObjectVariant& receiverVar,
|
||||
const JSIDVariant& id, const bool& strict,
|
||||
const JSVariant& value, ReturnStatus* rs, JSVariant* result) {
|
||||
return Answer::RecvSet(ObjectId::deserialize(objId), receiverVar, id, strict, value, rs, result);
|
||||
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,
|
||||
@@ -145,7 +144,7 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
|
||||
}
|
||||
bool SendDefineProperty(const ObjectId& objId, const JSIDVariant& id,
|
||||
const PPropertyDescriptor& flags,
|
||||
ReturnStatus* rs) {
|
||||
ReturnStatus *rs) {
|
||||
return Base::SendDefineProperty(objId.serialize(), id, flags, rs);
|
||||
}
|
||||
bool SendDelete(const ObjectId& objId, const JSIDVariant& id,
|
||||
@@ -167,9 +166,9 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
|
||||
return Base::SendGet(objId.serialize(), receiverVar, id, rs, result);
|
||||
}
|
||||
bool SendSet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
const JSIDVariant& id, const bool& strict,
|
||||
const JSVariant& value, ReturnStatus* rs, JSVariant* result) {
|
||||
return Base::SendSet(objId.serialize(), receiverVar, id, strict, value, rs, result);
|
||||
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,
|
||||
|
||||
@@ -605,7 +605,8 @@ UnknownPropertyStub(JSContext* cx, HandleObject obj, HandleId id, MutableHandleV
|
||||
}
|
||||
|
||||
bool
|
||||
UnknownStrictPropertyStub(JSContext* cx, HandleObject obj, HandleId id, bool strict, MutableHandleValue vp)
|
||||
UnknownStrictPropertyStub(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
JS_ReportError(cx, "setter could not be wrapped via CPOWs");
|
||||
return false;
|
||||
|
||||
@@ -103,11 +103,17 @@ struct ReturnException
|
||||
JSVariant exn;
|
||||
};
|
||||
|
||||
struct ReturnObjectOpResult
|
||||
{
|
||||
uint32_t code;
|
||||
};
|
||||
|
||||
union ReturnStatus
|
||||
{
|
||||
ReturnSuccess;
|
||||
ReturnStopIteration;
|
||||
ReturnException;
|
||||
ReturnObjectOpResult;
|
||||
};
|
||||
|
||||
union JSParam
|
||||
|
||||
@@ -33,7 +33,7 @@ both:
|
||||
prio(high) sync Has(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
|
||||
prio(high) sync HasOwn(uint64_t objId, JSIDVariant id) returns (ReturnStatus rs, bool has);
|
||||
prio(high) sync Get(uint64_t objId, ObjectVariant receiver, JSIDVariant id) returns (ReturnStatus rs, JSVariant result);
|
||||
prio(high) sync Set(uint64_t objId, ObjectVariant receiver, JSIDVariant id, bool strict, JSVariant value) returns (ReturnStatus rs, JSVariant result);
|
||||
prio(high) sync Set(uint64_t objId, ObjectVariant receiver, JSIDVariant id, JSVariant value) returns (ReturnStatus rs, JSVariant result);
|
||||
|
||||
prio(high) sync 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);
|
||||
|
||||
+20
-12
@@ -64,6 +64,15 @@ WrapperAnswer::ok(ReturnStatus* rs)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::ok(ReturnStatus *rs, const JS::ObjectOpResult &result)
|
||||
{
|
||||
*rs = result
|
||||
? ReturnStatus(ReturnSuccess())
|
||||
: ReturnStatus(ReturnObjectOpResult(result.failureCode()));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WrapperAnswer::RecvPreventExtensions(const ObjectId& objId, ReturnStatus* rs,
|
||||
bool* succeeded)
|
||||
@@ -179,11 +188,10 @@ WrapperAnswer::RecvDefineProperty(const ObjectId& objId, const JSIDVariant& idVa
|
||||
if (!toDescriptor(cx, descriptor, &desc))
|
||||
return fail(cx, rs);
|
||||
|
||||
bool ignored;
|
||||
if (!js::DefineOwnProperty(cx, obj, id, desc, &ignored))
|
||||
ObjectOpResult success;
|
||||
if (!js::DefineOwnProperty(cx, obj, id, desc, success))
|
||||
return fail(cx, rs);
|
||||
|
||||
return ok(rs);
|
||||
return ok(rs, success);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -305,8 +313,8 @@ WrapperAnswer::RecvGet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
|
||||
bool
|
||||
WrapperAnswer::RecvSet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
const JSIDVariant& idVar, const bool& strict, const JSVariant& value,
|
||||
ReturnStatus* rs, JSVariant* result)
|
||||
const JSIDVariant &idVar, const JSVariant &value, ReturnStatus *rs,
|
||||
JSVariant *resultValue)
|
||||
{
|
||||
// We may run scripted setters.
|
||||
AutoEntryScript aes(xpc::NativeGlobal(scopeForTargetObjects()));
|
||||
@@ -314,7 +322,7 @@ WrapperAnswer::RecvSet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
|
||||
// The outparam will be written to the buffer, so it must be set even if
|
||||
// the parent won't read it.
|
||||
*result = UndefinedVariant();
|
||||
*resultValue = UndefinedVariant();
|
||||
|
||||
RootedObject obj(cx, findObjectById(cx, objId));
|
||||
if (!obj)
|
||||
@@ -330,19 +338,19 @@ WrapperAnswer::RecvSet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
if (!fromJSIDVariant(cx, idVar, &id))
|
||||
return fail(cx, rs);
|
||||
|
||||
MOZ_ASSERT(obj == receiver);
|
||||
|
||||
RootedValue val(cx);
|
||||
if (!fromVariant(cx, value, &val))
|
||||
return fail(cx, rs);
|
||||
|
||||
if (!JS_SetPropertyById(cx, obj, id, val))
|
||||
ObjectOpResult result;
|
||||
RootedValue receiverVal(cx, ObjectValue(*receiver));
|
||||
if (!JS_ForwardSetPropertyTo(cx, obj, id, val, receiverVal, result))
|
||||
return fail(cx, rs);
|
||||
|
||||
if (!toVariant(cx, val, result))
|
||||
if (!toVariant(cx, val, resultValue))
|
||||
return fail(cx, rs);
|
||||
|
||||
return ok(rs);
|
||||
return ok(rs, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -28,8 +28,7 @@ class WrapperAnswer : public virtual JavaScriptShared
|
||||
ReturnStatus* rs,
|
||||
PPropertyDescriptor* out);
|
||||
bool RecvDefineProperty(const ObjectId& objId, const JSIDVariant& id,
|
||||
const PPropertyDescriptor& flags,
|
||||
ReturnStatus* rs);
|
||||
const PPropertyDescriptor &flags, ReturnStatus *rs);
|
||||
bool RecvDelete(const ObjectId& objId, const JSIDVariant& id,
|
||||
ReturnStatus* rs, bool* success);
|
||||
|
||||
@@ -41,8 +40,8 @@ class WrapperAnswer : public virtual JavaScriptShared
|
||||
const JSIDVariant& id,
|
||||
ReturnStatus* rs, JSVariant* result);
|
||||
bool RecvSet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
const JSIDVariant& id, const bool& strict,
|
||||
const JSVariant& value, ReturnStatus* rs, JSVariant* result);
|
||||
const JSIDVariant &id, const JSVariant &value, ReturnStatus *rs,
|
||||
JSVariant *result);
|
||||
|
||||
bool RecvIsExtensible(const ObjectId& objId, ReturnStatus* rs,
|
||||
bool* result);
|
||||
@@ -67,7 +66,8 @@ class WrapperAnswer : public virtual JavaScriptShared
|
||||
|
||||
private:
|
||||
bool fail(JSContext* cx, ReturnStatus* rs);
|
||||
bool ok(ReturnStatus* rs);
|
||||
bool ok(ReturnStatus *rs);
|
||||
bool ok(ReturnStatus *rs, const JS::ObjectOpResult &result);
|
||||
};
|
||||
|
||||
} // mozilla
|
||||
|
||||
+27
-13
@@ -90,7 +90,8 @@ 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,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const override;
|
||||
@@ -101,7 +102,8 @@ class CPOWProxyHandler : public BaseProxyHandler
|
||||
virtual bool get(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp) const override;
|
||||
virtual bool set(JSContext* cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, bool strict, JS::MutableHandleValue vp) const override;
|
||||
JS::HandleId id, JS::MutableHandleValue vp,
|
||||
JS::ObjectOpResult &result) const MOZ_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;
|
||||
|
||||
@@ -202,14 +204,16 @@ WrapperOwner::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, Handle
|
||||
|
||||
bool
|
||||
CPOWProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
FORWARD(defineProperty, (cx, proxy, id, desc));
|
||||
FORWARD(defineProperty, (cx, proxy, id, desc, result));
|
||||
}
|
||||
|
||||
bool
|
||||
WrapperOwner::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc)
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
ObjectId objId = idOf(proxy);
|
||||
|
||||
@@ -227,7 +231,7 @@ WrapperOwner::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
return ok(cx, status);
|
||||
return ok(cx, status, result);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -431,14 +435,14 @@ WrapperOwner::get(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
|
||||
bool
|
||||
CPOWProxyHandler::set(JSContext* cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, bool strict, JS::MutableHandleValue vp) const
|
||||
JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result) const
|
||||
{
|
||||
FORWARD(set, (cx, proxy, receiver, id, strict, vp));
|
||||
FORWARD(set, (cx, proxy, receiver, id, vp, result));
|
||||
}
|
||||
|
||||
bool
|
||||
WrapperOwner::set(JSContext* cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, bool strict, JS::MutableHandleValue vp)
|
||||
JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result)
|
||||
{
|
||||
ObjectId objId = idOf(proxy);
|
||||
|
||||
@@ -455,16 +459,16 @@ WrapperOwner::set(JSContext* cx, JS::HandleObject proxy, JS::HandleObject receiv
|
||||
return false;
|
||||
|
||||
ReturnStatus status;
|
||||
JSVariant result;
|
||||
if (!SendSet(objId, receiverVar, idVar, strict, val, &status, &result))
|
||||
JSVariant resultValue;
|
||||
if (!SendSet(objId, receiverVar, idVar, val, &status, &resultValue))
|
||||
return ipcfail(cx);
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
if (!ok(cx, status))
|
||||
if (!ok(cx, status, result))
|
||||
return false;
|
||||
|
||||
return fromVariant(cx, result, vp);
|
||||
return fromVariant(cx, resultValue, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -934,6 +938,16 @@ WrapperOwner::ok(JSContext* cx, const ReturnStatus& status)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
WrapperOwner::ok(JSContext *cx, const ReturnStatus &status, ObjectOpResult &result)
|
||||
{
|
||||
if (status.type() == ReturnStatus::TReturnObjectOpResult)
|
||||
return result.fail(status.get_ReturnObjectOpResult().code());
|
||||
if (!ok(cx, status))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
static RemoteObject
|
||||
MakeRemoteObject(JSContext* cx, ObjectId id, HandleObject obj)
|
||||
{
|
||||
|
||||
@@ -32,7 +32,8 @@ 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::MutableHandle<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, bool* bp);
|
||||
bool preventExtensions(JSContext* cx, JS::HandleObject proxy, bool* succeeded);
|
||||
@@ -41,7 +42,7 @@ class WrapperOwner : public virtual JavaScriptShared
|
||||
bool get(JSContext* cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandleValue vp);
|
||||
bool set(JSContext* cx, JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, bool strict, JS::MutableHandleValue vp);
|
||||
JS::HandleId id, JS::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
bool callOrConstruct(JSContext* cx, JS::HandleObject proxy, const JS::CallArgs& args,
|
||||
bool construct);
|
||||
|
||||
@@ -93,6 +94,10 @@ class WrapperOwner : public virtual JavaScriptShared
|
||||
bool ipcfail(JSContext* cx);
|
||||
|
||||
// Check whether a return status is okay, and if not, propagate its error.
|
||||
//
|
||||
// If 'status' might be a ReturnObjectOpResult, which is only possible for
|
||||
// a subset of the operations below, 'result' must be passed.
|
||||
bool ok(JSContext *cx, const ReturnStatus &status, JS::ObjectOpResult &result);
|
||||
bool ok(JSContext* cx, const ReturnStatus& status);
|
||||
|
||||
bool inactive_;
|
||||
@@ -123,8 +128,8 @@ class WrapperOwner : public virtual JavaScriptShared
|
||||
const JSIDVariant& id,
|
||||
ReturnStatus* rs, JSVariant* result) = 0;
|
||||
virtual bool SendSet(const ObjectId& objId, const ObjectVariant& receiverVar,
|
||||
const JSIDVariant& id, const bool& strict,
|
||||
const JSVariant& value, ReturnStatus* rs, JSVariant* result) = 0;
|
||||
const JSIDVariant &id, const JSVariant &value,
|
||||
ReturnStatus *rs, JSVariant *result) = 0;
|
||||
|
||||
virtual bool SendIsExtensible(const ObjectId& objId, ReturnStatus* rs,
|
||||
bool* result) = 0;
|
||||
|
||||
+125
-3
@@ -44,6 +44,127 @@ namespace JS {
|
||||
|
||||
class AutoIdVector;
|
||||
|
||||
/*
|
||||
* Per ES6, the [[DefineOwnProperty]] internal method has three different
|
||||
* possible outcomes:
|
||||
*
|
||||
* - It can throw an exception (which we indicate by returning false).
|
||||
*
|
||||
* - It can return true, indicating unvarnished success.
|
||||
*
|
||||
* - It can return false, indicating "strict failure". The property could
|
||||
* not be defined. It's an error, but no exception was thrown.
|
||||
*
|
||||
* It's not just [[DefineOwnProperty]]: all the mutating internal methods have
|
||||
* the same three outcomes. (The other affected internal methods are [[Set]],
|
||||
* [[Delete]], [[SetPrototypeOf]], and [[PreventExtensions]].)
|
||||
*
|
||||
* If you think this design is awful, you're not alone. But as it's the
|
||||
* standard, we must represent these boolean "success" values somehow.
|
||||
* ObjectOpSuccess is the class for this. It's like a bool, but when it's false
|
||||
* it also stores an error code.
|
||||
*
|
||||
* Typical usage:
|
||||
*
|
||||
* ObjectOpResult result;
|
||||
* if (!DefineProperty(cx, obj, id, ..., result))
|
||||
* return false;
|
||||
* if (!result)
|
||||
* return result.reportError(cx, obj, id);
|
||||
*
|
||||
* Users don't have to call `result.report()`; another possible ending is:
|
||||
*
|
||||
* argv.rval().setBoolean(bool(result));
|
||||
* return true;
|
||||
*/
|
||||
class ObjectOpResult
|
||||
{
|
||||
private:
|
||||
uint32_t code_;
|
||||
|
||||
public:
|
||||
enum { OkCode = 0, Uninitialized = 0xffffffff };
|
||||
|
||||
ObjectOpResult() : code_(Uninitialized) {}
|
||||
|
||||
/* Return true if fail() was not called. */
|
||||
bool ok() const {
|
||||
MOZ_ASSERT(code_ != Uninitialized);
|
||||
return code_ == OkCode;
|
||||
}
|
||||
|
||||
explicit operator bool() const { return ok(); }
|
||||
|
||||
/* Set this ObjectOpResult to true and return true. */
|
||||
bool succeed() {
|
||||
code_ = OkCode;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set this ObjectOpResult to false with an error code.
|
||||
*
|
||||
* Always returns true, as a convenience. Typical usage will be:
|
||||
*
|
||||
* if (funny condition)
|
||||
* return result.fail(JSMSG_CANT_DO_THE_THINGS);
|
||||
*
|
||||
* The true return value indicates that no exception is pending, and it
|
||||
* would be OK to ignore the failure and continue.
|
||||
*/
|
||||
bool fail(uint32_t msg) {
|
||||
MOZ_ASSERT(msg != OkCode);
|
||||
code_ = msg;
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool) failCantRedefineProp();
|
||||
JS_PUBLIC_API(bool) failReadOnly();
|
||||
JS_PUBLIC_API(bool) failGetterOnly();
|
||||
JS_PUBLIC_API(bool) failCantSetInterposed();
|
||||
|
||||
uint32_t failureCode() const {
|
||||
MOZ_ASSERT(!ok());
|
||||
return code_;
|
||||
}
|
||||
|
||||
/*
|
||||
* Report an error or warning if necessary; return true to proceed and
|
||||
* false if an error was reported. Call this when failure should cause
|
||||
* a warning if extraWarnings are enabled.
|
||||
*
|
||||
* The precise rules are like this:
|
||||
*
|
||||
* - If ok(), then we succeeded. Do nothing and return true.
|
||||
* - Otherwise, if |strict| is true, or if cx has both extraWarnings and
|
||||
* werrorOption enabled, throw a TypeError and return false.
|
||||
* - Otherwise, if cx has extraWarnings enabled, emit a warning and
|
||||
* return true.
|
||||
* - Otherwise, do nothing and return true.
|
||||
*/
|
||||
bool checkStrictErrorOrWarning(JSContext *cx, HandleObject obj, HandleId id, bool strict) {
|
||||
if (ok())
|
||||
return true;
|
||||
return reportStrictErrorOrWarning(cx, obj, id, strict);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convenience method. Return true if ok() or if strict is false; otherwise
|
||||
* throw a TypeError and return false.
|
||||
*/
|
||||
bool checkStrict(JSContext *cx, HandleObject obj, HandleId id) {
|
||||
return checkStrictErrorOrWarning(cx, obj, id, true);
|
||||
}
|
||||
|
||||
/* Throw a TypeError. Call this only if !ok(). */
|
||||
bool reportError(JSContext *cx, HandleObject obj, HandleId id) {
|
||||
return reportStrictErrorOrWarning(cx, obj, id, true);
|
||||
}
|
||||
|
||||
/* Helper function for checkStrictErrorOrWarning's slow path. */
|
||||
JS_PUBLIC_API(bool) reportStrictErrorOrWarning(JSContext *cx, HandleObject obj, HandleId id, bool strict);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// JSClass operation signatures.
|
||||
@@ -62,7 +183,7 @@ typedef bool
|
||||
// set.
|
||||
typedef bool
|
||||
(* JSStrictPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
|
||||
bool strict, JS::MutableHandleValue vp);
|
||||
JS::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
|
||||
// Delete a property named by id in obj.
|
||||
//
|
||||
@@ -166,7 +287,8 @@ typedef bool
|
||||
JS::MutableHandleObject objp, JS::MutableHandle<Shape*> propp);
|
||||
typedef bool
|
||||
(* DefinePropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs,
|
||||
JS::ObjectOpResult &result);
|
||||
typedef bool
|
||||
(* HasPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
|
||||
typedef bool
|
||||
@@ -174,7 +296,7 @@ typedef bool
|
||||
JS::MutableHandleValue vp);
|
||||
typedef bool
|
||||
(* SetPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
|
||||
JS::MutableHandleValue vp, bool strict);
|
||||
JS::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
typedef bool
|
||||
(* GetOwnPropertyOp)(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
||||
+8
-4
@@ -26,6 +26,7 @@ using JS::MutableHandle;
|
||||
using JS::MutableHandleObject;
|
||||
using JS::MutableHandleValue;
|
||||
using JS::NativeImpl;
|
||||
using JS::ObjectOpResult;
|
||||
using JS::PrivateValue;
|
||||
using JS::Value;
|
||||
|
||||
@@ -251,7 +252,8 @@ 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,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const = 0;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const = 0;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const = 0;
|
||||
virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const = 0;
|
||||
@@ -289,7 +291,7 @@ class JS_FRIEND_API(BaseProxyHandler)
|
||||
virtual bool get(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp) const;
|
||||
virtual bool set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, bool strict, MutableHandleValue vp) const;
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const;
|
||||
|
||||
/*
|
||||
* [[Call]] and [[Construct]] are standard internal methods but according
|
||||
@@ -368,7 +370,8 @@ class JS_PUBLIC_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,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
@@ -388,7 +391,8 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler
|
||||
virtual bool get(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp) const override;
|
||||
virtual bool set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, bool strict, MutableHandleValue vp) const override;
|
||||
HandleId id, MutableHandleValue vp,
|
||||
ObjectOpResult &result) const MOZ_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;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ class MOZ_STACK_CLASS SourceBufferHolder;
|
||||
|
||||
class HandleValueArray;
|
||||
|
||||
class ObjectOpResult;
|
||||
}
|
||||
|
||||
// Do the importing.
|
||||
@@ -143,6 +144,8 @@ using JS::FalseHandleValue;
|
||||
|
||||
using JS::HandleValueArray;
|
||||
|
||||
using JS::ObjectOpResult;
|
||||
|
||||
using JS::Zone;
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
@@ -833,8 +833,7 @@ js::obj_defineProperty(JSContext* cx, unsigned argc, Value* vp)
|
||||
if (!desc.initialize(cx, args.get(2)))
|
||||
return false;
|
||||
|
||||
bool ignored;
|
||||
if (!StandardDefineProperty(cx, obj, id, desc, true, &ignored))
|
||||
if (!StandardDefineProperty(cx, obj, id, desc))
|
||||
return false;
|
||||
|
||||
args.rval().setObject(*obj);
|
||||
|
||||
@@ -1755,7 +1755,8 @@ ReportPropertyError(JSContext* cx,
|
||||
|
||||
bool
|
||||
TypedObject::obj_defineProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
Rooted<TypedObject*> typedObj(cx, &obj->as<TypedObject>());
|
||||
return ReportTypedObjTypeError(cx, JSMSG_OBJECT_NOT_EXTENSIBLE, typedObj);
|
||||
@@ -1907,7 +1908,7 @@ TypedObject::obj_getArrayElement(JSContext* cx,
|
||||
|
||||
bool
|
||||
TypedObject::obj_setProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, bool strict)
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
Rooted<TypedObject*> typedObj(cx, &obj->as<TypedObject>());
|
||||
|
||||
@@ -1926,13 +1927,13 @@ TypedObject::obj_setProperty(JSContext* cx, HandleObject obj, HandleObject recei
|
||||
nullptr, JSMSG_CANT_REDEFINE_ARRAY_LENGTH);
|
||||
return false;
|
||||
}
|
||||
return SetNonWritableProperty(cx, id, strict);
|
||||
return result.failReadOnly();
|
||||
}
|
||||
|
||||
uint32_t index;
|
||||
if (IdIsIndex(id, &index)) {
|
||||
if (obj != receiver)
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, strict, false);
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result);
|
||||
|
||||
if (index >= uint32_t(typedObj->length())) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage,
|
||||
@@ -1943,7 +1944,9 @@ TypedObject::obj_setProperty(JSContext* cx, HandleObject obj, HandleObject recei
|
||||
Rooted<TypeDescr*> elementType(cx);
|
||||
elementType = &typedObj->typeDescr().as<ArrayTypeDescr>().elementType();
|
||||
size_t offset = elementType->size() * index;
|
||||
return ConvertAndCopyTo(cx, elementType, typedObj, offset, NullPtr(), vp);
|
||||
if (!ConvertAndCopyTo(cx, elementType, typedObj, offset, NullPtr(), vp))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1956,16 +1959,18 @@ TypedObject::obj_setProperty(JSContext* cx, HandleObject obj, HandleObject recei
|
||||
break;
|
||||
|
||||
if (obj != receiver)
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, strict, false);
|
||||
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));
|
||||
return ConvertAndCopyTo(cx, fieldType, typedObj, offset, fieldName, vp);
|
||||
if (!ConvertAndCopyTo(cx, fieldType, typedObj, offset, fieldName, vp))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
|
||||
return SetPropertyOnProto(cx, obj, receiver, id, vp, strict);
|
||||
return SetPropertyOnProto(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -528,7 +528,8 @@ class TypedObject : public JSObject
|
||||
MutableHandleObject objp, MutableHandleShape propp);
|
||||
|
||||
static bool obj_defineProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
ObjectOpResult &result);
|
||||
|
||||
static bool obj_hasProperty(JSContext* cx, HandleObject obj, HandleId id, bool* foundp);
|
||||
|
||||
@@ -539,7 +540,7 @@ class TypedObject : public JSObject
|
||||
uint32_t index, MutableHandleValue vp);
|
||||
|
||||
static bool obj_setProperty(JSContext* cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, bool strict);
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
static bool obj_getOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
||||
+17
-10
@@ -287,7 +287,8 @@ namespace ArrayType {
|
||||
bool LengthGetter(JSContext* cx, const JS::CallArgs& args);
|
||||
|
||||
static bool Getter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp);
|
||||
static bool Setter(JSContext* cx, HandleObject obj, HandleId idval, bool strict, MutableHandleValue vp);
|
||||
static bool Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp,
|
||||
ObjectOpResult &result);
|
||||
static bool AddressOfElement(JSContext* cx, unsigned argc, jsval* vp);
|
||||
}
|
||||
|
||||
@@ -300,9 +301,9 @@ namespace StructType {
|
||||
bool FieldsArrayGetter(JSContext* cx, const JS::CallArgs& args);
|
||||
|
||||
static bool FieldGetter(JSContext* cx, HandleObject obj, HandleId idval,
|
||||
MutableHandleValue vp);
|
||||
static bool FieldSetter(JSContext* cx, HandleObject obj, HandleId idval, bool strict,
|
||||
MutableHandleValue vp);
|
||||
MutableHandleValue vp);
|
||||
static bool FieldSetter(JSContext* cx, HandleObject obj, HandleId idval,
|
||||
MutableHandleValue vp, ObjectOpResult &result);
|
||||
static bool AddressOfField(JSContext* cx, unsigned argc, jsval* vp);
|
||||
static bool Define(JSContext* cx, unsigned argc, jsval* vp);
|
||||
}
|
||||
@@ -4628,7 +4629,8 @@ ArrayType::Getter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandle
|
||||
}
|
||||
|
||||
bool
|
||||
ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, bool strict, MutableHandleValue vp)
|
||||
ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
// This should never happen, but we'll check to be safe.
|
||||
if (!CData::IsCData(obj)) {
|
||||
@@ -4640,7 +4642,7 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, bool strict,
|
||||
// CData, regardless of CType.)
|
||||
JSObject* typeObj = CData::GetCType(obj);
|
||||
if (CType::GetTypeCode(typeObj) != TYPE_array)
|
||||
return true;
|
||||
return result.succeed();
|
||||
|
||||
// Convert the index to a size_t and bounds-check it.
|
||||
size_t index;
|
||||
@@ -4650,7 +4652,7 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, bool strict,
|
||||
if (!ok && JSID_IS_STRING(idval) && !StringToInteger(cx, JSID_TO_STRING(idval), &dummy)) {
|
||||
// String either isn't a number, or doesn't fit in size_t.
|
||||
// Chances are it's a regular property lookup, so return.
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
if (!ok || index >= length) {
|
||||
JS_ReportError(cx, "invalid index");
|
||||
@@ -4660,7 +4662,9 @@ ArrayType::Setter(JSContext* cx, HandleObject obj, HandleId idval, bool strict,
|
||||
JSObject* baseType = GetBaseType(typeObj);
|
||||
size_t elementSize = CType::GetSize(baseType);
|
||||
char* data = static_cast<char*>(CData::GetData(obj)) + elementSize * index;
|
||||
return ImplicitConvert(cx, vp, baseType, data, false, nullptr);
|
||||
if (!ImplicitConvert(cx, vp, baseType, data, false, nullptr))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -5293,7 +5297,8 @@ StructType::FieldGetter(JSContext* cx, HandleObject obj, HandleId idval, Mutable
|
||||
}
|
||||
|
||||
bool
|
||||
StructType::FieldSetter(JSContext* cx, HandleObject obj, HandleId idval, bool strict, MutableHandleValue vp)
|
||||
StructType::FieldSetter(JSContext* cx, HandleObject obj, HandleId idval, MutableHandleValue vp,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
if (!CData::IsCData(obj)) {
|
||||
JS_ReportError(cx, "not a CData");
|
||||
@@ -5311,7 +5316,9 @@ StructType::FieldSetter(JSContext* cx, HandleObject obj, HandleId idval, bool st
|
||||
return false;
|
||||
|
||||
char* data = static_cast<char*>(CData::GetData(obj)) + field->mOffset;
|
||||
return ImplicitConvert(cx, vp, field->mType, data, false, nullptr);
|
||||
if (!ImplicitConvert(cx, vp, field->mType, data, false, nullptr))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -99,7 +99,7 @@ check("o[- (o)]");
|
||||
|
||||
// A few one off tests
|
||||
check_one("6", (function () { 6() }), " is not a function");
|
||||
check_one("Array.prototype.reverse.call(...)", (function () { Array.prototype.reverse.call('123'); }), " is read-only");
|
||||
check_one("0", (function () { Array.prototype.reverse.call('123'); }), " is read-only");
|
||||
check_one(`(intermediate value)[Symbol.iterator](...).next(...).value`,
|
||||
function () { var [{ x }] = [null, {}]; }, " is null");
|
||||
check_one(`(intermediate value)[Symbol.iterator](...).next(...).value`,
|
||||
|
||||
@@ -8382,7 +8382,7 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
|
||||
MOZ_ASSERT(op == JSOP_SETPROP || op == JSOP_STRICTSETPROP);
|
||||
|
||||
RootedValue v(cx, rhs);
|
||||
if (!SetProperty(cx, obj, obj, id, &v, op == JSOP_STRICTSETPROP))
|
||||
if (!PutProperty(cx, obj, id, &v, op == JSOP_STRICTSETPROP))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+99
-18
@@ -1460,6 +1460,13 @@ GetPropertyIC::tryAttachTypedArrayLength(JSContext* cx, HandleScript outerScript
|
||||
return linkAndAttachStub(cx, masm, attacher, ion, "typed array length");
|
||||
}
|
||||
|
||||
static void
|
||||
PushObjectOpResult(MacroAssembler &masm, uint32_t value = ObjectOpResult::Uninitialized)
|
||||
{
|
||||
static_assert(sizeof(ObjectOpResult) == sizeof(int32_t),
|
||||
"ObjectOpResult size must match size reserved by masm.Push() here");
|
||||
masm.Push(Imm32(value));
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitCallProxyGet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& attacher,
|
||||
@@ -1504,6 +1511,9 @@ EmitCallProxyGet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
|
||||
masm.Push(object);
|
||||
masm.movePtr(StackPointer, argProxyReg);
|
||||
|
||||
// Unused space, to keep the same stack layout as Proxy::set frames.
|
||||
PushObjectOpResult(masm, 0);
|
||||
|
||||
masm.loadJSContext(argJSContextReg);
|
||||
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
@@ -2118,6 +2128,54 @@ IsCacheableSetPropCallPropertyOp(HandleObject obj, HandleObject holder, HandleSh
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ReportStrictErrorOrWarning(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool strict,
|
||||
JS::ObjectOpResult &result)
|
||||
{
|
||||
return result.reportStrictErrorOrWarning(cx, obj, id, strict);
|
||||
}
|
||||
|
||||
template <class FrameLayout>
|
||||
void
|
||||
EmitObjectOpResultCheck(MacroAssembler &masm, Label *failure, bool strict,
|
||||
Register scratchReg,
|
||||
Register argJSContextReg,
|
||||
Register argObjReg,
|
||||
Register argIdReg,
|
||||
Register argStrictReg,
|
||||
Register argResultReg)
|
||||
{
|
||||
// if (!result) {
|
||||
Label noStrictError;
|
||||
masm.branch32(Assembler::Equal,
|
||||
Address(StackPointer,
|
||||
FrameLayout::offsetOfObjectOpResult()),
|
||||
Imm32(ObjectOpResult::OkCode),
|
||||
&noStrictError);
|
||||
|
||||
// if (!ReportStrictErrorOrWarning(cx, obj, id, strict, &result))
|
||||
// goto failure;
|
||||
masm.loadJSContext(argJSContextReg);
|
||||
masm.computeEffectiveAddress(
|
||||
Address(StackPointer, FrameLayout::offsetOfId()),
|
||||
argIdReg);
|
||||
masm.move32(Imm32(strict), argStrictReg);
|
||||
masm.computeEffectiveAddress(
|
||||
Address(StackPointer, FrameLayout::offsetOfObjectOpResult()),
|
||||
argResultReg);
|
||||
masm.setupUnalignedABICall(5, scratchReg);
|
||||
masm.passABIArg(argJSContextReg);
|
||||
masm.passABIArg(argObjReg);
|
||||
masm.passABIArg(argIdReg);
|
||||
masm.passABIArg(argStrictReg);
|
||||
masm.passABIArg(argResultReg);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, ReportStrictErrorOrWarning));
|
||||
masm.branchIfFalseBool(ReturnReg, failure);
|
||||
|
||||
// }
|
||||
masm.bind(&noStrictError);
|
||||
}
|
||||
|
||||
static bool
|
||||
EmitCallProxySet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& attacher,
|
||||
HandleId propId, RegisterSet liveRegs, Register object,
|
||||
@@ -2125,18 +2183,23 @@ EmitCallProxySet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
|
||||
{
|
||||
MacroAssembler::AfterICSaveLive aic = masm.icSaveLive(liveRegs);
|
||||
|
||||
// Remaining registers should be free, but we need to use |object| still
|
||||
// so leave it alone.
|
||||
// Remaining registers should be free, but we still need to use |object| so
|
||||
// leave it alone.
|
||||
//
|
||||
// WARNING: We do not take() the register used by |value|, if any, so
|
||||
// regSet is going to re-allocate it. Hence the emitted code must not touch
|
||||
// any of the registers allocated from regSet until after the last use of
|
||||
// |value|. (We can't afford to take it, either, because x86.)
|
||||
RegisterSet regSet(RegisterSet::All());
|
||||
regSet.take(AnyRegister(object));
|
||||
|
||||
// Proxy::set(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
// bool strict, MutableHandleValue vp)
|
||||
// MutableHandleValue vp, ObjectOpResult &result)
|
||||
Register argJSContextReg = regSet.takeGeneral();
|
||||
Register argProxyReg = regSet.takeGeneral();
|
||||
Register argIdReg = regSet.takeGeneral();
|
||||
Register argVpReg = regSet.takeGeneral();
|
||||
Register argStrictReg = regSet.takeGeneral();
|
||||
Register argResultReg = regSet.takeGeneral();
|
||||
|
||||
Register scratch = regSet.takeGeneral();
|
||||
|
||||
@@ -2156,8 +2219,11 @@ EmitCallProxySet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
|
||||
masm.Push(object);
|
||||
masm.movePtr(StackPointer, argProxyReg);
|
||||
|
||||
// Allocate result out-param.
|
||||
PushObjectOpResult(masm);
|
||||
masm.movePtr(StackPointer, argResultReg);
|
||||
|
||||
masm.loadJSContext(argJSContextReg);
|
||||
masm.move32(Imm32(strict? 1 : 0), argStrictReg);
|
||||
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
@@ -2169,13 +2235,19 @@ EmitCallProxySet(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& at
|
||||
masm.passABIArg(argProxyReg);
|
||||
masm.passABIArg(argProxyReg);
|
||||
masm.passABIArg(argIdReg);
|
||||
masm.passABIArg(argStrictReg);
|
||||
masm.passABIArg(argVpReg);
|
||||
masm.passABIArg(argResultReg);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, Proxy::set));
|
||||
|
||||
// Test for failure.
|
||||
// Test for error.
|
||||
masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel());
|
||||
|
||||
// Test for strict failure. We emit the check even in non-strict mode in
|
||||
// order to pick up the warning if extraWarnings is enabled.
|
||||
EmitObjectOpResultCheck<IonOOLProxyExitFrameLayout>(masm, masm.exceptionLabel(), strict,
|
||||
scratch, argJSContextReg, argProxyReg,
|
||||
argIdReg, argVpReg, argResultReg);
|
||||
|
||||
// masm.leaveExitFrame & pop locals
|
||||
masm.adjustStack(IonOOLProxyExitFrameLayout::Size());
|
||||
|
||||
@@ -2386,24 +2458,28 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm,
|
||||
Register argVpReg = regSet.takeGeneral();
|
||||
Register argObjReg = regSet.takeGeneral();
|
||||
Register argIdReg = regSet.takeGeneral();
|
||||
Register argStrictReg = regSet.takeGeneral();
|
||||
|
||||
attacher.pushStubCodePointer(masm);
|
||||
Register argResultReg = regSet.takeGeneral();
|
||||
|
||||
StrictPropertyOp target = shape->setterOp();
|
||||
MOZ_ASSERT(target);
|
||||
// JSStrictPropertyOp: bool fn(JSContext* cx, HandleObject obj,
|
||||
// HandleId id, bool strict, MutableHandleValue vp);
|
||||
// HandleId id, MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
// Push args on stack first so we can take pointers to make handles.
|
||||
// First, allocate an ObjectOpResult on the stack. We push this before
|
||||
// the stubCode pointer in order to match the layout of
|
||||
// IonOOLSetterOpExitFrameLayout.
|
||||
PushObjectOpResult(masm);
|
||||
masm.movePtr(StackPointer, argResultReg);
|
||||
|
||||
attacher.pushStubCodePointer(masm);
|
||||
|
||||
// Push args on stack so we can take pointers to make handles.
|
||||
if (value.constant())
|
||||
masm.Push(value.value());
|
||||
else
|
||||
masm.Push(value.reg());
|
||||
masm.movePtr(StackPointer, argVpReg);
|
||||
|
||||
masm.move32(Imm32(strict ? 1 : 0), argStrictReg);
|
||||
|
||||
// push canonical jsid from shape instead of propertyname.
|
||||
masm.Push(shape->propid(), argIdReg);
|
||||
masm.movePtr(StackPointer, argIdReg);
|
||||
@@ -2415,22 +2491,27 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm,
|
||||
|
||||
if (!masm.icBuildOOLFakeExitFrame(returnAddr, aic))
|
||||
return false;
|
||||
masm.enterFakeExitFrame(IonOOLPropertyOpExitFrameLayout::Token());
|
||||
masm.enterFakeExitFrame(IonOOLSetterOpExitFrameLayout::Token());
|
||||
|
||||
// Make the call.
|
||||
masm.setupUnalignedABICall(5, scratchReg);
|
||||
masm.passABIArg(argJSContextReg);
|
||||
masm.passABIArg(argObjReg);
|
||||
masm.passABIArg(argIdReg);
|
||||
masm.passABIArg(argStrictReg);
|
||||
masm.passABIArg(argVpReg);
|
||||
masm.passABIArg(argResultReg);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, target));
|
||||
|
||||
// Test for failure.
|
||||
// Test for error.
|
||||
masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel());
|
||||
|
||||
// Test for failure.
|
||||
EmitObjectOpResultCheck<IonOOLSetterOpExitFrameLayout>(masm, failure, strict, scratchReg,
|
||||
argJSContextReg, argObjReg,
|
||||
argIdReg, argVpReg, argResultReg);
|
||||
|
||||
// masm.leaveExitFrame & pop locals.
|
||||
masm.adjustStack(IonOOLPropertyOpExitFrameLayout::Size());
|
||||
masm.adjustStack(IonOOLSetterOpExitFrameLayout::Size());
|
||||
} else {
|
||||
MOZ_ASSERT(IsCacheableSetPropCallScripted(obj, holder, shape));
|
||||
|
||||
|
||||
@@ -1316,7 +1316,7 @@ MarkJitExitFrame(JSTracer* trc, const JitFrameIterator& frame)
|
||||
}
|
||||
|
||||
if (frame.isExitFrameLayout<IonOOLNativeExitFrameLayout>()) {
|
||||
IonOOLNativeExitFrameLayout* oolnative =
|
||||
IonOOLNativeExitFrameLayout *oolnative =
|
||||
frame.exitFrame()->as<IonOOLNativeExitFrameLayout>();
|
||||
gc::MarkJitCodeRoot(trc, oolnative->stubCode(), "ion-ool-native-code");
|
||||
gc::MarkValueRoot(trc, oolnative->vp(), "iol-ool-native-vp");
|
||||
@@ -1325,9 +1325,16 @@ MarkJitExitFrame(JSTracer* trc, const JitFrameIterator& frame)
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame.isExitFrameLayout<IonOOLPropertyOpExitFrameLayout>()) {
|
||||
IonOOLPropertyOpExitFrameLayout* oolgetter =
|
||||
frame.exitFrame()->as<IonOOLPropertyOpExitFrameLayout>();
|
||||
if (frame.isExitFrameLayout<IonOOLPropertyOpExitFrameLayout>() ||
|
||||
frame.isExitFrameLayout<IonOOLSetterOpExitFrameLayout>())
|
||||
{
|
||||
// A SetterOp frame is a different size, but that's the only relevant
|
||||
// difference between the two. The fields that need marking are all in
|
||||
// the common base class.
|
||||
IonOOLPropertyOpExitFrameLayout *oolgetter =
|
||||
frame.isExitFrameLayout<IonOOLPropertyOpExitFrameLayout>()
|
||||
? frame.exitFrame()->as<IonOOLPropertyOpExitFrameLayout>()
|
||||
: frame.exitFrame()->as<IonOOLSetterOpExitFrameLayout>();
|
||||
gc::MarkJitCodeRoot(trc, oolgetter->stubCode(), "ion-ool-property-op-code");
|
||||
gc::MarkValueRoot(trc, oolgetter->vp(), "ion-ool-property-op-vp");
|
||||
gc::MarkIdRoot(trc, oolgetter->id(), "ion-ool-property-op-id");
|
||||
@@ -1335,6 +1342,7 @@ MarkJitExitFrame(JSTracer* trc, const JitFrameIterator& frame)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (frame.isExitFrameLayout<IonOOLProxyExitFrameLayout>()) {
|
||||
IonOOLProxyExitFrameLayout* oolproxy = frame.exitFrame()->as<IonOOLProxyExitFrameLayout>();
|
||||
gc::MarkJitCodeRoot(trc, oolproxy->stubCode(), "ion-ool-proxy-code");
|
||||
|
||||
+36
-3
@@ -494,7 +494,8 @@ enum ExitFrameTokenValues
|
||||
IonDOMMethodExitFrameLayoutToken = 0x3,
|
||||
IonOOLNativeExitFrameLayoutToken = 0x4,
|
||||
IonOOLPropertyOpExitFrameLayoutToken = 0x5,
|
||||
IonOOLProxyExitFrameLayoutToken = 0x6,
|
||||
IonOOLSetterOpExitFrameLayoutToken = 0x6,
|
||||
IonOOLProxyExitFrameLayoutToken = 0x7,
|
||||
LazyLinkExitFrameLayoutToken = 0xFE,
|
||||
ExitFrameLayoutBareToken = 0xFF
|
||||
};
|
||||
@@ -628,7 +629,7 @@ class IonOOLNativeExitFrameLayout
|
||||
|
||||
class IonOOLPropertyOpExitFrameLayout
|
||||
{
|
||||
protected: // only to silence a clang warning about unused private fields
|
||||
protected:
|
||||
ExitFooterFrame footer_;
|
||||
ExitFrameLayout exit_;
|
||||
|
||||
@@ -653,6 +654,10 @@ class IonOOLPropertyOpExitFrameLayout
|
||||
return sizeof(IonOOLPropertyOpExitFrameLayout);
|
||||
}
|
||||
|
||||
static size_t offsetOfId() {
|
||||
return offsetof(IonOOLPropertyOpExitFrameLayout, id_);
|
||||
}
|
||||
|
||||
static size_t offsetOfResult() {
|
||||
return offsetof(IonOOLPropertyOpExitFrameLayout, vp0_);
|
||||
}
|
||||
@@ -671,16 +676,36 @@ class IonOOLPropertyOpExitFrameLayout
|
||||
}
|
||||
};
|
||||
|
||||
class IonOOLSetterOpExitFrameLayout : public IonOOLPropertyOpExitFrameLayout
|
||||
{
|
||||
protected: // only to silence a clang warning about unused private fields
|
||||
JS::ObjectOpResult result_;
|
||||
|
||||
public:
|
||||
static JitCode *Token() { return (JitCode *)IonOOLSetterOpExitFrameLayoutToken; }
|
||||
|
||||
static size_t offsetOfObjectOpResult() {
|
||||
return offsetof(IonOOLSetterOpExitFrameLayout, result_);
|
||||
}
|
||||
|
||||
static size_t Size() {
|
||||
return sizeof(IonOOLSetterOpExitFrameLayout);
|
||||
}
|
||||
};
|
||||
|
||||
// Proxy::get(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
// MutableHandleValue vp)
|
||||
// Proxy::set(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
// bool strict, MutableHandleValue vp)
|
||||
// MutableHandleValue vp, ObjectOpResult &result)
|
||||
class IonOOLProxyExitFrameLayout
|
||||
{
|
||||
protected: // only to silence a clang warning about unused private fields
|
||||
ExitFooterFrame footer_;
|
||||
ExitFrameLayout exit_;
|
||||
|
||||
// result out-parameter (unused for Proxy::get)
|
||||
JS::ObjectOpResult result_;
|
||||
|
||||
// The proxy object.
|
||||
JSObject* proxy_;
|
||||
|
||||
@@ -709,6 +734,14 @@ class IonOOLProxyExitFrameLayout
|
||||
return offsetof(IonOOLProxyExitFrameLayout, vp0_);
|
||||
}
|
||||
|
||||
static size_t offsetOfId() {
|
||||
return offsetof(IonOOLProxyExitFrameLayout, id_);
|
||||
}
|
||||
|
||||
static size_t offsetOfObjectOpResult() {
|
||||
return offsetof(IonOOLProxyExitFrameLayout, result_);
|
||||
}
|
||||
|
||||
inline JitCode** stubCode() {
|
||||
return &stubCode_;
|
||||
}
|
||||
|
||||
+16
-10
@@ -448,18 +448,24 @@ SetProperty(JSContext* cx, HandleObject obj, HandlePropertyName name, HandleValu
|
||||
return true;
|
||||
}
|
||||
|
||||
ObjectOpResult result;
|
||||
if (MOZ_LIKELY(!obj->getOps()->setProperty)) {
|
||||
return NativeSetProperty(
|
||||
cx, obj.as<NativeObject>(), obj.as<NativeObject>(), id,
|
||||
(op == JSOP_SETNAME || op == JSOP_STRICTSETNAME ||
|
||||
op == JSOP_SETGNAME || op == JSOP_STRICTSETGNAME)
|
||||
? Unqualified
|
||||
: Qualified,
|
||||
&v,
|
||||
strict);
|
||||
if (!NativeSetProperty(
|
||||
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, obj, id, &v, result))
|
||||
return false;
|
||||
}
|
||||
|
||||
return SetProperty(cx, obj, obj, id, &v, strict);
|
||||
return result.checkStrictErrorOrWarning(cx, obj, id, strict);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
+5
-1
@@ -50,6 +50,7 @@ MSG_DEF(JSMSG_BAD_SORT_ARG, 0, JSEXN_TYPEERR, "invalid Array.prototyp
|
||||
MSG_DEF(JSMSG_CANT_WATCH, 1, JSEXN_TYPEERR, "can't watch non-native objects of class {0}")
|
||||
MSG_DEF(JSMSG_READ_ONLY, 1, JSEXN_TYPEERR, "{0} is read-only")
|
||||
MSG_DEF(JSMSG_CANT_DELETE, 1, JSEXN_TYPEERR, "property {0} is non-configurable and can't be deleted")
|
||||
MSG_DEF(JSMSG_CANT_TRUNCATE_ARRAY, 0, JSEXN_TYPEERR, "can't delete non-configurable array element")
|
||||
MSG_DEF(JSMSG_NOT_FUNCTION, 1, JSEXN_TYPEERR, "{0} is not a function")
|
||||
MSG_DEF(JSMSG_NOT_CONSTRUCTOR, 1, JSEXN_TYPEERR, "{0} is not a constructor")
|
||||
MSG_DEF(JSMSG_CANT_CONVERT, 1, JSEXN_ERR, "can't convert {0} to an integer")
|
||||
@@ -83,7 +84,7 @@ MSG_DEF(JSMSG_MISSING_FUN_ARG, 2, JSEXN_TYPEERR, "missing argument {0} w
|
||||
MSG_DEF(JSMSG_NOT_NONNULL_OBJECT, 1, JSEXN_TYPEERR, "{0} is not a non-null 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}'")
|
||||
MSG_DEF(JSMSG_CANT_REDEFINE_PROP, 1, JSEXN_TYPEERR, "can't redefine non-configurable property {0}")
|
||||
MSG_DEF(JSMSG_CANT_APPEND_TO_ARRAY, 0, JSEXN_TYPEERR, "can't add elements past the end of an array if its length property is unwritable")
|
||||
MSG_DEF(JSMSG_CANT_REDEFINE_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't redefine array length")
|
||||
MSG_DEF(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH, 0, JSEXN_TYPEERR, "can't define array index property past the end of an array with non-writable length")
|
||||
@@ -464,3 +465,6 @@ MSG_DEF(JSMSG_SYMBOL_TO_NUMBER, 0, JSEXN_TYPEERR, "can't convert symbol t
|
||||
MSG_DEF(JSMSG_ATOMICS_BAD_ARRAY, 0, JSEXN_TYPEERR, "invalid array type for the operation")
|
||||
MSG_DEF(JSMSG_ATOMICS_TOO_LONG, 0, JSEXN_RANGEERR, "timeout value too large")
|
||||
MSG_DEF(JSMSG_ATOMICS_WAIT_NOT_ALLOWED, 0, JSEXN_ERR, "waiting is not allowed on this thread")
|
||||
|
||||
// XPConnect wrappers
|
||||
MSG_DEF(JSMSG_CANT_SET_INTERPOSED, 1, JSEXN_TYPEERR, "unable to set interposed data property '{0}'")
|
||||
|
||||
@@ -45,11 +45,14 @@ BEGIN_TEST(testForwardSetProperty)
|
||||
|
||||
// Non-strict setter
|
||||
|
||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, v3, true, setval));
|
||||
ObjectOpResult result;
|
||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, v3, result));
|
||||
CHECK(result);
|
||||
|
||||
EXEC("assertEq(foundValue, obj3, 'wrong receiver passed to setter');");
|
||||
|
||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, true, setval));
|
||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, setval, result));
|
||||
CHECK(result);
|
||||
|
||||
EXEC("assertEq(typeof foundValue === 'object', true, \n"
|
||||
" 'passing 42 as receiver to non-strict setter ' + \n"
|
||||
@@ -69,12 +72,13 @@ BEGIN_TEST(testForwardSetProperty)
|
||||
"obj1;",
|
||||
&v1);
|
||||
|
||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, v3, true, setval));
|
||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, v3, result));
|
||||
CHECK(result);
|
||||
|
||||
EXEC("assertEq(foundValue, obj3, 'wrong receiver passed to strict setter');");
|
||||
|
||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, true, setval));
|
||||
|
||||
CHECK(JS_ForwardSetPropertyTo(cx, obj2, prop, setval, setval, result));
|
||||
CHECK(result);
|
||||
|
||||
JS::RootedValue strictSetSupported(cx);
|
||||
EVAL("var strictSetSupported = false; \n"
|
||||
|
||||
@@ -28,13 +28,13 @@ class CustomProxyHandler : public DirectProxyHandler {
|
||||
}
|
||||
|
||||
bool set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, bool strict, MutableHandleValue vp) const override
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const MOZ_OVERRIDE
|
||||
{
|
||||
Rooted<JSPropertyDescriptor> desc(cx);
|
||||
if (!DirectProxyHandler::getPropertyDescriptor(cx, proxy, id, &desc))
|
||||
return false;
|
||||
return SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id, &desc,
|
||||
desc.object() == proxy, strict, vp);
|
||||
desc.object() == proxy, vp, result);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
+129
-11
@@ -129,6 +129,70 @@ JS::CallArgs::requireAtLeast(JSContext* cx, const char* fnname, unsigned require
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ErrorTakesIdArgument(unsigned msg)
|
||||
{
|
||||
MOZ_ASSERT(msg < JSErr_Limit);
|
||||
unsigned argCount = js_ErrorFormatString[msg].argCount;
|
||||
MOZ_ASSERT(argCount <= 1);
|
||||
return argCount == 1;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::ObjectOpResult::reportStrictErrorOrWarning(JSContext *cx, HandleObject obj, HandleId id,
|
||||
bool strict)
|
||||
{
|
||||
static_assert(unsigned(OkCode) == unsigned(JSMSG_NOT_AN_ERROR),
|
||||
"unsigned value of OkCode must not be an error code");
|
||||
MOZ_ASSERT(code_ != Uninitialized);
|
||||
MOZ_ASSERT(!ok());
|
||||
|
||||
unsigned flags = strict ? JSREPORT_ERROR : (JSREPORT_WARNING | JSREPORT_STRICT);
|
||||
if (code_ == JSMSG_OBJECT_NOT_EXTENSIBLE) {
|
||||
RootedValue val(cx, ObjectValue(*obj));
|
||||
return ReportValueErrorFlags(cx, flags, code_, JSDVG_IGNORE_STACK, val,
|
||||
NullPtr(), nullptr, nullptr);
|
||||
}
|
||||
if (ErrorTakesIdArgument(code_)) {
|
||||
RootedValue idv(cx, IdToValue(id));
|
||||
RootedString str(cx, ValueToSource(cx, idv));
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
JSAutoByteString propName(cx, str);
|
||||
if (!propName)
|
||||
return false;
|
||||
|
||||
return JS_ReportErrorFlagsAndNumber(cx, flags, GetErrorMessage, nullptr, code_,
|
||||
propName.ptr());
|
||||
}
|
||||
return JS_ReportErrorFlagsAndNumber(cx, flags, GetErrorMessage, nullptr, code_);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::ObjectOpResult::failCantRedefineProp()
|
||||
{
|
||||
return fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::ObjectOpResult::failReadOnly()
|
||||
{
|
||||
return fail(JSMSG_READ_ONLY);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::ObjectOpResult::failGetterOnly()
|
||||
{
|
||||
return fail(JSMSG_GETTER_ONLY);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS::ObjectOpResult::failCantSetInterposed()
|
||||
{
|
||||
return fail(JSMSG_CANT_SET_INTERPOSED);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(int64_t)
|
||||
JS_Now()
|
||||
{
|
||||
@@ -1787,9 +1851,10 @@ JS_PropertyStub(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_StrictPropertyStub(JSContext* cx, HandleObject obj, HandleId id, bool strict, MutableHandleValue vp)
|
||||
JS_StrictPropertyStub(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject*)
|
||||
@@ -2386,6 +2451,33 @@ JS_DefinePropertyById(JSContext* cx, HandleObject obj, HandleId id, double value
|
||||
NativeOpWrapper(getter), NativeOpWrapper(setter), attrs, 0);
|
||||
}
|
||||
|
||||
static bool
|
||||
DefinePropertyByDescriptor(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc, ObjectOpResult &result)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, id, desc);
|
||||
return DefineProperty(cx, obj, id, desc.value(), desc.getter(), desc.setter(),
|
||||
desc.attributes(), result);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc, ObjectOpResult &result)
|
||||
{
|
||||
return DefinePropertyByDescriptor(cx, obj, id, desc, result);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc)
|
||||
{
|
||||
ObjectOpResult result;
|
||||
return DefinePropertyByDescriptor(cx, obj, id, desc, result) &&
|
||||
result.checkStrict(cx, obj, id);
|
||||
}
|
||||
|
||||
static bool
|
||||
DefineElement(JSContext* cx, HandleObject obj, uint32_t index, HandleValue value,
|
||||
unsigned attrs, Native getter, Native setter)
|
||||
@@ -2642,6 +2734,31 @@ JS_DefineUCProperty(JSContext* cx, HandleObject obj, const char16_t* name, size_
|
||||
getter, setter, attrs, 0);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
if (!atom)
|
||||
return false;
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
return DefinePropertyByDescriptor(cx, obj, id, desc, result);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
|
||||
Handle<JSPropertyDescriptor> desc)
|
||||
{
|
||||
JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
if (!atom)
|
||||
return false;
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
ObjectOpResult result;
|
||||
return DefinePropertyByDescriptor(cx, obj, id, desc, result) &&
|
||||
result.checkStrict(cx, obj, id);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject*)
|
||||
JS_DefineObject(JSContext* cx, HandleObject obj, const char* name, const JSClass* jsclasp,
|
||||
unsigned attrs)
|
||||
@@ -2884,25 +3001,25 @@ JS_SetPropertyById(JSContext* cx, HandleObject obj, HandleId id, HandleValue v)
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, id);
|
||||
|
||||
return SetProperty(cx, obj, obj, id, &value, false);
|
||||
ObjectOpResult ignored;
|
||||
return SetProperty(cx, obj, obj, id, &value, ignored);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_ForwardSetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue onBehalfOf,
|
||||
bool strict, JS::HandleValue v)
|
||||
JS_ForwardSetPropertyTo(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
HandleValue receiver, ObjectOpResult &result)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, id);
|
||||
assertSameCompartment(cx, onBehalfOf);
|
||||
assertSameCompartment(cx, obj, id, receiver);
|
||||
|
||||
// XXX Bug 603201 will eliminate this ToObject.
|
||||
RootedObject receiver(cx, ToObject(cx, onBehalfOf));
|
||||
if (!receiver)
|
||||
RootedObject receiverObj(cx, ToObject(cx, receiver));
|
||||
if (!receiverObj)
|
||||
return false;
|
||||
|
||||
RootedValue value(cx, v);
|
||||
return SetProperty(cx, obj, receiver, id, &value, strict);
|
||||
return SetProperty(cx, obj, receiverObj, id, &value, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -2912,7 +3029,8 @@ SetElement(JSContext* cx, HandleObject obj, uint32_t index, MutableHandleValue v
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, vp);
|
||||
|
||||
return SetElement(cx, obj, obj, index, vp, false);
|
||||
ObjectOpResult ignored;
|
||||
return SetElement(cx, obj, obj, index, vp, ignored);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
||||
+116
-90
@@ -2036,8 +2036,8 @@ JS_PropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::MutableHandleValue vp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_StrictPropertyStub(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool strict,
|
||||
JS::MutableHandleValue vp);
|
||||
JS_StrictPropertyStub(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
|
||||
template<typename T>
|
||||
struct JSConstScalarSpec {
|
||||
@@ -2555,92 +2555,7 @@ JS_PreventExtensions(JSContext* cx, JS::HandleObject obj, bool* succeeded);
|
||||
extern JS_PUBLIC_API(JSObject*)
|
||||
JS_New(JSContext* cx, JS::HandleObject ctor, const JS::HandleValueArray& args);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject*)
|
||||
JS_DefineObject(JSContext* cx, JS::HandleObject obj, const char* name,
|
||||
const JSClass* clasp = nullptr, unsigned attrs = 0);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineConstDoubles(JSContext* cx, JS::HandleObject obj, const JSConstDoubleSpec* cds);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineConstIntegers(JSContext* cx, JS::HandleObject obj, const JSConstIntegerSpec* cis);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperties(JSContext* cx, JS::HandleObject obj, const JSPropertySpec* ps);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleValue value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleObject value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, JS::HandleString value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, int32_t value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, uint32_t value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperty(JSContext* cx, JS::HandleObject obj, const char* name, double value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleString value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, int32_t value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, uint32_t value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, double value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnProperty(JSContext* cx, JS::HandleObject obj, const char* name,
|
||||
bool* foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
|
||||
bool* foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_HasProperty(JSContext* cx, JS::HandleObject obj, const char* name, bool* foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_HasPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
|
||||
/*** Property descriptors ************************************************************************/
|
||||
|
||||
struct JSPropertyDescriptor {
|
||||
JSObject* obj;
|
||||
@@ -2829,6 +2744,108 @@ ParsePropertyDescriptorObject(JSContext* cx,
|
||||
|
||||
} // namespace JS
|
||||
|
||||
/*** [[DefineOwnProperty]] and variations ********************************************************/
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleValue value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleObject value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleString value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, int32_t value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, uint32_t value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, double value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleString value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, int32_t value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, uint32_t value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, double value,
|
||||
unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefinePropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_DefineObject(JSContext *cx, JS::HandleObject obj, const char *name,
|
||||
const JSClass *clasp = nullptr, unsigned attrs = 0);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineConstDoubles(JSContext *cx, JS::HandleObject obj, const JSConstDoubleSpec *cds);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineConstIntegers(JSContext *cx, JS::HandleObject obj, const JSConstIntegerSpec *cis);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineProperties(JSContext *cx, JS::HandleObject obj, const JSPropertySpec *ps);
|
||||
|
||||
|
||||
/* * */
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnProperty(JSContext *cx, JS::HandleObject obj, const char *name,
|
||||
bool *foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
bool *foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_HasProperty(JSContext *cx, JS::HandleObject obj, const char *name, bool *foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_HasPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *foundp);
|
||||
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_GetOwnPropertyDescriptorById(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
@@ -2867,8 +2884,8 @@ extern JS_PUBLIC_API(bool)
|
||||
JS_SetPropertyById(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_ForwardSetPropertyTo(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue onBehalfOf,
|
||||
bool strict, JS::HandleValue vp);
|
||||
JS_ForwardSetPropertyTo(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue v,
|
||||
JS::HandleValue receiver, JS::ObjectOpResult &result);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DeleteProperty(JSContext* cx, JS::HandleObject obj, const char* name);
|
||||
@@ -2912,6 +2929,15 @@ JS_DefineUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name, s
|
||||
double value, unsigned attrs,
|
||||
JSNative getter = nullptr, JSNative setter = nullptr);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
|
||||
JS::Handle<JSPropertyDescriptor> desc);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnUCProperty(JSContext* cx, JS::HandleObject obj, const char16_t* name,
|
||||
size_t namelen, bool* foundp);
|
||||
|
||||
+22
-62
@@ -363,7 +363,7 @@ SetArrayElement(JSContext* cx, HandleObject obj, double index, HandleValue v)
|
||||
return false;
|
||||
|
||||
RootedValue tmp(cx, v);
|
||||
return SetProperty(cx, obj, obj, id, &tmp, true);
|
||||
return SetProperty(cx, obj, obj, id, &tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -433,7 +433,7 @@ bool
|
||||
js::SetLengthProperty(JSContext* cx, HandleObject obj, double length)
|
||||
{
|
||||
RootedValue v(cx, NumberValue(length));
|
||||
return SetProperty(cx, obj, obj, cx->names().length, &v, true);
|
||||
return SetProperty(cx, obj, obj, cx->names().length, &v);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -459,7 +459,8 @@ array_length_getter(JSContext* cx, HandleObject obj_, HandleId id, MutableHandle
|
||||
}
|
||||
|
||||
static bool
|
||||
array_length_setter(JSContext* cx, HandleObject obj, HandleId id, bool strict, MutableHandleValue vp)
|
||||
array_length_setter(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
if (!obj->is<ArrayObject>()) {
|
||||
// This array .length property was found on the prototype
|
||||
@@ -467,13 +468,14 @@ array_length_setter(JSContext* cx, HandleObject obj, HandleId id, bool strict, M
|
||||
// we're here, do an impression of SetPropertyByDefining.
|
||||
const Class* clasp = obj->getClass();
|
||||
return DefineProperty(cx, obj, cx->names().length, vp,
|
||||
clasp->getProperty, clasp->setProperty, JSPROP_ENUMERATE);
|
||||
clasp->getProperty, clasp->setProperty, JSPROP_ENUMERATE, result);
|
||||
}
|
||||
|
||||
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
|
||||
MOZ_ASSERT(arr->lengthIsWritable(),
|
||||
"setter shouldn't be called if property is non-writable");
|
||||
return ArraySetLength(cx, arr, id, JSPROP_PERMANENT, vp, strict);
|
||||
|
||||
return ArraySetLength(cx, arr, id, JSPROP_PERMANENT, vp, result);
|
||||
}
|
||||
|
||||
struct ReverseIndexComparator
|
||||
@@ -506,7 +508,7 @@ js::CanonicalizeArrayLengthValue(JSContext* cx, HandleValue v, uint32_t* newLen)
|
||||
/* ES6 20130308 draft 8.4.2.4 ArraySetLength */
|
||||
bool
|
||||
js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
|
||||
unsigned attrs, HandleValue value, bool setterIsStrict)
|
||||
unsigned attrs, HandleValue value, ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(id == NameToId(cx->names().length));
|
||||
|
||||
@@ -529,11 +531,8 @@ js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
|
||||
// OrdinaryDefineOwnProperty in ES6, the default [[DefineOwnProperty]] in
|
||||
// ES5 -- but we reimplement all the conflict-detection bits ourselves here
|
||||
// so that we can use a customized length representation.)
|
||||
if (!(attrs & JSPROP_PERMANENT) || (attrs & JSPROP_ENUMERATE)) {
|
||||
if (!setterIsStrict)
|
||||
return true;
|
||||
return Throw(cx, id, JSMSG_CANT_REDEFINE_PROP);
|
||||
}
|
||||
if (!(attrs & JSPROP_PERMANENT) || (attrs & JSPROP_ENUMERATE))
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
/* Steps 6-7. */
|
||||
bool lengthIsWritable = arr->lengthIsWritable();
|
||||
@@ -550,14 +549,9 @@ js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
|
||||
/* Steps 8-9 for arrays with non-writable length. */
|
||||
if (!lengthIsWritable) {
|
||||
if (newLen == oldLen)
|
||||
return true;
|
||||
return result.succeed();
|
||||
|
||||
if (setterIsStrict) {
|
||||
return JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
|
||||
JSMSG_CANT_REDEFINE_ARRAY_LENGTH);
|
||||
}
|
||||
|
||||
return JSObject::reportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_ARRAY_LENGTH);
|
||||
}
|
||||
|
||||
/* Step 8. */
|
||||
@@ -738,53 +732,20 @@ js::ArraySetLength(JSContext* cx, Handle<ArrayObject*> arr, HandleId id,
|
||||
}
|
||||
}
|
||||
|
||||
if (setterIsStrict && !succeeded) {
|
||||
RootedId elementId(cx);
|
||||
if (!IndexToId(cx, newLen - 1, &elementId))
|
||||
return false;
|
||||
return arr->reportNotConfigurable(cx, elementId);
|
||||
}
|
||||
if (!succeeded)
|
||||
return result.fail(JSMSG_CANT_TRUNCATE_ARRAY);
|
||||
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
bool
|
||||
js::WouldDefinePastNonwritableLength(ExclusiveContext* cx,
|
||||
HandleObject obj, uint32_t index, bool strict,
|
||||
bool* definesPast)
|
||||
js::WouldDefinePastNonwritableLength(HandleNativeObject obj, uint32_t index)
|
||||
{
|
||||
if (!obj->is<ArrayObject>()) {
|
||||
*definesPast = false;
|
||||
return true;
|
||||
}
|
||||
if (!obj->is<ArrayObject>())
|
||||
return false;
|
||||
|
||||
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
|
||||
uint32_t length = arr->length();
|
||||
if (index < length) {
|
||||
*definesPast = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (arr->lengthIsWritable()) {
|
||||
*definesPast = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
*definesPast = true;
|
||||
|
||||
// Error in strict mode code or warn with strict option.
|
||||
unsigned flags = strict ? JSREPORT_ERROR : (JSREPORT_STRICT | JSREPORT_WARNING);
|
||||
if (!cx->isJSContext())
|
||||
return true;
|
||||
|
||||
JSContext* ncx = cx->asJSContext();
|
||||
|
||||
if (!strict && !ncx->compartment()->options().extraWarnings(ncx))
|
||||
return true;
|
||||
|
||||
// XXX include the index and maybe array length in the error message
|
||||
return JS_ReportErrorFlagsAndNumber(ncx, flags, GetErrorMessage, nullptr,
|
||||
JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH);
|
||||
ArrayObject *arr = &obj->as<ArrayObject>();
|
||||
return !arr->lengthIsWritable() && index >= arr->length();
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -1308,7 +1269,7 @@ InitArrayElements(JSContext* cx, HandleObject obj, uint32_t start, uint32_t coun
|
||||
value = *vector++;
|
||||
indexv = DoubleValue(index);
|
||||
if (!ValueToId<CanGC>(cx, indexv, &id) ||
|
||||
!SetProperty(cx, obj, obj, id, &value, true))
|
||||
!SetProperty(cx, obj, obj, id, &value))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -3112,8 +3073,7 @@ array_of(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
// Steps 9-10.
|
||||
RootedValue v(cx, NumberValue(args.length()));
|
||||
if (!SetProperty(cx, obj, obj, cx->names().length, &v, true))
|
||||
if (!SetLengthProperty(cx, obj, args.length()))
|
||||
return false;
|
||||
|
||||
// Step 11.
|
||||
|
||||
+1
-3
@@ -101,9 +101,7 @@ NewDenseCopyOnWriteArray(JSContext* cx, HandleArrayObject templateObject, gc::In
|
||||
* increase the length of the array.
|
||||
*/
|
||||
extern bool
|
||||
WouldDefinePastNonwritableLength(ExclusiveContext* cx,
|
||||
HandleObject obj, uint32_t index, bool strict,
|
||||
bool* definesPast);
|
||||
WouldDefinePastNonwritableLength(HandleNativeObject obj, uint32_t index);
|
||||
|
||||
/*
|
||||
* Canonicalize |vp| to a uint32_t value potentially suitable for use as an
|
||||
|
||||
+18
-7
@@ -132,6 +132,15 @@ class CompartmentChecker
|
||||
void check(InterpreterFrame* fp);
|
||||
void check(AbstractFramePtr frame);
|
||||
void check(SavedStacks* stacks);
|
||||
|
||||
void check(Handle<JSPropertyDescriptor> desc) {
|
||||
check(desc.object());
|
||||
if (desc.hasGetterObject())
|
||||
check(desc.getterObject());
|
||||
if (desc.hasSetterObject())
|
||||
check(desc.setterObject());
|
||||
check(desc.value());
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -307,12 +316,12 @@ CallJSPropertyOp(JSContext* cx, PropertyOp op, HandleObject receiver, HandleId i
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
CallJSPropertyOpSetter(JSContext* cx, StrictPropertyOp op, HandleObject obj, HandleId id,
|
||||
bool strict, MutableHandleValue vp)
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
assertSameCompartment(cx, obj, id, vp);
|
||||
return op(cx, obj, id, strict, vp);
|
||||
return op(cx, obj, id, vp, result);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
@@ -330,20 +339,22 @@ CallJSDeletePropertyOp(JSContext* cx, JSDeletePropertyOp op, HandleObject receiv
|
||||
|
||||
inline bool
|
||||
CallSetter(JSContext* cx, HandleObject obj, HandleId id, StrictPropertyOp op, unsigned attrs,
|
||||
bool strict, MutableHandleValue vp)
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
if (attrs & JSPROP_SETTER) {
|
||||
RootedValue opv(cx, CastAsObjectJsval(op));
|
||||
return InvokeGetterOrSetter(cx, obj, opv, 1, vp.address(), vp);
|
||||
if (!InvokeGetterOrSetter(cx, obj, opv, 1, vp.address(), vp))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
if (attrs & JSPROP_GETTER)
|
||||
return ReportGetterOnlyAssignment(cx, strict);
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
|
||||
if (!op)
|
||||
return true;
|
||||
return result.succeed();
|
||||
|
||||
return CallJSPropertyOpSetter(cx, op, obj, id, strict, vp);
|
||||
return CallJSPropertyOpSetter(cx, op, obj, id, vp, result);
|
||||
}
|
||||
|
||||
inline uintptr_t
|
||||
|
||||
@@ -1169,7 +1169,7 @@ js::GetObjectMetadata(JSObject* obj)
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::DefineOwnProperty(JSContext* cx, JSObject* objArg, jsid idArg,
|
||||
JS::Handle<js::PropertyDescriptor> descriptor, bool* bp)
|
||||
JS::Handle<js::PropertyDescriptor> descriptor, ObjectOpResult &result)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
RootedId id(cx, idArg);
|
||||
@@ -1181,7 +1181,7 @@ js::DefineOwnProperty(JSContext* cx, JSObject* objArg, jsid idArg,
|
||||
if (descriptor.hasSetterObject())
|
||||
assertSameCompartment(cx, descriptor.setterObject());
|
||||
|
||||
return StandardDefineProperty(cx, obj, id, descriptor, bp);
|
||||
return StandardDefineProperty(cx, obj, id, descriptor, result);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
|
||||
@@ -311,7 +311,8 @@ proxy_LookupProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::M
|
||||
JS::MutableHandle<Shape*> propp);
|
||||
extern JS_FRIEND_API(bool)
|
||||
proxy_DefineProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs,
|
||||
JS::ObjectOpResult &result);
|
||||
extern JS_FRIEND_API(bool)
|
||||
proxy_HasProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id, bool* foundp);
|
||||
extern JS_FRIEND_API(bool)
|
||||
@@ -319,7 +320,7 @@ proxy_GetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver
|
||||
JS::MutableHandleValue vp);
|
||||
extern JS_FRIEND_API(bool)
|
||||
proxy_SetProperty(JSContext* cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
|
||||
JS::MutableHandleValue bp, bool strict);
|
||||
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);
|
||||
@@ -2550,7 +2551,8 @@ JS_FRIEND_API(bool)
|
||||
SetPropertyIgnoringNamedGetter(JSContext* cx, const BaseProxyHandler* handler,
|
||||
JS::HandleObject proxy, JS::HandleObject receiver,
|
||||
JS::HandleId id, JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool descIsOwn, bool strict, JS::MutableHandleValue vp);
|
||||
bool descIsOwn, JS::MutableHandleValue vp,
|
||||
JS::ObjectOpResult &result);
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
ReportErrorWithId(JSContext* cx, const char* msg, JS::HandleId id);
|
||||
@@ -2621,7 +2623,7 @@ ReportIsNotFunction(JSContext* cx, JS::HandleValue v);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
DefineOwnProperty(JSContext* cx, JSObject* objArg, jsid idArg,
|
||||
JS::Handle<JSPropertyDescriptor> descriptor, bool* bp);
|
||||
JS::Handle<JSPropertyDescriptor> descriptor, JS::ObjectOpResult &result);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
|
||||
+132
-99
@@ -445,41 +445,12 @@ js::Throw(JSContext* cx, JSObject* obj, unsigned errorNumber)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
Reject(JSContext* cx, unsigned errorNumber, bool throwError, jsid id, bool* rval)
|
||||
{
|
||||
if (throwError)
|
||||
return Throw(cx, id, errorNumber);
|
||||
|
||||
*rval = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
Reject(JSContext* cx, JSObject* obj, unsigned errorNumber, bool throwError, bool* rval)
|
||||
{
|
||||
if (throwError)
|
||||
return Throw(cx, obj, errorNumber);
|
||||
|
||||
*rval = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
Reject(JSContext* cx, HandleId id, unsigned errorNumber, bool throwError, bool* rval)
|
||||
{
|
||||
if (throwError)
|
||||
return Throw(cx, id, errorNumber);
|
||||
|
||||
*rval = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*** Standard-compliant property definition (used by Object.defineProperty) **********************/
|
||||
|
||||
static bool
|
||||
DefinePropertyOnObject(JSContext* cx, HandleNativeObject obj, HandleId id, const PropDesc& desc,
|
||||
bool throwError, bool* rval)
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
/* 8.12.9 step 1. */
|
||||
RootedShape shape(cx);
|
||||
@@ -495,20 +466,19 @@ DefinePropertyOnObject(JSContext* cx, HandleNativeObject obj, HandleId id, const
|
||||
if (!IsExtensible(cx, obj, &extensible))
|
||||
return false;
|
||||
if (!extensible)
|
||||
return Reject(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE, throwError, rval);
|
||||
|
||||
*rval = true;
|
||||
return result.fail(JSMSG_OBJECT_NOT_EXTENSIBLE);
|
||||
|
||||
if (desc.isGenericDescriptor() || desc.isDataDescriptor()) {
|
||||
MOZ_ASSERT(!obj->getOps()->defineProperty);
|
||||
RootedValue v(cx, desc.hasValue() ? desc.value() : UndefinedValue());
|
||||
return NativeDefineProperty(cx, obj, id, v, nullptr, nullptr, desc.attributes());
|
||||
return NativeDefineProperty(cx, obj, id, v, nullptr, nullptr, desc.attributes(),
|
||||
result);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(desc.isAccessorDescriptor());
|
||||
|
||||
return NativeDefineProperty(cx, obj, id, UndefinedHandleValue,
|
||||
desc.getter(), desc.setter(), desc.attributes());
|
||||
desc.getter(), desc.setter(), desc.attributes(), result);
|
||||
}
|
||||
|
||||
/* 8.12.9 steps 5-6 (note 5 is merely a special case of 6). */
|
||||
@@ -585,7 +555,7 @@ DefinePropertyOnObject(JSContext* cx, HandleNativeObject obj, HandleId id, const
|
||||
desc.isDataDescriptor() &&
|
||||
(desc.hasWritable() ? desc.writable() : shape->writable()))
|
||||
{
|
||||
return Reject(cx, JSMSG_CANT_REDEFINE_PROP, throwError, id, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
}
|
||||
|
||||
if (!NativeGetExistingProperty(cx, obj, obj, shape, &v))
|
||||
@@ -611,16 +581,16 @@ DefinePropertyOnObject(JSContext* cx, HandleNativeObject obj, HandleId id, const
|
||||
* flag we veto from true to false for non-configurable
|
||||
* PropertyOp-based data properties and test before the
|
||||
* SameValue check later on in order to re-use that "if
|
||||
* (!SameValue) Reject" logic.
|
||||
* (!SameValue) return false" logic.
|
||||
*
|
||||
* This function is large and complex enough that it
|
||||
* seems best to repeat a small bit of code and return
|
||||
* Reject(...) ASAP, instead of being clever.
|
||||
* result.fail() ASAP, instead of being clever.
|
||||
*/
|
||||
if (!shapeConfigurable &&
|
||||
(!shape->hasDefaultGetter() || !shape->hasDefaultSetter()))
|
||||
{
|
||||
return Reject(cx, JSMSG_CANT_REDEFINE_PROP, throwError, id, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -639,15 +609,14 @@ DefinePropertyOnObject(JSContext* cx, HandleNativeObject obj, HandleId id, const
|
||||
break;
|
||||
|
||||
/* The conditions imposed by step 5 or step 6 apply. */
|
||||
*rval = true;
|
||||
return true;
|
||||
return result.succeed();
|
||||
} while (0);
|
||||
|
||||
/* 8.12.9 step 7. */
|
||||
if (!shapeConfigurable) {
|
||||
if ((desc.hasConfigurable() && desc.configurable()) ||
|
||||
(desc.hasEnumerable() && desc.enumerable() != shape->enumerable())) {
|
||||
return Reject(cx, JSMSG_CANT_REDEFINE_PROP, throwError, id, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -658,19 +627,19 @@ DefinePropertyOnObject(JSContext* cx, HandleNativeObject obj, HandleId id, const
|
||||
} else if (desc.isDataDescriptor() != shapeDataDescriptor) {
|
||||
/* 8.12.9 step 9. */
|
||||
if (!shapeConfigurable)
|
||||
return Reject(cx, JSMSG_CANT_REDEFINE_PROP, throwError, id, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
} else if (desc.isDataDescriptor()) {
|
||||
/* 8.12.9 step 10. */
|
||||
MOZ_ASSERT(shapeDataDescriptor);
|
||||
if (!shapeConfigurable && !shape->writable()) {
|
||||
if (desc.hasWritable() && desc.writable())
|
||||
return Reject(cx, JSMSG_CANT_REDEFINE_PROP, throwError, id, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
if (desc.hasValue()) {
|
||||
bool same;
|
||||
if (!SameValue(cx, desc.value(), v, &same))
|
||||
return false;
|
||||
if (!same)
|
||||
return Reject(cx, JSMSG_CANT_REDEFINE_PROP, throwError, id, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -685,7 +654,7 @@ DefinePropertyOnObject(JSContext* cx, HandleNativeObject obj, HandleId id, const
|
||||
if (!SameValue(cx, desc.setterValue(), setter, &same))
|
||||
return false;
|
||||
if (!same)
|
||||
return Reject(cx, JSMSG_CANT_REDEFINE_PROP, throwError, id, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
}
|
||||
|
||||
if (desc.hasGet()) {
|
||||
@@ -694,7 +663,7 @@ DefinePropertyOnObject(JSContext* cx, HandleNativeObject obj, HandleId id, const
|
||||
if (!SameValue(cx, desc.getterValue(), getter, &same))
|
||||
return false;
|
||||
if (!same)
|
||||
return Reject(cx, JSMSG_CANT_REDEFINE_PROP, throwError, id, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -759,8 +728,6 @@ DefinePropertyOnObject(JSContext* cx, HandleNativeObject obj, HandleId id, const
|
||||
}
|
||||
}
|
||||
|
||||
*rval = true;
|
||||
|
||||
/*
|
||||
* Since "data" properties implemented using native C functions may rely on
|
||||
* side effects during setting, we must make them aware that they have been
|
||||
@@ -771,18 +738,18 @@ DefinePropertyOnObject(JSContext* cx, HandleNativeObject obj, HandleId id, const
|
||||
* redefining it or we had invoked its setter to change its value).
|
||||
*/
|
||||
if (callDelProperty) {
|
||||
bool succeeded;
|
||||
if (!CallJSDeletePropertyOp(cx, obj->getClass()->delProperty, obj, id, &succeeded))
|
||||
bool ignored;
|
||||
if (!CallJSDeletePropertyOp(cx, obj->getClass()->delProperty, obj, id, &ignored))
|
||||
return false;
|
||||
}
|
||||
|
||||
return NativeDefineProperty(cx, obj, id, v, getter, setter, attrs);
|
||||
return NativeDefineProperty(cx, obj, id, v, getter, setter, attrs, result);
|
||||
}
|
||||
|
||||
/* ES6 20130308 draft 8.4.2.1 [[DefineOwnProperty]] */
|
||||
static bool
|
||||
DefinePropertyOnArray(JSContext* cx, Handle<ArrayObject*> arr, HandleId id, const PropDesc& desc,
|
||||
bool throwError, bool* rval)
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
/* Step 2. */
|
||||
if (id == NameToId(cx->names().length)) {
|
||||
@@ -804,23 +771,23 @@ DefinePropertyOnArray(JSContext* cx, Handle<ArrayObject*> arr, HandleId id, cons
|
||||
}
|
||||
|
||||
if (desc.hasConfigurable() && desc.configurable())
|
||||
return Reject(cx, id, JSMSG_CANT_REDEFINE_PROP, throwError, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
if (desc.hasEnumerable() && desc.enumerable())
|
||||
return Reject(cx, id, JSMSG_CANT_REDEFINE_PROP, throwError, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
if (desc.isAccessorDescriptor())
|
||||
return Reject(cx, id, JSMSG_CANT_REDEFINE_PROP, throwError, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
unsigned attrs = arr->lookup(cx, id)->attributes();
|
||||
if (!arr->lengthIsWritable()) {
|
||||
if (desc.hasWritable() && desc.writable())
|
||||
return Reject(cx, id, JSMSG_CANT_REDEFINE_PROP, throwError, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
} else {
|
||||
if (desc.hasWritable() && !desc.writable())
|
||||
attrs = attrs | JSPROP_READONLY;
|
||||
}
|
||||
|
||||
return ArraySetLength(cx, arr, id, attrs, v, throwError);
|
||||
return ArraySetLength(cx, arr, id, attrs, v, result);
|
||||
}
|
||||
|
||||
/* Step 3. */
|
||||
@@ -831,22 +798,21 @@ DefinePropertyOnArray(JSContext* cx, Handle<ArrayObject*> arr, HandleId id, cons
|
||||
|
||||
/* Steps 3a, 3e. */
|
||||
if (index >= oldLen && !arr->lengthIsWritable())
|
||||
return Reject(cx, arr, JSMSG_CANT_APPEND_TO_ARRAY, throwError, rval);
|
||||
return result.fail(JSMSG_CANT_APPEND_TO_ARRAY);
|
||||
|
||||
/* Steps 3f-j. */
|
||||
return DefinePropertyOnObject(cx, arr, id, desc, throwError, rval);
|
||||
return DefinePropertyOnObject(cx, arr, id, desc, result);
|
||||
}
|
||||
|
||||
/* Step 4. */
|
||||
return DefinePropertyOnObject(cx, arr, id, desc, throwError, rval);
|
||||
return DefinePropertyOnObject(cx, arr, id, desc, result);
|
||||
}
|
||||
|
||||
// ES6 draft rev31 9.4.5.3 [[DefineOwnProperty]]
|
||||
static bool
|
||||
DefinePropertyOnTypedArray(JSContext* cx, HandleObject obj, HandleId id, const PropDesc& desc,
|
||||
bool throwError, bool* rval)
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
|
||||
MOZ_ASSERT(IsAnyTypedArray(obj));
|
||||
// Steps 3.a-c.
|
||||
uint64_t index;
|
||||
@@ -854,26 +820,24 @@ DefinePropertyOnTypedArray(JSContext* cx, HandleObject obj, HandleId id, const P
|
||||
// These are all substeps of 3.c.
|
||||
// Steps i-vi.
|
||||
// We (wrongly) ignore out of range defines with a value.
|
||||
if (index >= AnyTypedArrayLength(obj)) {
|
||||
*rval = true;
|
||||
return true;
|
||||
}
|
||||
if (index >= AnyTypedArrayLength(obj))
|
||||
return result.succeed();
|
||||
|
||||
// Step vii.
|
||||
if (desc.isAccessorDescriptor())
|
||||
return Reject(cx, id, JSMSG_CANT_REDEFINE_PROP, throwError, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
// Step viii.
|
||||
if (desc.hasConfigurable() && desc.configurable())
|
||||
return Reject(cx, id, JSMSG_CANT_REDEFINE_PROP, throwError, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
// Step ix.
|
||||
if (desc.hasEnumerable() && !desc.enumerable())
|
||||
return Reject(cx, id, JSMSG_CANT_REDEFINE_PROP, throwError, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
// Step x.
|
||||
if (desc.hasWritable() && !desc.writable())
|
||||
return Reject(cx, id, JSMSG_CANT_REDEFINE_PROP, throwError, rval);
|
||||
return result.fail(JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
// Step xi.
|
||||
if (desc.hasValue()) {
|
||||
@@ -888,25 +852,24 @@ DefinePropertyOnTypedArray(JSContext* cx, HandleObject obj, HandleId id, const P
|
||||
}
|
||||
|
||||
// Step xii.
|
||||
*rval = true;
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
// Step 4.
|
||||
return DefinePropertyOnObject(cx, obj.as<NativeObject>(), id, desc, throwError, rval);
|
||||
return DefinePropertyOnObject(cx, obj.as<NativeObject>(), id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::StandardDefineProperty(JSContext* cx, HandleObject obj, HandleId id, const PropDesc& desc,
|
||||
bool throwError, bool* rval)
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
if (obj->is<ArrayObject>()) {
|
||||
Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
|
||||
return DefinePropertyOnArray(cx, arr, id, desc, throwError, rval);
|
||||
return DefinePropertyOnArray(cx, arr, id, desc, result);
|
||||
}
|
||||
|
||||
if (IsAnyTypedArray(obj))
|
||||
return DefinePropertyOnTypedArray(cx, obj, id, desc, throwError, rval);
|
||||
return DefinePropertyOnTypedArray(cx, obj, id, desc, result);
|
||||
|
||||
if (obj->is<UnboxedPlainObject>() && !UnboxedPlainObject::convertToNative(cx, obj))
|
||||
return false;
|
||||
@@ -916,21 +879,38 @@ js::StandardDefineProperty(JSContext* cx, HandleObject obj, HandleId id, const P
|
||||
Rooted<PropertyDescriptor> pd(cx);
|
||||
desc.populatePropertyDescriptor(obj, &pd);
|
||||
pd.object().set(obj);
|
||||
return Proxy::defineProperty(cx, obj, id, &pd);
|
||||
return Proxy::defineProperty(cx, obj, id, &pd, result);
|
||||
}
|
||||
return Reject(cx, obj, JSMSG_OBJECT_NOT_EXTENSIBLE, throwError, rval);
|
||||
return result.fail(JSMSG_OBJECT_NOT_EXTENSIBLE);
|
||||
}
|
||||
|
||||
return DefinePropertyOnObject(cx, obj.as<NativeObject>(), id, desc, throwError, rval);
|
||||
return DefinePropertyOnObject(cx, obj.as<NativeObject>(), id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::StandardDefineProperty(JSContext* cx, HandleObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> descriptor, bool* bp)
|
||||
Handle<PropertyDescriptor> descriptor, ObjectOpResult &result)
|
||||
{
|
||||
Rooted<PropDesc> desc(cx);
|
||||
desc.initFromPropertyDescriptor(descriptor);
|
||||
return StandardDefineProperty(cx, obj, id, desc, true, bp);
|
||||
return StandardDefineProperty(cx, obj, id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::StandardDefineProperty(JSContext *cx, HandleObject obj, HandleId id, const PropDesc &desc)
|
||||
{
|
||||
ObjectOpResult success;
|
||||
return StandardDefineProperty(cx, obj, id, desc, success) &&
|
||||
success.checkStrict(cx, obj, id);
|
||||
}
|
||||
|
||||
bool
|
||||
js::StandardDefineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> desc)
|
||||
{
|
||||
ObjectOpResult success;
|
||||
return StandardDefineProperty(cx, obj, id, desc, success) &&
|
||||
success.checkStrict(cx, obj, id);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -963,9 +943,8 @@ js::DefineProperties(JSContext* cx, HandleObject obj, HandleObject props)
|
||||
if (!ReadPropertyDescriptors(cx, props, true, &ids, &descs))
|
||||
return false;
|
||||
|
||||
bool dummy;
|
||||
for (size_t i = 0, len = ids.length(); i < len; i++) {
|
||||
if (!StandardDefineProperty(cx, obj, ids[i], descs[i], true, &dummy))
|
||||
if (!StandardDefineProperty(cx, obj, ids[i], descs[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1083,8 +1062,7 @@ js::SetIntegrityLevel(JSContext* cx, HandleObject obj, IntegrityLevel level)
|
||||
desc.object().set(obj);
|
||||
|
||||
// 8.a.i-ii. / 9.a.iii.3-4
|
||||
bool result;
|
||||
if (!StandardDefineProperty(cx, obj, id, desc, &result))
|
||||
if (!StandardDefineProperty(cx, obj, id, desc))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1676,24 +1654,24 @@ js::CreateThisForFunction(JSContext* cx, HandleObject callee, NewObjectKind newK
|
||||
|
||||
/* static */ bool
|
||||
JSObject::nonNativeSetProperty(JSContext* cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, bool strict)
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
if (MOZ_UNLIKELY(obj->watched())) {
|
||||
WatchpointMap* wpmap = cx->compartment()->watchpointMap;
|
||||
if (wpmap && !wpmap->triggerWatchpoint(cx, obj, id, vp))
|
||||
return false;
|
||||
}
|
||||
return obj->getOps()->setProperty(cx, obj, receiver, id, vp, strict);
|
||||
return obj->getOps()->setProperty(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
JSObject::nonNativeSetElement(JSContext* cx, HandleObject obj, HandleObject receiver,
|
||||
uint32_t index, MutableHandleValue vp, bool strict)
|
||||
uint32_t index, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
return nonNativeSetProperty(cx, obj, receiver, id, vp, strict);
|
||||
return nonNativeSetProperty(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
@@ -1724,8 +1702,7 @@ JS_CopyPropertyFrom(JSContext* cx, HandleId id, HandleObject target,
|
||||
if (!cx->compartment()->wrap(cx, &desc))
|
||||
return false;
|
||||
|
||||
bool ignored;
|
||||
return StandardDefineProperty(cx, target, wrappedId, desc, &ignored);
|
||||
return StandardDefineProperty(cx, target, wrappedId, desc);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
@@ -3206,7 +3183,8 @@ js::GetOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id,
|
||||
|
||||
bool
|
||||
js::DefineProperty(ExclusiveContext* cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
@@ -3216,15 +3194,54 @@ js::DefineProperty(ExclusiveContext* cx, HandleObject obj, HandleId id, HandleVa
|
||||
if (op) {
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
return op(cx->asJSContext(), obj, id, value, getter, setter, attrs);
|
||||
return op(cx->asJSContext(), obj, id, value, getter, setter, attrs, result);
|
||||
}
|
||||
return NativeDefineProperty(cx, obj.as<NativeObject>(), id, value, getter, setter, attrs);
|
||||
return NativeDefineProperty(cx, obj.as<NativeObject>(), id, value, getter, setter, attrs,
|
||||
result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::DefineProperty(ExclusiveContext* cx, HandleObject obj,
|
||||
PropertyName* name, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
js::DefineProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return DefineProperty(cx, obj, id, value, getter, setter, attrs, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::DefineElement(ExclusiveContext *cx, HandleObject obj, uint32_t index, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
return DefineProperty(cx, obj, id, value, getter, setter, attrs, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::DefineProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
ObjectOpResult result;
|
||||
if (!DefineProperty(cx, obj, id, value, getter, setter, attrs, result))
|
||||
return false;
|
||||
if (!result) {
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
result.reportError(cx->asJSContext(), obj, id);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::DefineProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return DefineProperty(cx, obj, id, value, getter, setter, attrs);
|
||||
@@ -3232,7 +3249,7 @@ js::DefineProperty(ExclusiveContext* cx, HandleObject obj,
|
||||
|
||||
bool
|
||||
js::DefineElement(ExclusiveContext* cx, HandleObject obj, uint32_t index, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
{
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
@@ -3243,6 +3260,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 ***************************************************/
|
||||
|
||||
|
||||
+66
-9
@@ -519,10 +519,10 @@ class JSObject : public js::gc::Cell
|
||||
|
||||
static bool nonNativeSetProperty(JSContext* cx, js::HandleObject obj,
|
||||
js::HandleObject receiver, js::HandleId id,
|
||||
js::MutableHandleValue vp, bool strict);
|
||||
js::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
static bool nonNativeSetElement(JSContext* cx, js::HandleObject obj,
|
||||
js::HandleObject receiver, uint32_t index,
|
||||
js::MutableHandleValue vp, bool strict);
|
||||
js::MutableHandleValue vp, JS::ObjectOpResult &result);
|
||||
|
||||
static bool swap(JSContext* cx, JS::HandleObject a, JS::HandleObject b);
|
||||
|
||||
@@ -787,13 +787,40 @@ GetOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id,
|
||||
* the DefineProperty functions do not enforce some invariants mandated by ES6.
|
||||
*/
|
||||
extern bool
|
||||
StandardDefineProperty(JSContext* cx, HandleObject obj, HandleId id,
|
||||
const PropDesc& desc, bool throwError, bool* rval);
|
||||
StandardDefineProperty(JSContext *cx, HandleObject obj, HandleId id, const PropDesc &desc,
|
||||
ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
StandardDefineProperty(JSContext* cx, HandleObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> descriptor, bool* bp);
|
||||
Handle<PropertyDescriptor> descriptor, ObjectOpResult &result);
|
||||
|
||||
/*
|
||||
* For convenience, signatures identical to the above except without the
|
||||
* ObjectOpResult out-parameter. They throw a TypeError on failure.
|
||||
*/
|
||||
extern bool
|
||||
StandardDefineProperty(JSContext *cx, HandleObject obj, HandleId id, const PropDesc &desc);
|
||||
|
||||
extern bool
|
||||
StandardDefineProperty(JSContext* cx, HandleObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> desc);
|
||||
|
||||
extern bool
|
||||
DefineProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp, unsigned attrs, ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
DefineProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp, unsigned attrs, ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
DefineElement(ExclusiveContext *cx, HandleObject obj, uint32_t index, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp, unsigned attrs, ObjectOpResult &result);
|
||||
|
||||
/*
|
||||
* When the 'result' out-param is omitted, the behavior is the same as above, except
|
||||
* that any failure results in a TypeError.
|
||||
*/
|
||||
extern bool
|
||||
DefineProperty(ExclusiveContext* cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSPropertyOp getter = nullptr,
|
||||
@@ -876,19 +903,49 @@ GetElementNoGC(JSContext* cx, JSObject* obj, JSObject* receiver, uint32_t index,
|
||||
*/
|
||||
inline bool
|
||||
SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, bool strict);
|
||||
MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
inline bool
|
||||
SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, PropertyName* name,
|
||||
MutableHandleValue vp, bool strict)
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return SetProperty(cx, obj, receiver, id, vp, strict);
|
||||
return SetProperty(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
inline bool
|
||||
SetElement(JSContext* cx, HandleObject obj, HandleObject receiver, uint32_t index,
|
||||
MutableHandleValue vp, bool strict);
|
||||
MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
inline bool
|
||||
SetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp)
|
||||
{
|
||||
ObjectOpResult result;
|
||||
return SetProperty(cx, obj, receiver, id, vp, result) &&
|
||||
result.checkStrict(cx, receiver, id);
|
||||
}
|
||||
|
||||
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
|
||||
* success, the spec says this is supposed to return a boolean value, which we
|
||||
* don't bother doing.
|
||||
*/
|
||||
inline bool
|
||||
PutProperty(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue value, bool strict)
|
||||
{
|
||||
ObjectOpResult 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]`.
|
||||
|
||||
@@ -742,7 +742,7 @@ NodeBuilder::newArray(NodeVector& elts, MutableHandleValue dst)
|
||||
if (val.isMagic(JS_SERIALIZE_NO_NODE))
|
||||
continue;
|
||||
|
||||
if (!SetElement(cx, array, array, i, &val, false))
|
||||
if (!DefineElement(cx, array, i, val))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -2175,7 +2175,7 @@ class MOZ_STACK_CLASS StringRegExpGuard
|
||||
|
||||
// Handle everything else generically (including throwing if .lastIndex is non-writable).
|
||||
RootedValue zero(cx, Int32Value(0));
|
||||
return SetProperty(cx, obj_, obj_, cx->names().lastIndex, &zero, true);
|
||||
return SetProperty(cx, obj_, obj_, cx->names().lastIndex, &zero);
|
||||
}
|
||||
|
||||
RegExpShared& regExp() { return *re_; }
|
||||
|
||||
+6
-4
@@ -117,7 +117,8 @@ 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,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject wrapper,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool delete_(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const override;
|
||||
@@ -134,8 +135,8 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
|
||||
virtual bool has(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const override;
|
||||
virtual bool get(JSContext* cx, HandleObject wrapper, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp) const override;
|
||||
virtual bool set(JSContext* cx, HandleObject wrapper, HandleObject receiver,
|
||||
HandleId id, bool strict, MutableHandleValue vp) const override;
|
||||
virtual bool set(JSContext *cx, HandleObject wrapper, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result) const MOZ_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;
|
||||
|
||||
@@ -182,7 +183,8 @@ class JS_FRIEND_API(SecurityWrapper) : public Base
|
||||
bool* bp) const override;
|
||||
|
||||
virtual bool defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool isExtensible(JSContext* cx, HandleObject wrapper, bool* extensible) const override;
|
||||
virtual bool preventExtensions(JSContext* cx, HandleObject wrapper, bool* succeeded) const override;
|
||||
virtual bool setPrototypeOf(JSContext* cx, HandleObject proxy, HandleObject proto,
|
||||
|
||||
@@ -73,7 +73,7 @@ BaseProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
|
||||
bool
|
||||
BaseProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, bool strict, MutableHandleValue vp) const
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
|
||||
@@ -94,7 +94,7 @@ BaseProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
if (!GetPrototype(cx, proxy, &proto))
|
||||
return false;
|
||||
if (proto)
|
||||
return SetProperty(cx, proto, receiver, id, vp, strict);
|
||||
return SetProperty(cx, proto, receiver, id, vp, result);
|
||||
|
||||
// Change ownDesc to be a complete descriptor for a configurable,
|
||||
// writable, enumerable data property. Then fall through to step 5.
|
||||
@@ -106,19 +106,14 @@ BaseProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
if (ownDesc.isDataDescriptor()) {
|
||||
// Steps 5.a-b, adapted to our nonstandard implementation of ES6
|
||||
// [[Set]] return values.
|
||||
if (!ownDesc.isWritable()) {
|
||||
if (strict)
|
||||
return JSObject::reportReadOnly(cx, id, JSREPORT_ERROR);
|
||||
if (cx->compartment()->options().extraWarnings(cx))
|
||||
return JSObject::reportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING);
|
||||
return true;
|
||||
}
|
||||
if (!ownDesc.isWritable())
|
||||
return result.fail(JSMSG_READ_ONLY);
|
||||
|
||||
// Nonstandard SpiderMonkey special case: setter ops.
|
||||
StrictPropertyOp setter = ownDesc.setter();
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
if (setter && setter != JS_StrictPropertyStub)
|
||||
return CallSetter(cx, receiver, id, setter, ownDesc.attributes(), strict, vp);
|
||||
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]].
|
||||
@@ -137,8 +132,8 @@ BaseProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
const Class* clasp = receiver->getClass();
|
||||
MOZ_ASSERT(clasp->getProperty != JS_PropertyStub);
|
||||
MOZ_ASSERT(clasp->setProperty != JS_StrictPropertyStub);
|
||||
return DefineProperty(cx, receiver, id, vp,
|
||||
clasp->getProperty, clasp->setProperty, attrs);
|
||||
return DefineProperty(cx, receiver, id, vp, clasp->getProperty, clasp->setProperty,
|
||||
attrs, result);
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
@@ -147,16 +142,18 @@ BaseProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
if (ownDesc.hasSetterObject())
|
||||
setter = ownDesc.setterObject();
|
||||
if (!setter)
|
||||
return ReportGetterOnlyAssignment(cx, strict);
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
RootedValue setterValue(cx, ObjectValue(*setter));
|
||||
return InvokeGetterOrSetter(cx, receiver, setterValue, 1, vp.address(), vp);
|
||||
if (!InvokeGetterOrSetter(cx, receiver, setterValue, 1, vp.address(), vp))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
bool
|
||||
js::SetPropertyIgnoringNamedGetter(JSContext* cx, const BaseProxyHandler* handler,
|
||||
HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, MutableHandle<PropertyDescriptor> desc,
|
||||
bool descIsOwn, bool strict, MutableHandleValue vp)
|
||||
bool descIsOwn, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
/* The control-flow here differs from ::get() because of the fall-through case below. */
|
||||
MOZ_ASSERT_IF(descIsOwn, desc.object());
|
||||
@@ -165,35 +162,37 @@ js::SetPropertyIgnoringNamedGetter(JSContext* cx, const BaseProxyHandler* handle
|
||||
MOZ_ASSERT(desc.setter() != JS_StrictPropertyStub);
|
||||
|
||||
// Check for read-only properties.
|
||||
if (desc.isReadonly()) {
|
||||
if (strict)
|
||||
return Throw(cx, id, descIsOwn ? JSMSG_READ_ONLY : JSMSG_CANT_REDEFINE_PROP);
|
||||
return true;
|
||||
}
|
||||
if (desc.isReadonly())
|
||||
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(), strict, vp))
|
||||
if (!CallSetter(cx, receiver, id, desc.setter(), desc.attributes(), vp, result))
|
||||
return false;
|
||||
if (!proxy->is<ProxyObject>() || proxy->as<ProxyObject>().handler() != handler)
|
||||
return true;
|
||||
if (desc.isShared())
|
||||
if (!result)
|
||||
return true;
|
||||
if (!proxy->is<ProxyObject>() ||
|
||||
proxy->as<ProxyObject>().handler() != handler ||
|
||||
desc.isShared())
|
||||
{
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
desc.value().set(vp.get());
|
||||
|
||||
if (descIsOwn) {
|
||||
MOZ_ASSERT(desc.object() == proxy);
|
||||
return handler->defineProperty(cx, proxy, id, desc);
|
||||
return handler->defineProperty(cx, proxy, id, desc, result);
|
||||
}
|
||||
return DefineProperty(cx, receiver, id, desc.value(),
|
||||
desc.getter(), desc.setter(), desc.attributes());
|
||||
return DefineProperty(cx, receiver, id, desc.value(), desc.getter(), desc.setter(),
|
||||
desc.attributes(), 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);
|
||||
return DefineProperty(cx, receiver, id, desc.value(), nullptr, nullptr, JSPROP_ENUMERATE,
|
||||
result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -49,12 +49,13 @@ CrossCompartmentWrapper::getOwnPropertyDescriptor(JSContext* cx, HandleObject wr
|
||||
|
||||
bool
|
||||
CrossCompartmentWrapper::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const
|
||||
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),
|
||||
Wrapper::defineProperty(cx, wrapper, id, &desc2, result),
|
||||
NOTHING);
|
||||
}
|
||||
|
||||
@@ -168,13 +169,13 @@ CrossCompartmentWrapper::get(JSContext* cx, HandleObject wrapper, HandleObject r
|
||||
|
||||
bool
|
||||
CrossCompartmentWrapper::set(JSContext* cx, HandleObject wrapper, HandleObject receiver,
|
||||
HandleId id, bool strict, MutableHandleValue vp) const
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
RootedObject receiverCopy(cx, receiver);
|
||||
PIERCE(cx, wrapper,
|
||||
cx->compartment()->wrap(cx, &receiverCopy) &&
|
||||
cx->compartment()->wrap(cx, vp),
|
||||
Wrapper::set(cx, wrapper, receiverCopy, id, strict, vp),
|
||||
Wrapper::set(cx, wrapper, receiverCopy, id, vp, result),
|
||||
NOTHING);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ DeadObjectProxy::getOwnPropertyDescriptor(JSContext* cx, HandleObject wrapper, H
|
||||
|
||||
bool
|
||||
DeadObjectProxy::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
|
||||
return false;
|
||||
|
||||
@@ -22,7 +22,8 @@ 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,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject wrapper,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool delete_(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp) const override;
|
||||
|
||||
@@ -34,12 +34,12 @@ DirectProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy,
|
||||
|
||||
bool
|
||||
DirectProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
bool ignored;
|
||||
return StandardDefineProperty(cx, target, id, desc, &ignored);
|
||||
return StandardDefineProperty(cx, target, id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -223,11 +223,11 @@ DirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject receiver
|
||||
|
||||
bool
|
||||
DirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, bool strict, MutableHandleValue vp) const
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, id, SET);
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
return SetProperty(cx, target, receiver, id, vp, strict);
|
||||
return SetProperty(cx, target, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
+21
-14
@@ -134,14 +134,17 @@ Proxy::getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
|
||||
bool
|
||||
Proxy::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc)
|
||||
MutableHandle<PropertyDescriptor> desc, ObjectOpResult &result)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
const BaseProxyHandler* handler = proxy->as<ProxyObject>().handler();
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
|
||||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
return proxy->as<ProxyObject>().handler()->defineProperty(cx, proxy, id, desc);
|
||||
if (!policy.allowed()) {
|
||||
if (!policy.returnValue())
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
return proxy->as<ProxyObject>().handler()->defineProperty(cx, proxy, id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -301,20 +304,23 @@ Proxy::callProp(JSContext* cx, HandleObject proxy, HandleObject receiver, Handle
|
||||
}
|
||||
|
||||
bool
|
||||
Proxy::set(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id, bool strict,
|
||||
MutableHandleValue vp)
|
||||
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();
|
||||
AutoEnterPolicy policy(cx, handler, proxy, id, BaseProxyHandler::SET, true);
|
||||
if (!policy.allowed())
|
||||
return policy.returnValue();
|
||||
if (!policy.allowed()) {
|
||||
if (!policy.returnValue())
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
// Special case. See the comment on BaseProxyHandler::mHasPrototype.
|
||||
if (handler->hasPrototype())
|
||||
return handler->BaseProxyHandler::set(cx, proxy, receiver, id, strict, vp);
|
||||
return handler->BaseProxyHandler::set(cx, proxy, receiver, id, vp, result);
|
||||
|
||||
return handler->set(cx, proxy, receiver, id, strict, vp);
|
||||
return handler->set(cx, proxy, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -551,7 +557,8 @@ js::proxy_LookupProperty(JSContext* cx, HandleObject obj, HandleId id,
|
||||
|
||||
bool
|
||||
js::proxy_DefineProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
desc.object().set(obj);
|
||||
@@ -559,7 +566,7 @@ js::proxy_DefineProperty(JSContext* cx, HandleObject obj, HandleId id, HandleVal
|
||||
desc.setAttributes(attrs);
|
||||
desc.setGetter(getter);
|
||||
desc.setSetter(setter);
|
||||
return Proxy::defineProperty(cx, obj, id, &desc);
|
||||
return Proxy::defineProperty(cx, obj, id, &desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -577,9 +584,9 @@ js::proxy_GetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, Ha
|
||||
|
||||
bool
|
||||
js::proxy_SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, bool strict)
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
return Proxy::set(cx, obj, receiver, id, strict, vp);
|
||||
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,
|
||||
MutableHandle<JSPropertyDescriptor> desc);
|
||||
MutableHandle<JSPropertyDescriptor> desc, ObjectOpResult &result);
|
||||
static bool ownPropertyKeys(JSContext* cx, HandleObject proxy, AutoIdVector& props);
|
||||
static bool delete_(JSContext* cx, HandleObject proxy, HandleId id, bool* bp);
|
||||
static bool enumerate(JSContext* cx, HandleObject proxy, MutableHandleObject objp);
|
||||
@@ -42,7 +42,7 @@ class Proxy
|
||||
static bool get(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp);
|
||||
static bool set(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
bool strict, MutableHandleValue vp);
|
||||
MutableHandleValue vp, ObjectOpResult &result);
|
||||
static bool call(JSContext* cx, HandleObject proxy, const CallArgs& args);
|
||||
static bool construct(JSContext* cx, HandleObject proxy, const CallArgs& args);
|
||||
|
||||
|
||||
@@ -552,38 +552,37 @@ ScriptedDirectProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObject
|
||||
return true;
|
||||
}
|
||||
|
||||
// ES6 (5 April 2014) 9.5.6 Proxy.[[DefineOwnProperty]](O,P)
|
||||
// ES6 draft rev 31 (15 Jan 2015) 9.5.6 Proxy.[[DefineOwnProperty]](P, Desc)
|
||||
bool
|
||||
ScriptedDirectProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
// step 2
|
||||
// step 2-4
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
|
||||
// step 3
|
||||
if (!handler) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_PROXY_REVOKED);
|
||||
return false;
|
||||
}
|
||||
|
||||
// step 4
|
||||
// step 5
|
||||
RootedObject target(cx, proxy->as<ProxyObject>().target());
|
||||
|
||||
// step 5-6
|
||||
// steps 6-7
|
||||
RootedValue trap(cx);
|
||||
if (!GetProperty(cx, handler, handler, cx->names().defineProperty, &trap))
|
||||
return false;
|
||||
|
||||
// step 7
|
||||
// step 8
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::defineProperty(cx, proxy, id, desc);
|
||||
return DirectProxyHandler::defineProperty(cx, proxy, id, desc, result);
|
||||
|
||||
// step 8-9
|
||||
// step 9
|
||||
RootedValue descObj(cx);
|
||||
if (!NewPropertyDescriptorObject(cx, desc, &descObj))
|
||||
return false;
|
||||
|
||||
// step 10, 12
|
||||
// steps 10-11
|
||||
RootedValue propKey(cx);
|
||||
if (!IdToStringOrSymbol(cx, id, &propKey))
|
||||
return false;
|
||||
@@ -597,48 +596,50 @@ ScriptedDirectProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, Ha
|
||||
if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult))
|
||||
return false;
|
||||
|
||||
// step 11, 13
|
||||
if (ToBoolean(trapResult)) {
|
||||
// step 14-15
|
||||
Rooted<PropertyDescriptor> targetDesc(cx);
|
||||
if (!GetOwnPropertyDescriptor(cx, target, id, &targetDesc))
|
||||
return false;
|
||||
// FIXME - bug 1132522: Step 12 is not implemented yet.
|
||||
// if (!ToBoolean(trapResult))
|
||||
// return result.fail(JSMSG_PROXY_DEFINE_RETURNED_FALSE);
|
||||
|
||||
// step 16-17
|
||||
bool extensibleTarget;
|
||||
if (!IsExtensible(cx, target, &extensibleTarget))
|
||||
return false;
|
||||
// step 13-14
|
||||
Rooted<PropertyDescriptor> targetDesc(cx);
|
||||
if (!GetOwnPropertyDescriptor(cx, target, id, &targetDesc))
|
||||
return false;
|
||||
|
||||
// step 18-19
|
||||
bool settingConfigFalse = desc.isPermanent();
|
||||
if (!targetDesc.object()) {
|
||||
// step 20a
|
||||
if (!extensibleTarget) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_DEFINE_NEW);
|
||||
return false;
|
||||
}
|
||||
// step 20b
|
||||
if (settingConfigFalse) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_DEFINE_NE_AS_NC);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// step 21
|
||||
bool valid;
|
||||
Rooted<PropDesc> pd(cx);
|
||||
pd.initFromPropertyDescriptor(desc);
|
||||
if (!ValidatePropertyDescriptor(cx, extensibleTarget, pd, targetDesc, &valid))
|
||||
return false;
|
||||
if (!valid || (settingConfigFalse && !targetDesc.isPermanent())) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_DEFINE_INVALID);
|
||||
return false;
|
||||
}
|
||||
// step 15-16
|
||||
bool extensibleTarget;
|
||||
if (!IsExtensible(cx, target, &extensibleTarget))
|
||||
return false;
|
||||
|
||||
// step 17-18
|
||||
// FIXME bug 1133081: settingConfigFalse should be false if we have
|
||||
// JSPROP_IGNORE_PERMANENT.
|
||||
bool settingConfigFalse = desc.isPermanent();
|
||||
if (!targetDesc.object()) {
|
||||
// step 19.a
|
||||
if (!extensibleTarget) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_DEFINE_NEW);
|
||||
return false;
|
||||
}
|
||||
// step 19.b
|
||||
if (settingConfigFalse) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_DEFINE_NE_AS_NC);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// step 20
|
||||
bool valid;
|
||||
Rooted<PropDesc> pd(cx);
|
||||
pd.initFromPropertyDescriptor(desc);
|
||||
if (!ValidatePropertyDescriptor(cx, extensibleTarget, pd, targetDesc, &valid))
|
||||
return false;
|
||||
if (!valid || (settingConfigFalse && !targetDesc.isPermanent())) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_DEFINE_INVALID);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// [[DefineProperty]] should return a boolean value, which is used to do things like
|
||||
// strict-mode throwing. At present, the engine is not prepared to do that. See bug 826587.
|
||||
return true;
|
||||
// step 21
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
// ES6 (5 April 2014) 9.5.12 Proxy.[[OwnPropertyKeys]]()
|
||||
@@ -934,7 +935,7 @@ ScriptedDirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObject
|
||||
// ES6 (22 May, 2014) 9.5.9 Proxy.[[SetP]](P, V, Receiver)
|
||||
bool
|
||||
ScriptedDirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, bool strict, MutableHandleValue vp) const
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
// step 2
|
||||
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
|
||||
@@ -955,7 +956,7 @@ ScriptedDirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject
|
||||
|
||||
// step 7
|
||||
if (trap.isUndefined())
|
||||
return DirectProxyHandler::set(cx, proxy, receiver, id, strict, vp);
|
||||
return DirectProxyHandler::set(cx, proxy, receiver, id, vp, result);
|
||||
|
||||
// step 8,10
|
||||
RootedValue value(cx);
|
||||
@@ -971,7 +972,9 @@ ScriptedDirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject
|
||||
if (!Invoke(cx, ObjectValue(*handler), trap, ArrayLength(argv), argv, &trapResult))
|
||||
return false;
|
||||
|
||||
// step 9
|
||||
// FIXME - bug 1132522: Step 9 is not implemented yet.
|
||||
// if (!ToBoolean(trapResult))
|
||||
// return result.fail(JSMSG_PROXY_SET_RETURNED_FALSE);
|
||||
bool success = ToBoolean(trapResult);
|
||||
|
||||
if (success) {
|
||||
@@ -1000,8 +1003,9 @@ ScriptedDirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject
|
||||
}
|
||||
|
||||
// step 11, 15
|
||||
// XXX FIXME - This use of vp is wrong. Bug 1132522 can clean it up.
|
||||
vp.setBoolean(success);
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler {
|
||||
virtual bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const override;
|
||||
@@ -44,7 +45,7 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler {
|
||||
virtual bool get(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp) const override;
|
||||
virtual bool set(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
bool strict, MutableHandleValue vp) const override;
|
||||
MutableHandleValue vp, ObjectOpResult &result) const MOZ_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;
|
||||
|
||||
|
||||
@@ -196,13 +196,15 @@ ScriptedIndirectProxyHandler::getOwnPropertyDescriptor(JSContext* cx, HandleObje
|
||||
|
||||
bool
|
||||
ScriptedIndirectProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy));
|
||||
RootedValue fval(cx), value(cx);
|
||||
return GetFundamentalTrap(cx, handler, cx->names().defineProperty, &fval) &&
|
||||
NewPropertyDescriptorObject(cx, desc, &value) &&
|
||||
Trap2(cx, handler, fval, id, value, &value);
|
||||
Trap2(cx, handler, fval, id, value, &value) &&
|
||||
result.succeed();
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -294,7 +296,7 @@ ScriptedIndirectProxyHandler::get(JSContext* cx, HandleObject proxy, HandleObjec
|
||||
|
||||
bool
|
||||
ScriptedIndirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, bool strict, MutableHandleValue vp) const
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy));
|
||||
RootedValue idv(cx);
|
||||
@@ -308,13 +310,16 @@ ScriptedIndirectProxyHandler::set(JSContext* cx, HandleObject proxy, HandleObjec
|
||||
if (!GetDerivedTrap(cx, handler, cx->names().set, &fval))
|
||||
return false;
|
||||
if (!IsCallable(fval))
|
||||
return derivedSet(cx, proxy, receiver, id, strict, vp);
|
||||
return Trap(cx, handler, fval, 3, argv.begin(), &idv);
|
||||
return derivedSet(cx, proxy, receiver, id, vp, result);
|
||||
if (!Trap(cx, handler, fval, 3, argv.begin(), &idv))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptedIndirectProxyHandler::derivedSet(JSContext* cx, HandleObject proxy, HandleObject receiver,
|
||||
HandleId id, bool strict, MutableHandleValue vp) const
|
||||
HandleId id, MutableHandleValue vp,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
// Find an own or inherited property. The code here is strange for maximum
|
||||
// backward compatibility with earlier code written before ES6 and before
|
||||
@@ -328,8 +333,8 @@ ScriptedIndirectProxyHandler::derivedSet(JSContext* cx, HandleObject proxy, Hand
|
||||
return false;
|
||||
}
|
||||
|
||||
return SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id, &desc, descIsOwn, strict,
|
||||
vp);
|
||||
return SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id, &desc, descIsOwn, vp,
|
||||
result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -23,7 +23,8 @@ 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,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
|
||||
AutoIdVector& props) const override;
|
||||
virtual bool delete_(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const override;
|
||||
@@ -35,7 +36,7 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
|
||||
virtual bool get(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp) const override;
|
||||
virtual bool set(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
bool strict, MutableHandleValue vp) const override;
|
||||
MutableHandleValue vp, ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
|
||||
/* SpiderMonkey extensions. */
|
||||
virtual bool getPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
@@ -53,7 +54,7 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
|
||||
|
||||
private:
|
||||
bool derivedSet(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
bool strict, MutableHandleValue vp) const;
|
||||
MutableHandleValue vp, ObjectOpResult &result) const;
|
||||
};
|
||||
|
||||
/* Derived class to handle Proxy.createFunction() */
|
||||
|
||||
@@ -105,7 +105,8 @@ SecurityWrapper<Base>::boxedValue_unbox(JSContext* cx, HandleObject obj, Mutable
|
||||
template <class Base>
|
||||
bool
|
||||
SecurityWrapper<Base>::defineProperty(JSContext* cx, HandleObject wrapper,
|
||||
HandleId id, MutableHandle<PropertyDescriptor> desc) const
|
||||
HandleId id, MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
if (desc.getter() || desc.setter()) {
|
||||
RootedValue idVal(cx, IdToValue(id));
|
||||
@@ -121,7 +122,7 @@ SecurityWrapper<Base>::defineProperty(JSContext* cx, HandleObject wrapper,
|
||||
return false;
|
||||
}
|
||||
|
||||
return Base::defineProperty(cx, wrapper, id, desc);
|
||||
return Base::defineProperty(cx, wrapper, id, desc, result);
|
||||
}
|
||||
|
||||
template <class Base>
|
||||
|
||||
@@ -33,7 +33,7 @@ function test()
|
||||
|
||||
try
|
||||
{
|
||||
expect = "TypeError: can't redefine non-configurable property '5'";
|
||||
expect = "TypeError: can't redefine non-configurable property 5";
|
||||
"012345".__defineSetter__(5, function(){});
|
||||
}
|
||||
catch(ex)
|
||||
|
||||
@@ -29,7 +29,7 @@ reportCompare(expect, actual, summary + ': join');
|
||||
|
||||
// reverse
|
||||
value = '123';
|
||||
expect = 'TypeError: Array.prototype.reverse.call(...) is read-only';
|
||||
expect = 'TypeError: 0 is read-only';
|
||||
try
|
||||
{
|
||||
actual = Array.prototype.reverse.call(value) + '';
|
||||
@@ -42,7 +42,7 @@ reportCompare(expect, actual, summary + ': reverse');
|
||||
|
||||
// sort
|
||||
value = 'cba';
|
||||
expect = 'TypeError: Array.prototype.sort.call(...) is read-only';
|
||||
expect = 'TypeError: 0 is read-only';
|
||||
try
|
||||
{
|
||||
actual = Array.prototype.sort.call(value) + '';
|
||||
@@ -100,7 +100,7 @@ reportCompare('abc', value, summary + ': pop');
|
||||
|
||||
// unshift
|
||||
value = 'def';
|
||||
expect = 'TypeError: Array.prototype.unshift.call(...) is read-only';
|
||||
expect = 'TypeError: 0 is read-only';
|
||||
try
|
||||
{
|
||||
actual = Array.prototype.unshift.call(value, 'a', 'b', 'c');
|
||||
@@ -114,7 +114,7 @@ reportCompare('def', value, summary + ': unshift');
|
||||
|
||||
// shift
|
||||
value = 'abc';
|
||||
expect = 'TypeError: Array.prototype.shift.call(...) is read-only';
|
||||
expect = 'TypeError: 0 is read-only';
|
||||
try
|
||||
{
|
||||
actual = Array.prototype.shift.call(value);
|
||||
@@ -128,7 +128,7 @@ reportCompare('abc', value, summary + ': shift');
|
||||
|
||||
// splice
|
||||
value = 'abc';
|
||||
expect = 'TypeError: Array.prototype.splice.call(...) is read-only';
|
||||
expect = 'TypeError: 1 is read-only';
|
||||
try
|
||||
{
|
||||
actual = Array.prototype.splice.call(value, 1, 1) + '';
|
||||
|
||||
@@ -317,10 +317,11 @@ ArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp)
|
||||
}
|
||||
|
||||
static bool
|
||||
ArgSetter(JSContext* cx, HandleObject obj, HandleId id, bool strict, MutableHandleValue vp)
|
||||
ArgSetter(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
if (!obj->is<NormalArgumentsObject>())
|
||||
return true;
|
||||
return result.succeed();
|
||||
Handle<NormalArgumentsObject*> argsobj = obj.as<NormalArgumentsObject>();
|
||||
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
@@ -339,7 +340,7 @@ ArgSetter(JSContext* cx, HandleObject obj, HandleId id, bool strict, MutableHand
|
||||
argsobj->setElement(cx, arg, vp);
|
||||
if (arg < script->functionNonDelazifying()->nargs())
|
||||
TypeScript::SetArgument(cx, script, arg, vp);
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(JSID_IS_ATOM(id, cx->names().length) || JSID_IS_ATOM(id, cx->names().callee));
|
||||
@@ -354,7 +355,7 @@ ArgSetter(JSContext* cx, HandleObject obj, HandleId id, bool strict, MutableHand
|
||||
*/
|
||||
bool succeeded;
|
||||
return NativeDeleteProperty(cx, argsobj, id, &succeeded) &&
|
||||
NativeDefineProperty(cx, argsobj, id, vp, nullptr, nullptr, attrs);
|
||||
NativeDefineProperty(cx, argsobj, id, vp, nullptr, nullptr, attrs, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -438,10 +439,11 @@ StrictArgGetter(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue
|
||||
}
|
||||
|
||||
static bool
|
||||
StrictArgSetter(JSContext* cx, HandleObject obj, HandleId id, bool strict, MutableHandleValue vp)
|
||||
StrictArgSetter(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
if (!obj->is<StrictArgumentsObject>())
|
||||
return true;
|
||||
return result.succeed();
|
||||
Handle<StrictArgumentsObject*> argsobj = obj.as<StrictArgumentsObject>();
|
||||
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
@@ -456,7 +458,7 @@ StrictArgSetter(JSContext* cx, HandleObject obj, HandleId id, bool strict, Mutab
|
||||
unsigned arg = unsigned(JSID_TO_INT(id));
|
||||
if (arg < argsobj->initialLength()) {
|
||||
argsobj->setElement(cx, arg, vp);
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(JSID_IS_ATOM(id, cx->names().length));
|
||||
@@ -469,7 +471,7 @@ StrictArgSetter(JSContext* cx, HandleObject obj, HandleId id, bool strict, Mutab
|
||||
*/
|
||||
bool succeeded;
|
||||
return NativeDeleteProperty(cx, argsobj, id, &succeeded) &&
|
||||
NativeDefineProperty(cx, argsobj, id, vp, nullptr, nullptr, attrs);
|
||||
NativeDefineProperty(cx, argsobj, id, vp, nullptr, nullptr, attrs, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
||||
@@ -6720,8 +6720,7 @@ DebuggerObject_defineProperty(JSContext* cx, unsigned argc, Value* vp)
|
||||
return false;
|
||||
|
||||
ErrorCopier ec(ac);
|
||||
bool dummy;
|
||||
if (!StandardDefineProperty(cx, obj, id, desc, true, &dummy))
|
||||
if (!StandardDefineProperty(cx, obj, id, desc))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6764,8 +6763,7 @@ DebuggerObject_defineProperties(JSContext* cx, unsigned argc, Value* vp)
|
||||
|
||||
ErrorCopier ec(ac);
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
bool dummy;
|
||||
if (!StandardDefineProperty(cx, obj, ids[i], descs[i], true, &dummy))
|
||||
if (!StandardDefineProperty(cx, obj, ids[i], descs[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -7512,7 +7510,7 @@ DebuggerEnv_setVariable(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
/* Just set the property. */
|
||||
if (!SetProperty(cx, env, env, id, &v, true))
|
||||
if (!SetProperty(cx, env, env, id, &v))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -607,7 +607,10 @@ class GlobalObject : public NativeObject
|
||||
#endif
|
||||
RootedObject holder(cx, intrinsicsHolder());
|
||||
RootedValue valCopy(cx, value);
|
||||
return SetProperty(cx, holder, holder, name, &valCopy, false);
|
||||
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,
|
||||
|
||||
+12
-11
@@ -313,19 +313,20 @@ SetNameOperation(JSContext* cx, JSScript* script, jsbytecode* pc, HandleObject s
|
||||
RootedPropertyName name(cx, script->getName(pc));
|
||||
RootedValue valCopy(cx, val);
|
||||
|
||||
/*
|
||||
* In strict-mode, we need to trigger an error when trying to assign to an
|
||||
* undeclared global variable. To do this, we call NativeSetProperty
|
||||
* directly and pass Unqualified.
|
||||
*/
|
||||
// In strict mode, assigning to an undeclared global variable is an
|
||||
// error. To detect this, we call NativeSetProperty directly and pass
|
||||
// Unqualified. It stores the error, if any, in |result|.
|
||||
bool ok;
|
||||
ObjectOpResult result;
|
||||
RootedId id(cx, NameToId(name));
|
||||
if (scope->isUnqualifiedVarObj()) {
|
||||
MOZ_ASSERT(!scope->getOps()->setProperty);
|
||||
RootedId id(cx, NameToId(name));
|
||||
return NativeSetProperty(cx, scope.as<NativeObject>(), scope.as<NativeObject>(), id,
|
||||
Unqualified, &valCopy, strict);
|
||||
ok = NativeSetProperty(cx, scope.as<NativeObject>(), scope.as<NativeObject>(), id,
|
||||
Unqualified, &valCopy, result);
|
||||
} else {
|
||||
ok = SetProperty(cx, scope, scope, id, &valCopy, result);
|
||||
}
|
||||
|
||||
return SetProperty(cx, scope, scope, name, &valCopy, strict);
|
||||
return ok && result.checkStrictErrorOrWarning(cx, scope, id, strict);
|
||||
}
|
||||
|
||||
inline bool
|
||||
@@ -339,7 +340,7 @@ InitPropertyOperation(JSContext *cx, JSOp op, HandleObject obj, HandleId id, Han
|
||||
|
||||
MOZ_ASSERT(obj->as<UnboxedPlainObject>().layout().lookup(id));
|
||||
RootedValue v(cx, rhs);
|
||||
return SetProperty(cx, obj, obj, id, &v, false);
|
||||
return PutProperty(cx, obj, id, &v, false);
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
||||
@@ -310,19 +310,19 @@ SetObjectProperty(JSContext* cx, JSOp op, HandleValue lval, HandleId id, Mutable
|
||||
|
||||
RootedObject obj(cx, &lval.toObject());
|
||||
|
||||
bool strict = op == JSOP_STRICTSETPROP;
|
||||
ObjectOpResult result;
|
||||
if (MOZ_LIKELY(!obj->getOps()->setProperty)) {
|
||||
if (!NativeSetProperty(cx, obj.as<NativeObject>(), obj.as<NativeObject>(), id,
|
||||
Qualified, rref, strict))
|
||||
Qualified, rref, result))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!SetProperty(cx, obj, obj, id, rref, strict))
|
||||
if (!SetProperty(cx, obj, obj, id, rref, result))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return result.checkStrictErrorOrWarning(cx, obj, id, op == JSOP_STRICTSETPROP);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -1425,7 +1425,7 @@ SetObjectElementOperation(JSContext* cx, Handle<JSObject*> obj, HandleId id, con
|
||||
return false;
|
||||
|
||||
RootedValue tmp(cx, value);
|
||||
return SetProperty(cx, obj, obj, id, &tmp, strict);
|
||||
return PutProperty(cx, obj, id, &tmp, strict);
|
||||
}
|
||||
|
||||
static MOZ_NEVER_INLINE bool
|
||||
@@ -3859,7 +3859,7 @@ js::DefFunOperation(JSContext* cx, HandleScript script, HandleObject scopeChain,
|
||||
*/
|
||||
|
||||
/* Step 5f. */
|
||||
return SetProperty(cx, parent, parent, name, &rval, script->strict());
|
||||
return PutProperty(cx, parent, name, &rval, script->strict());
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -598,18 +598,6 @@ NativeLookupProperty(ExclusiveContext* cx, HandleNativeObject obj, PropertyName*
|
||||
return NativeLookupProperty<CanGC>(cx, obj, id, objp, propp);
|
||||
}
|
||||
|
||||
inline bool
|
||||
NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, PropertyName* name,
|
||||
HandleValue value, PropertyOp getter, StrictPropertyOp setter,
|
||||
unsigned attrs)
|
||||
{
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
|
||||
RootedId id(cx, NameToId(name));
|
||||
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
inline bool
|
||||
WarnIfNotConstructing(JSContext* cx, const CallArgs& args, const char* builtinName)
|
||||
{
|
||||
|
||||
+112
-95
@@ -1129,13 +1129,13 @@ UpdateShapeTypeAndValue(ExclusiveContext* cx, NativeObject* obj, Shape* shape, c
|
||||
|
||||
static bool
|
||||
NativeSet(JSContext* cx, HandleNativeObject obj, HandleObject receiver,
|
||||
HandleShape shape, bool strict, MutableHandleValue vp);
|
||||
HandleShape shape, MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
static inline bool
|
||||
DefinePropertyOrElement(ExclusiveContext* cx, HandleNativeObject obj, HandleId id,
|
||||
PropertyOp getter, StrictPropertyOp setter,
|
||||
unsigned attrs, HandleValue value,
|
||||
bool callSetterAfterwards, bool setterIsStrict)
|
||||
bool callSetterAfterwards, ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
@@ -1149,20 +1149,17 @@ DefinePropertyOrElement(ExclusiveContext* cx, HandleNativeObject obj, HandleId i
|
||||
!IsAnyTypedArray(obj))
|
||||
{
|
||||
uint32_t index = JSID_TO_INT(id);
|
||||
bool definesPast;
|
||||
if (!WouldDefinePastNonwritableLength(cx, obj, index, setterIsStrict, &definesPast))
|
||||
return false;
|
||||
if (definesPast)
|
||||
return true;
|
||||
if (WouldDefinePastNonwritableLength(obj, index))
|
||||
return result.fail(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH);
|
||||
|
||||
NativeObject::EnsureDenseResult result;
|
||||
result = obj->ensureDenseElements(cx, index, 1);
|
||||
|
||||
if (result == NativeObject::ED_FAILED)
|
||||
NativeObject::EnsureDenseResult edResult = obj->ensureDenseElements(cx, index, 1);
|
||||
if (edResult == NativeObject::ED_FAILED)
|
||||
return false;
|
||||
if (result == NativeObject::ED_OK) {
|
||||
if (edResult == NativeObject::ED_OK) {
|
||||
obj->setDenseElementWithType(cx, index, value);
|
||||
return CallAddPropertyHookDense(cx, obj, index, value);
|
||||
if (!CallAddPropertyHookDense(cx, obj, index, value))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1171,16 +1168,13 @@ DefinePropertyOrElement(ExclusiveContext* cx, HandleNativeObject obj, HandleId i
|
||||
if (id == NameToId(cx->names().length)) {
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
return ArraySetLength(cx->asJSContext(), arr, id, attrs, value, setterIsStrict);
|
||||
return ArraySetLength(cx->asJSContext(), arr, id, attrs, value, result);
|
||||
}
|
||||
|
||||
uint32_t index;
|
||||
if (IdIsIndex(id, &index)) {
|
||||
bool definesPast;
|
||||
if (!WouldDefinePastNonwritableLength(cx, arr, index, setterIsStrict, &definesPast))
|
||||
return false;
|
||||
if (definesPast)
|
||||
return true;
|
||||
if (WouldDefinePastNonwritableLength(obj, index))
|
||||
return result.fail(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1188,7 +1182,7 @@ DefinePropertyOrElement(ExclusiveContext* cx, HandleNativeObject obj, HandleId i
|
||||
if (IsAnyTypedArray(obj)) {
|
||||
uint64_t index;
|
||||
if (IsTypedArrayIndex(id, &index))
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
|
||||
@@ -1210,12 +1204,14 @@ DefinePropertyOrElement(ExclusiveContext* cx, HandleNativeObject obj, HandleId i
|
||||
|
||||
uint32_t index = JSID_TO_INT(id);
|
||||
NativeObject::removeDenseElementForSparseIndex(cx, obj, index);
|
||||
NativeObject::EnsureDenseResult result = NativeObject::maybeDensifySparseElements(cx, obj);
|
||||
if (result == NativeObject::ED_FAILED)
|
||||
NativeObject::EnsureDenseResult edResult = NativeObject::maybeDensifySparseElements(cx, obj);
|
||||
if (edResult == NativeObject::ED_FAILED)
|
||||
return false;
|
||||
if (result == NativeObject::ED_OK) {
|
||||
if (edResult == NativeObject::ED_OK) {
|
||||
MOZ_ASSERT(!setter);
|
||||
return CallAddPropertyHookDense(cx, obj, index, value);
|
||||
if (!CallAddPropertyHookDense(cx, obj, index, value))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1226,9 +1222,10 @@ DefinePropertyOrElement(ExclusiveContext* cx, HandleNativeObject obj, HandleId i
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
RootedValue nvalue(cx, value);
|
||||
return NativeSet(cx->asJSContext(), obj, obj, shape, setterIsStrict, &nvalue);
|
||||
return NativeSet(cx->asJSContext(), obj, obj, shape, &nvalue, result);
|
||||
}
|
||||
return true;
|
||||
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
static unsigned
|
||||
@@ -1341,7 +1338,8 @@ CheckAccessorRedefinition(ExclusiveContext* cx, HandleObject obj, HandleShape sh
|
||||
|
||||
bool
|
||||
js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId id, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
@@ -1369,7 +1367,7 @@ js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
|
||||
if (IsImplicitDenseOrTypedArrayElement(shape)) {
|
||||
if (IsAnyTypedArray(obj)) {
|
||||
/* Ignore getter/setter properties added to typed arrays. */
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
if (!NativeObject::sparsifyDenseElement(cx, obj, JSID_TO_INT(id)))
|
||||
return false;
|
||||
@@ -1434,11 +1432,11 @@ js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
|
||||
if (IsImplicitDenseOrTypedArrayElement(shape)) {
|
||||
if (IsAnyTypedArray(obj)) {
|
||||
/*
|
||||
* Silently ignore attempts to change individial index attributes.
|
||||
* Silently ignore attempts to change individual index attributes.
|
||||
* FIXME: Uses the same broken behavior as for accessors. This should
|
||||
* probably throw.
|
||||
* fail.
|
||||
*/
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
if (!NativeObject::sparsifyDenseElement(cx, obj, JSID_TO_INT(id)))
|
||||
return false;
|
||||
@@ -1485,14 +1483,16 @@ js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
|
||||
// relevant, just clear it.
|
||||
attrs = ApplyOrDefaultAttributes(attrs) & ~JSPROP_IGNORE_VALUE;
|
||||
return DefinePropertyOrElement(cx, obj, id, getter, setter,
|
||||
attrs, updateValue, false, false);
|
||||
attrs, updateValue, false, result);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(shape);
|
||||
|
||||
JS_ALWAYS_TRUE(UpdateShapeTypeAndValue(cx, obj, shape, updateValue));
|
||||
|
||||
return CallAddPropertyHook(cx, obj, shape, updateValue);
|
||||
if (!CallAddPropertyHook(cx, obj, shape, updateValue))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
@@ -1546,13 +1546,23 @@ js::NativeLookupElement(JSContext* cx, HandleNativeObject obj, uint32_t index,
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeDefineElement(ExclusiveContext* cx, HandleNativeObject obj, uint32_t index, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyName *name,
|
||||
HandleValue value, PropertyOp getter, StrictPropertyOp setter,
|
||||
unsigned attrs, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeDefineElement(ExclusiveContext *cx, HandleNativeObject obj, uint32_t index,
|
||||
HandleValue value, PropertyOp getter, StrictPropertyOp setter,
|
||||
unsigned attrs, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (index <= JSID_INT_MAX) {
|
||||
id = INT_TO_JSID(index);
|
||||
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs);
|
||||
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs, result);
|
||||
}
|
||||
|
||||
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
|
||||
@@ -1560,6 +1570,35 @@ js::NativeDefineElement(ExclusiveContext* cx, HandleNativeObject obj, uint32_t i
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
|
||||
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
HandleValue value, PropertyOp getter, StrictPropertyOp setter,
|
||||
unsigned attrs)
|
||||
{
|
||||
ObjectOpResult result;
|
||||
if (!NativeDefineProperty(cx, obj, id, value, getter, setter, attrs, result))
|
||||
return false;
|
||||
if (!result) {
|
||||
// Off-main-thread callers should not get here: they must call this
|
||||
// function only with known-valid arguments. Populating a new
|
||||
// PlainObject with configurable properties is fine.
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
result.reportError(cx->asJSContext(), obj, id);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyName *name,
|
||||
HandleValue value, PropertyOp getter, StrictPropertyOp setter,
|
||||
unsigned attrs)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
@@ -1961,7 +2000,7 @@ MaybeReportUndeclaredVarAssignment(JSContext* cx, JSString* propname)
|
||||
*/
|
||||
bool
|
||||
js::SetPropertyByDefining(JSContext* cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, HandleValue v, bool strict, bool objHasOwn)
|
||||
HandleId id, HandleValue v, bool objHasOwn, ObjectOpResult &result)
|
||||
{
|
||||
// Step 5.c-d: Test whether receiver has an existing own property
|
||||
// receiver[id]. The spec calls [[GetOwnProperty]]; js::HasOwnProperty is
|
||||
@@ -1992,15 +2031,8 @@ js::SetPropertyByDefining(JSContext* cx, HandleObject obj, HandleObject receiver
|
||||
bool extensible;
|
||||
if (!IsExtensible(cx, receiver, &extensible))
|
||||
return false;
|
||||
if (!extensible) {
|
||||
// Error in strict mode code, warn with extra warnings option,
|
||||
// otherwise do nothing.
|
||||
if (strict)
|
||||
return receiver->reportNotExtensible(cx);
|
||||
if (cx->compartment()->options().extraWarnings(cx))
|
||||
return receiver->reportNotExtensible(cx, JSREPORT_STRICT | JSREPORT_WARNING);
|
||||
return true;
|
||||
}
|
||||
if (!extensible)
|
||||
return result.fail(JSMSG_OBJECT_NOT_EXTENSIBLE);
|
||||
}
|
||||
|
||||
// Invalidate SpiderMonkey-specific caches or bail.
|
||||
@@ -2020,37 +2052,24 @@ js::SetPropertyByDefining(JSContext* cx, HandleObject obj, HandleObject receiver
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
if (!receiver->is<NativeObject>())
|
||||
return DefineProperty(cx, receiver, id, v, getter, setter, attrs);
|
||||
return DefineProperty(cx, receiver, id, v, getter, setter, attrs, result);
|
||||
|
||||
Rooted<NativeObject*> nativeReceiver(cx, &receiver->as<NativeObject>());
|
||||
return DefinePropertyOrElement(cx, nativeReceiver, id, getter, setter, attrs, v, true, strict);
|
||||
return DefinePropertyOrElement(cx, nativeReceiver, id, getter, setter, attrs, v, true, result);
|
||||
}
|
||||
|
||||
// When setting |id| for |receiver| and |obj| has no property for id, continue
|
||||
// the search up the prototype chain.
|
||||
bool
|
||||
js::SetPropertyOnProto(JSContext* cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, bool strict)
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(!obj->is<ProxyObject>());
|
||||
|
||||
RootedObject proto(cx, obj->getProto());
|
||||
if (proto)
|
||||
return SetProperty(cx, proto, receiver, id, vp, strict);
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, strict, false);
|
||||
}
|
||||
|
||||
bool
|
||||
js::SetNonWritableProperty(JSContext* cx, HandleId id, bool strict)
|
||||
{
|
||||
// Setting a non-writable property is an error in strict mode code, a
|
||||
// warning with the extra warnings option, and otherwise does nothing.
|
||||
|
||||
if (strict)
|
||||
return JSObject::reportReadOnly(cx, id, JSREPORT_ERROR);
|
||||
if (cx->compartment()->options().extraWarnings(cx))
|
||||
return JSObject::reportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING);
|
||||
return true;
|
||||
return SetProperty(cx, proto, receiver, id, vp, result);
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2064,7 +2083,7 @@ js::SetNonWritableProperty(JSContext* cx, HandleId id, bool strict)
|
||||
*/
|
||||
static bool
|
||||
SetNonexistentProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
|
||||
QualifiedBool qualified, HandleValue v, bool strict)
|
||||
QualifiedBool qualified, HandleValue v, ObjectOpResult &result)
|
||||
{
|
||||
// We should never add properties to lexical blocks.
|
||||
MOZ_ASSERT(!receiver->is<BlockObject>());
|
||||
@@ -2074,7 +2093,7 @@ SetNonexistentProperty(JSContext* cx, HandleNativeObject obj, HandleObject recei
|
||||
return false;
|
||||
}
|
||||
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, v, strict, false);
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, v, false, result);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2083,7 +2102,7 @@ SetNonexistentProperty(JSContext* cx, HandleNativeObject obj, HandleObject recei
|
||||
*/
|
||||
static bool
|
||||
SetDenseOrTypedArrayElement(JSContext* cx, HandleNativeObject obj, uint32_t index,
|
||||
MutableHandleValue vp, bool strict)
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
if (IsAnyTypedArray(obj)) {
|
||||
double d;
|
||||
@@ -2100,20 +2119,17 @@ SetDenseOrTypedArrayElement(JSContext* cx, HandleNativeObject obj, uint32_t inde
|
||||
else
|
||||
SharedTypedArrayObject::setElement(obj->as<SharedTypedArrayObject>(), index, d);
|
||||
}
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
bool definesPast;
|
||||
if (!WouldDefinePastNonwritableLength(cx, obj, index, strict, &definesPast))
|
||||
return false;
|
||||
if (definesPast)
|
||||
return true;
|
||||
if (WouldDefinePastNonwritableLength(obj, index))
|
||||
return result.fail(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH);
|
||||
|
||||
if (!obj->maybeCopyElementsForWrite(cx))
|
||||
return false;
|
||||
|
||||
obj->setDenseElementWithType(cx, index, vp);
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2122,7 +2138,7 @@ SetDenseOrTypedArrayElement(JSContext* cx, HandleNativeObject obj, uint32_t inde
|
||||
*/
|
||||
static bool
|
||||
NativeSet(JSContext* cx, HandleNativeObject obj, HandleObject receiver,
|
||||
HandleShape shape, bool strict, MutableHandleValue vp)
|
||||
HandleShape shape, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(obj->isNative());
|
||||
|
||||
@@ -2134,7 +2150,7 @@ NativeSet(JSContext* cx, HandleNativeObject obj, HandleObject receiver,
|
||||
// assignments to such properties as overwrites.
|
||||
bool overwriting = !obj->is<GlobalObject>() || !obj->getSlot(shape->slot()).isUndefined();
|
||||
obj->setSlotWithType(cx, shape, vp, overwriting);
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2146,13 +2162,13 @@ NativeSet(JSContext* cx, HandleNativeObject obj, HandleObject receiver,
|
||||
* or throw if we're in strict mode.
|
||||
*/
|
||||
if (!shape->hasGetterValue() && shape->hasDefaultSetter())
|
||||
return ReportGetterOnlyAssignment(cx, strict);
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
}
|
||||
|
||||
RootedValue ovp(cx, vp);
|
||||
|
||||
uint32_t sample = cx->runtime()->propertyRemovals;
|
||||
if (!shape->set(cx, obj, receiver, strict, vp))
|
||||
if (!shape->set(cx, obj, receiver, vp, result))
|
||||
return false;
|
||||
|
||||
/*
|
||||
@@ -2166,7 +2182,7 @@ NativeSet(JSContext* cx, HandleNativeObject obj, HandleObject receiver,
|
||||
obj->setSlot(shape->slot(), vp);
|
||||
}
|
||||
|
||||
return true;
|
||||
return true; // result is populated by shape->set() above.
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2178,30 +2194,31 @@ NativeSet(JSContext* cx, HandleNativeObject obj, HandleObject receiver,
|
||||
*/
|
||||
static bool
|
||||
SetExistingProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
|
||||
HandleNativeObject pobj, HandleShape shape, MutableHandleValue vp, bool strict)
|
||||
HandleNativeObject pobj, HandleShape shape, MutableHandleValue vp,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
if (IsImplicitDenseOrTypedArrayElement(shape)) {
|
||||
/* 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, strict);
|
||||
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 ReportGetterOnlyAssignment(cx, strict);
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
} else {
|
||||
MOZ_ASSERT(shape->isDataDescriptor());
|
||||
|
||||
if (!shape->writable())
|
||||
return SetNonWritableProperty(cx, id, strict);
|
||||
return result.fail(JSMSG_READ_ONLY);
|
||||
}
|
||||
|
||||
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(), vp, strict);
|
||||
return ArraySetLength(cx, arr, id, shape->attributes(), vp, result);
|
||||
}
|
||||
return NativeSet(cx, obj, receiver, shape, strict, vp);
|
||||
return NativeSet(cx, obj, receiver, shape, vp, result);
|
||||
}
|
||||
|
||||
// pobj[id] is not an own property of receiver. Call the setter or shadow it.
|
||||
@@ -2210,19 +2227,19 @@ SetExistingProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiver
|
||||
{
|
||||
// Weird special case: slotless property with default setter.
|
||||
if (shape->hasDefaultSetter() && !shape->hasGetterValue())
|
||||
return true;
|
||||
return result.succeed();
|
||||
|
||||
return shape->set(cx, obj, receiver, strict, vp);
|
||||
return shape->set(cx, obj, receiver, vp, result);
|
||||
}
|
||||
}
|
||||
|
||||
// Shadow pobj[id] by defining a new data property receiver[id].
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, strict, obj == pobj);
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, obj == pobj, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
|
||||
QualifiedBool qualified, MutableHandleValue vp, bool strict)
|
||||
QualifiedBool qualified, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
// Fire watchpoints, if any.
|
||||
if (MOZ_UNLIKELY(obj->watched())) {
|
||||
@@ -2248,7 +2265,7 @@ js::NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiv
|
||||
|
||||
if (shape) {
|
||||
// Steps 5-6.
|
||||
return SetExistingProperty(cx, obj, receiver, id, pobj, shape, vp, strict);
|
||||
return SetExistingProperty(cx, obj, receiver, id, pobj, shape, vp, result);
|
||||
}
|
||||
|
||||
// Steps 4.a-b. The check for 'done' on this next line is tricky.
|
||||
@@ -2262,7 +2279,7 @@ js::NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiv
|
||||
RootedObject proto(cx, done ? nullptr : pobj->getProto());
|
||||
if (!proto) {
|
||||
// Step 4.d.i (and step 5).
|
||||
return SetNonexistentProperty(cx, obj, receiver, id, qualified, vp, strict);
|
||||
return SetNonexistentProperty(cx, obj, receiver, id, qualified, vp, result);
|
||||
}
|
||||
|
||||
// Step 4.c.i. If the prototype is also native, this step is a
|
||||
@@ -2279,10 +2296,10 @@ js::NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiv
|
||||
if (!HasProperty(cx, proto, id, &found))
|
||||
return false;
|
||||
if (!found)
|
||||
return SetNonexistentProperty(cx, obj, receiver, id, qualified, vp, strict);
|
||||
return SetNonexistentProperty(cx, obj, receiver, id, qualified, vp, result);
|
||||
}
|
||||
|
||||
return SetProperty(cx, proto, receiver, id, vp, strict);
|
||||
return SetProperty(cx, proto, receiver, id, vp, result);
|
||||
}
|
||||
pobj = &proto->as<NativeObject>();
|
||||
}
|
||||
@@ -2290,12 +2307,12 @@ js::NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiv
|
||||
|
||||
bool
|
||||
js::NativeSetElement(JSContext* cx, HandleNativeObject obj, HandleObject receiver, uint32_t index,
|
||||
MutableHandleValue vp, bool strict)
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx);
|
||||
if (!IndexToId(cx, index, &id))
|
||||
return false;
|
||||
return NativeSetProperty(cx, obj, receiver, id, Qualified, vp, strict);
|
||||
return NativeSetProperty(cx, obj, receiver, id, Qualified, vp, result);
|
||||
}
|
||||
|
||||
/*** [[Delete]] **********************************************************************************/
|
||||
|
||||
+31
-28
@@ -83,12 +83,11 @@ class ArrayObject;
|
||||
*
|
||||
* |id| must be "length", |attrs| are the attributes to be used for the newly-
|
||||
* changed length property, |value| is the value for the new length, and
|
||||
* |setterIsStrict| indicates whether invalid changes will cause a TypeError
|
||||
* to be thrown.
|
||||
* |result| receives an error code if the change is invalid.
|
||||
*/
|
||||
extern bool
|
||||
ArraySetLength(JSContext* cx, Handle<ArrayObject*> obj, HandleId id,
|
||||
unsigned attrs, HandleValue value, bool setterIsStrict);
|
||||
unsigned attrs, HandleValue value, ObjectOpResult &result);
|
||||
|
||||
/*
|
||||
* Elements header used for native objects. The elements component of such objects
|
||||
@@ -189,7 +188,7 @@ class ObjectElements
|
||||
|
||||
friend bool
|
||||
ArraySetLength(JSContext* cx, Handle<ArrayObject*> obj, HandleId id,
|
||||
unsigned attrs, HandleValue value, bool setterIsStrict);
|
||||
unsigned attrs, HandleValue value, ObjectOpResult &result);
|
||||
|
||||
/* See Flags enum above. */
|
||||
uint32_t flags;
|
||||
@@ -347,10 +346,6 @@ class NativeObject : public JSObject
|
||||
/* Slots for object dense elements. */
|
||||
js::HeapSlot* elements_;
|
||||
|
||||
friend bool
|
||||
ArraySetLength(JSContext* cx, Handle<ArrayObject*> obj, HandleId id, unsigned attrs,
|
||||
HandleValue value, bool setterIsStrict);
|
||||
|
||||
friend class ::JSObject;
|
||||
|
||||
private:
|
||||
@@ -1238,16 +1233,28 @@ IsObjectValueInCompartment(Value v, JSCompartment* comp)
|
||||
|
||||
extern bool
|
||||
NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId id, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
|
||||
PropertyOp getter, StrictPropertyOp, unsigned attrs,
|
||||
ObjectOpResult &result);
|
||||
|
||||
inline bool
|
||||
extern bool
|
||||
NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, PropertyName* name,
|
||||
HandleValue value, PropertyOp getter, StrictPropertyOp setter,
|
||||
unsigned attrs);
|
||||
unsigned attrs, ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
NativeDefineElement(ExclusiveContext* cx, HandleNativeObject obj, uint32_t index, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
ObjectOpResult &result);
|
||||
|
||||
/* If the result out-param is omitted, throw on failure. */
|
||||
extern bool
|
||||
NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, HandleValue value,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
|
||||
|
||||
extern bool
|
||||
NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyName *name,
|
||||
HandleValue value, PropertyOp getter, StrictPropertyOp setter,
|
||||
unsigned attrs);
|
||||
|
||||
extern bool
|
||||
NativeHasProperty(JSContext* cx, HandleNativeObject obj, HandleId id, bool* foundp);
|
||||
@@ -1276,16 +1283,12 @@ NativeGetElement(JSContext* cx, HandleNativeObject obj, uint32_t index, MutableH
|
||||
}
|
||||
|
||||
bool
|
||||
SetPropertyByDefining(JSContext* cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, HandleValue v, bool strict, bool objHasOwn);
|
||||
SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
HandleValue v, bool objHasOwn, ObjectOpResult &result);
|
||||
|
||||
bool
|
||||
SetPropertyOnProto(JSContext* cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, bool strict);
|
||||
|
||||
// Report any error or warning when writing to a non-writable property.
|
||||
bool
|
||||
SetNonWritableProperty(JSContext* cx, HandleId id, bool strict);
|
||||
SetPropertyOnProto(JSContext *cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
/*
|
||||
* Indicates whether an assignment operation is qualified (`x.y = 0`) or
|
||||
@@ -1301,11 +1304,11 @@ enum QualifiedBool {
|
||||
|
||||
extern bool
|
||||
NativeSetProperty(JSContext* cx, HandleNativeObject obj, HandleObject receiver, HandleId id,
|
||||
QualifiedBool qualified, MutableHandleValue vp, bool strict);
|
||||
QualifiedBool qualified, MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
NativeSetElement(JSContext* cx, HandleNativeObject obj, HandleObject receiver, uint32_t index,
|
||||
MutableHandleValue vp, bool strict);
|
||||
MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
NativeDeleteProperty(JSContext* cx, HandleNativeObject obj, HandleId id, bool* succeeded);
|
||||
@@ -1417,20 +1420,20 @@ js::GetPropertyNoGC(JSContext* cx, JSObject* obj, JSObject* receiver, jsid id, V
|
||||
|
||||
inline bool
|
||||
js::SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, bool strict)
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
if (obj->getOps()->setProperty)
|
||||
return JSObject::nonNativeSetProperty(cx, obj, receiver, id, vp, strict);
|
||||
return NativeSetProperty(cx, obj.as<NativeObject>(), receiver, id, Qualified, vp, strict);
|
||||
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, HandleObject receiver, uint32_t index,
|
||||
MutableHandleValue vp, bool strict)
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
if (obj->getOps()->setProperty)
|
||||
return JSObject::nonNativeSetElement(cx, obj, receiver, index, vp, strict);
|
||||
return NativeSetElement(cx, obj.as<NativeObject>(), receiver, index, vp, strict);
|
||||
return JSObject::nonNativeSetElement(cx, obj, receiver, index, vp, result);
|
||||
return NativeSetElement(cx, obj.as<NativeObject>(), receiver, index, vp, result);
|
||||
}
|
||||
|
||||
#endif /* vm_NativeObject_h */
|
||||
|
||||
+14
-18
@@ -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, callobj, id, &optimizedOut, true))
|
||||
if (!SetProperty(cx, callobj, callobj, id, &optimizedOut))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -503,10 +503,11 @@ with_LookupProperty(JSContext* cx, HandleObject obj, HandleId id,
|
||||
|
||||
static bool
|
||||
with_DefineProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
return DefineProperty(cx, actual, id, value, getter, setter, attrs);
|
||||
return DefineProperty(cx, actual, id, value, getter, setter, attrs, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -534,13 +535,13 @@ with_GetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleI
|
||||
|
||||
static bool
|
||||
with_SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, bool strict)
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
|
||||
RootedObject actualReceiver(cx, receiver);
|
||||
if (receiver == obj)
|
||||
actualReceiver = actual;
|
||||
return SetProperty(cx, actual, actualReceiver, id, vp, strict);
|
||||
return SetProperty(cx, actual, actualReceiver, id, vp, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -1009,7 +1010,7 @@ uninitialized_GetProperty(JSContext* cx, HandleObject obj, HandleObject receiver
|
||||
|
||||
static bool
|
||||
uninitialized_SetProperty(JSContext* cx, HandleObject obj, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, bool strict)
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
ReportUninitializedLexicalId(cx, id);
|
||||
return false;
|
||||
@@ -1671,8 +1672,8 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
}
|
||||
}
|
||||
|
||||
bool set(JSContext* cx, HandleObject proxy, HandleObject receiver, HandleId id, bool strict,
|
||||
MutableHandleValue vp) const override
|
||||
bool set(JSContext *cx, HandleObject proxy, HandleObject receiver, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result) const MOZ_OVERRIDE
|
||||
{
|
||||
Rooted<DebugScopeObject*> debugScope(cx, &proxy->as<DebugScopeObject>());
|
||||
Rooted<ScopeObject*> scope(cx, &proxy->as<DebugScopeObject>().scope());
|
||||
@@ -1686,16 +1687,17 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
|
||||
switch (access) {
|
||||
case ACCESS_UNALIASED:
|
||||
return true;
|
||||
return result.succeed();
|
||||
case ACCESS_GENERIC:
|
||||
return SetProperty(cx, scope, scope, id, vp, strict);
|
||||
return SetProperty(cx, scope, scope, id, vp, result);
|
||||
default:
|
||||
MOZ_CRASH("bad AccessResult");
|
||||
}
|
||||
}
|
||||
|
||||
bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const override
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE
|
||||
{
|
||||
Rooted<ScopeObject*> scope(cx, &proxy->as<DebugScopeObject>().scope());
|
||||
|
||||
@@ -1705,13 +1707,7 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
if (found)
|
||||
return Throw(cx, id, JSMSG_CANT_REDEFINE_PROP);
|
||||
|
||||
return JS_DefinePropertyById(cx, scope, id, desc.value(),
|
||||
// Descriptors never store JSNatives for
|
||||
// accessors: they have either JSFunctions
|
||||
// or JSPropertyOps.
|
||||
desc.attributes() | JSPROP_PROPOP_ACCESSORS,
|
||||
JS_PROPERTYOP_GETTER(desc.getter()),
|
||||
JS_PROPERTYOP_SETTER(desc.setter()));
|
||||
return JS_DefinePropertyById(cx, scope, id, desc, result);
|
||||
}
|
||||
|
||||
bool ownPropertyKeys(JSContext* cx, HandleObject proxy, AutoIdVector& props) const override
|
||||
|
||||
@@ -373,7 +373,8 @@ js::intrinsic_UnsafePutElements(JSContext* cx, unsigned argc, Value* vp)
|
||||
MOZ_ASSERT_IF(arrobj->is<TypedObject>(), idx < uint32_t(arrobj->as<TypedObject>().length()));
|
||||
RootedValue tmp(cx, args[elemi]);
|
||||
// XXX: Always non-strict.
|
||||
if (!SetElement(cx, arrobj, arrobj, idx, &tmp, false))
|
||||
ObjectOpResult ignored;
|
||||
if (!SetElement(cx, arrobj, arrobj, idx, &tmp, ignored))
|
||||
return false;
|
||||
} else {
|
||||
MOZ_ASSERT(idx < arrobj->as<ArrayObject>().getDenseInitializedLength());
|
||||
@@ -421,8 +422,7 @@ js::intrinsic_DefineDataProperty(JSContext* cx, unsigned argc, Value* vp)
|
||||
|
||||
desc = PropDesc(value, writable, enumerable, configurable);
|
||||
|
||||
bool result;
|
||||
return StandardDefineProperty(cx, obj, id, desc, true, &result);
|
||||
return StandardDefineProperty(cx, obj, id, desc);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -41,25 +41,27 @@ Shape::search(ExclusiveContext* cx, jsid id)
|
||||
}
|
||||
|
||||
inline bool
|
||||
Shape::set(JSContext* cx, HandleNativeObject obj, HandleObject receiver, bool strict,
|
||||
MutableHandleValue vp)
|
||||
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();
|
||||
return InvokeGetterOrSetter(cx, receiver, fval, 1, vp.address(), vp);
|
||||
if (!InvokeGetterOrSetter(cx, receiver, fval, 1, vp.address(), vp))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
if (attrs & JSPROP_GETTER)
|
||||
return ReportGetterOnlyAssignment(cx, strict);
|
||||
return result.fail(JSMSG_GETTER_ONLY);
|
||||
|
||||
if (!setterOp())
|
||||
return true;
|
||||
return result.succeed();
|
||||
|
||||
RootedId id(cx, propid());
|
||||
return CallJSPropertyOpSetter(cx, setterOp(), obj, id, strict, vp);
|
||||
return CallJSPropertyOpSetter(cx, setterOp(), obj, id, vp, result);
|
||||
}
|
||||
|
||||
/* static */ inline Shape*
|
||||
|
||||
+2
-2
@@ -959,8 +959,8 @@ class Shape : public gc::TenuredCell
|
||||
setter() == rawSetter;
|
||||
}
|
||||
|
||||
bool set(JSContext* cx, HandleNativeObject obj, HandleObject receiver, bool strict,
|
||||
MutableHandleValue vp);
|
||||
bool set(JSContext* cx, HandleNativeObject obj, HandleObject receiver, MutableHandleValue vp,
|
||||
ObjectOpResult &result);
|
||||
|
||||
BaseShape* base() const { return base_.get(); }
|
||||
|
||||
|
||||
@@ -362,12 +362,13 @@ UnboxedPlainObject::obj_lookupProperty(JSContext* cx, HandleObject obj,
|
||||
|
||||
/* static */ bool
|
||||
UnboxedPlainObject::obj_defineProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
if (!convertToNative(cx, obj))
|
||||
return false;
|
||||
|
||||
return DefineProperty(cx, obj, id, v, getter, setter, attrs);
|
||||
return DefineProperty(cx, obj, id, v, getter, setter, attrs, result);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
@@ -409,24 +410,24 @@ UnboxedPlainObject::obj_getProperty(JSContext* cx, HandleObject obj, HandleObjec
|
||||
|
||||
/* static */ bool
|
||||
UnboxedPlainObject::obj_setProperty(JSContext* cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, bool strict)
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
const UnboxedLayout& layout = obj->as<UnboxedPlainObject>().layout();
|
||||
|
||||
if (const UnboxedLayout::Property* property = layout.lookup(id)) {
|
||||
if (obj == receiver) {
|
||||
if (obj->as<UnboxedPlainObject>().setValue(cx, *property, vp))
|
||||
return true;
|
||||
return result.succeed();
|
||||
|
||||
if (!convertToNative(cx, obj))
|
||||
return false;
|
||||
return SetProperty(cx, obj, receiver, id, vp, strict);
|
||||
return SetProperty(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, strict, false);
|
||||
return SetPropertyByDefining(cx, obj, receiver, id, vp, false, result);
|
||||
}
|
||||
|
||||
return SetPropertyOnProto(cx, obj, receiver, id, vp, strict);
|
||||
return SetPropertyOnProto(cx, obj, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
|
||||
@@ -162,7 +162,8 @@ class UnboxedPlainObject : public JSObject
|
||||
MutableHandleShape propp);
|
||||
|
||||
static bool obj_defineProperty(JSContext* cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
|
||||
PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
|
||||
ObjectOpResult &result);
|
||||
|
||||
static bool obj_hasProperty(JSContext* cx, HandleObject obj, HandleId id, bool* foundp);
|
||||
|
||||
@@ -170,7 +171,7 @@ class UnboxedPlainObject : public JSObject
|
||||
HandleId id, MutableHandleValue vp);
|
||||
|
||||
static bool obj_setProperty(JSContext* cx, HandleObject obj, HandleObject receiver,
|
||||
HandleId id, MutableHandleValue vp, bool strict);
|
||||
HandleId id, MutableHandleValue vp, ObjectOpResult &result);
|
||||
|
||||
static bool obj_getOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
||||
+2
-2
@@ -29,11 +29,11 @@ namespace js {
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
|
||||
*/
|
||||
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 239;
|
||||
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 241;
|
||||
static const uint32_t XDR_BYTECODE_VERSION =
|
||||
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
|
||||
|
||||
static_assert(JSErr_Limit == 371,
|
||||
static_assert(JSErr_Limit == 373,
|
||||
"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 "
|
||||
|
||||
@@ -357,13 +357,14 @@ sandbox_convert(JSContext* cx, HandleObject obj, JSType type, MutableHandleValue
|
||||
|
||||
static bool
|
||||
writeToProto_setProperty(JSContext* cx, JS::HandleObject obj, JS::HandleId id,
|
||||
bool strict, JS::MutableHandleValue vp)
|
||||
JS::MutableHandleValue vp, JS::ObjectOpResult &result)
|
||||
{
|
||||
RootedObject proto(cx);
|
||||
if (!JS_GetPrototype(cx, obj, &proto))
|
||||
return false;
|
||||
|
||||
return JS_SetPropertyById(cx, proto, id, vp);
|
||||
RootedValue receiver(cx, ObjectValue(*proto));
|
||||
return JS_ForwardSetPropertyTo(cx, proto, id, vp, receiver, result);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -738,10 +739,10 @@ bool
|
||||
xpc::SandboxProxyHandler::set(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id,
|
||||
bool strict,
|
||||
JS::MutableHandle<Value> vp) const
|
||||
JS::MutableHandle<Value> vp,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
return BaseProxyHandler::set(cx, proxy, receiver, id, strict, vp);
|
||||
return BaseProxyHandler::set(cx, proxy, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -659,7 +659,8 @@ static const JSFunctionSpec glob_functions[] = {
|
||||
};
|
||||
|
||||
static bool
|
||||
env_setProperty(JSContext* cx, HandleObject obj, HandleId id, bool strict, MutableHandleValue vp)
|
||||
env_setProperty(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
/* XXX porting may be easy, but these don't seem to supply setenv by default */
|
||||
#if !defined SOLARIS
|
||||
@@ -709,7 +710,7 @@ env_setProperty(JSContext* cx, HandleObject obj, HandleId id, bool strict, Mutab
|
||||
}
|
||||
vp.set(STRING_TO_JSVAL(valstr));
|
||||
#endif /* !defined SOLARIS */
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
static bool
|
||||
|
||||
@@ -364,13 +364,7 @@ DefinePropertyIfFound(XPCCallContext& ccx,
|
||||
AutoResolveName arn(ccx, id);
|
||||
if (resolved)
|
||||
*resolved = true;
|
||||
return JS_DefinePropertyById(ccx, obj, id, desc.value(),
|
||||
// Descriptors never store JSNatives
|
||||
// for accessors: they have either
|
||||
// JSFunctions or JSPropertyOps.
|
||||
desc.attributes(),
|
||||
JS_PROPERTYOP_GETTER(desc.getter()),
|
||||
JS_PROPERTYOP_SETTER(desc.setter()));
|
||||
return JS_DefinePropertyById(ccx, obj, id, desc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -433,9 +427,10 @@ XPC_WN_OnlyIWrite_AddPropertyStub(JSContext* cx, HandleObject obj, HandleId id,
|
||||
}
|
||||
|
||||
static bool
|
||||
XPC_WN_OnlyIWrite_SetPropertyStub(JSContext* cx, HandleObject obj, HandleId id, bool strict,
|
||||
MutableHandleValue vp)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -454,10 +449,10 @@ XPC_WN_CantDeletePropertyStub(JSContext* cx, HandleObject obj, HandleId id,
|
||||
}
|
||||
|
||||
static bool
|
||||
XPC_WN_CannotModifyStrictPropertyStub(JSContext* cx, HandleObject obj, HandleId id, bool strict,
|
||||
MutableHandleValue vp)
|
||||
XPC_WN_CannotModifySetPropertyStub(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
return XPC_WN_CannotModifyPropertyStub(cx, obj, id, vp);
|
||||
return Throw(NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN, cx);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -713,9 +708,10 @@ XPC_WN_MaybeResolvingPropertyStub(JSContext* cx, HandleObject obj, HandleId id,
|
||||
}
|
||||
|
||||
static bool
|
||||
XPC_WN_MaybeResolvingStrictPropertyStub(JSContext* cx, HandleObject obj, HandleId id, bool strict,
|
||||
MutableHandleValue vp)
|
||||
XPC_WN_MaybeResolvingSetPropertyStub(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
result.succeed();
|
||||
return XPC_WN_MaybeResolvingPropertyStub(cx, obj, id, vp);
|
||||
}
|
||||
|
||||
@@ -753,6 +749,11 @@ XPC_WN_MaybeResolvingDeletePropertyStub(JSContext* cx, HandleObject obj, HandleI
|
||||
return Throw(rv, cx); \
|
||||
return retval;
|
||||
|
||||
#define POST_HELPER_STUB_WITH_OBJECTOPRESULT(failMethod) \
|
||||
if (NS_FAILED(rv)) \
|
||||
return Throw(rv, cx); \
|
||||
return retval ? result.succeed() : result.failMethod();
|
||||
|
||||
static bool
|
||||
XPC_WN_Helper_AddProperty(JSContext* cx, HandleObject obj, HandleId id,
|
||||
MutableHandleValue vp)
|
||||
@@ -772,12 +773,12 @@ XPC_WN_Helper_GetProperty(JSContext* cx, HandleObject obj, HandleId id,
|
||||
}
|
||||
|
||||
bool
|
||||
XPC_WN_Helper_SetProperty(JSContext* cx, HandleObject obj, HandleId id, bool strict,
|
||||
MutableHandleValue vp)
|
||||
XPC_WN_Helper_SetProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
MutableHandleValue vp, ObjectOpResult &result)
|
||||
{
|
||||
PRE_HELPER_STUB
|
||||
SetProperty(wrapper, cx, obj, id, vp.address(), &retval);
|
||||
POST_HELPER_STUB
|
||||
POST_HELPER_STUB_WITH_OBJECTOPRESULT(failReadOnly)
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -1029,9 +1030,9 @@ XPCNativeScriptableShared::PopulateJSClass()
|
||||
else if (mFlags.UseJSStubForSetProperty())
|
||||
setProperty = nullptr;
|
||||
else if (mFlags.AllowPropModsDuringResolve())
|
||||
setProperty = XPC_WN_MaybeResolvingStrictPropertyStub;
|
||||
setProperty = XPC_WN_MaybeResolvingSetPropertyStub;
|
||||
else
|
||||
setProperty = XPC_WN_CannotModifyStrictPropertyStub;
|
||||
setProperty = XPC_WN_CannotModifySetPropertyStub;
|
||||
mJSClass.base.setProperty = setProperty;
|
||||
|
||||
MOZ_ASSERT_IF(mFlags.WantEnumerate(), !mFlags.WantNewEnumerate());
|
||||
@@ -1358,9 +1359,10 @@ XPC_WN_OnlyIWrite_Proto_AddPropertyStub(JSContext* cx, HandleObject obj, HandleI
|
||||
}
|
||||
|
||||
static bool
|
||||
XPC_WN_OnlyIWrite_Proto_SetPropertyStub(JSContext* cx, HandleObject obj, HandleId id, bool strict,
|
||||
MutableHandleValue vp)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -120,14 +120,15 @@ AddonWrapper<Base>::get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle
|
||||
template<typename Base>
|
||||
bool
|
||||
AddonWrapper<Base>::set(JSContext* cx, JS::HandleObject wrapper, JS::HandleObject receiver,
|
||||
JS::HandleId id, bool strict, JS::MutableHandleValue vp) const
|
||||
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, receiver, id, strict, vp);
|
||||
return Base::set(cx, wrapper, receiver, id, vp, result);
|
||||
|
||||
if (desc.setter()) {
|
||||
MOZ_ASSERT(desc.hasSetterObject());
|
||||
@@ -135,27 +136,26 @@ AddonWrapper<Base>::set(JSContext* cx, JS::HandleObject wrapper, JS::HandleObjec
|
||||
JS::AutoValueVector args(cx);
|
||||
args.append(vp);
|
||||
RootedValue fval(cx, ObjectValue(*desc.setterObject()));
|
||||
return JS_CallFunctionValue(cx, receiver, fval, args, vp);
|
||||
} else {
|
||||
if (!strict)
|
||||
return true;
|
||||
|
||||
js::ReportErrorWithId(cx, "unable to set interposed data property %s", id);
|
||||
return false;
|
||||
if (!JS_CallFunctionValue(cx, receiver, fval, args, vp))
|
||||
return false;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
return result.failCantSetInterposed();
|
||||
}
|
||||
|
||||
template<typename Base>
|
||||
bool
|
||||
AddonWrapper<Base>::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
Rooted<JSPropertyDescriptor> interpDesc(cx);
|
||||
if (!Interpose(cx, wrapper, nullptr, id, &interpDesc))
|
||||
return false;
|
||||
|
||||
if (!interpDesc.object())
|
||||
return Base::defineProperty(cx, wrapper, id, desc);
|
||||
return Base::defineProperty(cx, wrapper, id, desc, result);
|
||||
|
||||
js::ReportErrorWithId(cx, "unable to modify interposed property %s", id);
|
||||
return false;
|
||||
|
||||
@@ -28,12 +28,14 @@ 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::MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool delete_(JSContext* cx, JS::HandleObject proxy, JS::HandleId id, 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::HandleObject wrapper, JS::HandleObject receiver,
|
||||
JS::HandleId id, bool strict, JS::MutableHandleValue vp) const override;
|
||||
JS::HandleId id, JS::MutableHandleValue vp,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
|
||||
virtual bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
|
||||
@@ -21,21 +21,22 @@ const ChromeObjectWrapper ChromeObjectWrapper::singleton;
|
||||
bool
|
||||
ChromeObjectWrapper::defineProperty(JSContext* cx, HandleObject wrapper,
|
||||
HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
if (!AccessCheck::checkPassToPrivilegedCode(cx, wrapper, desc.value()))
|
||||
return false;
|
||||
return ChromeObjectWrapperBase::defineProperty(cx, wrapper, id, desc);
|
||||
return ChromeObjectWrapperBase::defineProperty(cx, wrapper, id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
ChromeObjectWrapper::set(JSContext* cx, HandleObject wrapper,
|
||||
HandleObject receiver, HandleId id,
|
||||
bool strict, MutableHandleValue vp) const
|
||||
MutableHandleValue vp, ObjectOpResult &result) const
|
||||
{
|
||||
if (!AccessCheck::checkPassToPrivilegedCode(cx, wrapper, vp))
|
||||
return false;
|
||||
return ChromeObjectWrapperBase::set(cx, wrapper, receiver, id, strict, vp);
|
||||
return ChromeObjectWrapperBase::set(cx, wrapper, receiver, id, vp, result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,10 +29,12 @@ class ChromeObjectWrapper : public ChromeObjectWrapperBase
|
||||
|
||||
virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool set(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> receiver, JS::Handle<jsid> id,
|
||||
bool strict, JS::MutableHandle<JS::Value> vp) const override;
|
||||
JS::MutableHandle<JS::Value> vp,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
|
||||
static const ChromeObjectWrapper singleton;
|
||||
};
|
||||
|
||||
@@ -234,7 +234,8 @@ CrossOriginXrayWrapper::ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> wra
|
||||
bool
|
||||
CrossOriginXrayWrapper::defineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const
|
||||
{
|
||||
JS_ReportError(cx, "Permission denied to define property on cross-origin object");
|
||||
return false;
|
||||
|
||||
@@ -73,7 +73,8 @@ class CrossOriginXrayWrapper : public SecurityXrayDOM {
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
virtual bool defineProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::AutoIdVector& props) const override;
|
||||
virtual bool delete_(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
|
||||
@@ -568,9 +568,10 @@ JSXrayTraits::delete_(JSContext* cx, HandleObject wrapper, HandleId id, bool* bp
|
||||
|
||||
bool
|
||||
JSXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
bool* defined)
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
ObjectOpResult &result,
|
||||
bool *defined)
|
||||
{
|
||||
*defined = false;
|
||||
RootedObject holder(cx, ensureHolder(cx, wrapper));
|
||||
@@ -613,9 +614,7 @@ JSXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
|
||||
JSAutoCompartment ac(cx, target);
|
||||
if (!JS_WrapPropertyDescriptor(cx, desc) ||
|
||||
!JS_DefinePropertyById(cx, target, id, desc.value(),
|
||||
desc.attributes(),
|
||||
JS_STUBGETTER, JS_STUBSETTER))
|
||||
!JS_DefinePropertyById(cx, target, id, desc, result))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1190,13 +1189,7 @@ XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext* cx, HandleObject wr
|
||||
FillPropertyDescriptor(desc, wrapper, 0,
|
||||
ObjectValue(*JS_GetFunctionObject(toString)));
|
||||
|
||||
return JS_DefinePropertyById(cx, holder, id, desc.value(),
|
||||
// Descriptors never store JSNatives for
|
||||
// accessors: they have either JSFunctions
|
||||
// or JSPropertyOps.
|
||||
desc.attributes() | JSPROP_PROPOP_ACCESSORS,
|
||||
JS_PROPERTYOP_GETTER(desc.getter()),
|
||||
JS_PROPERTYOP_SETTER(desc.setter())) &&
|
||||
return JS_DefinePropertyById(cx, holder, id, desc) &&
|
||||
JS_GetPropertyDescriptorById(cx, holder, id, desc);
|
||||
}
|
||||
|
||||
@@ -1251,14 +1244,7 @@ XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext* cx, HandleObject wr
|
||||
if (desc.hasSetterObject())
|
||||
desc.setSetterObject(&fval.toObject());
|
||||
|
||||
// Define the property.
|
||||
return JS_DefinePropertyById(cx, holder, id, desc.value(),
|
||||
// Descriptors never store JSNatives for
|
||||
// accessors: they have either JSFunctions or
|
||||
// JSPropertyOps.
|
||||
desc.attributes() | JSPROP_PROPOP_ACCESSORS,
|
||||
JS_PROPERTYOP_GETTER(desc.getter()),
|
||||
JS_PROPERTYOP_SETTER(desc.setter()));
|
||||
return JS_DefinePropertyById(cx, holder, id, desc);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -1397,7 +1383,8 @@ XPCWrappedNativeXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsW
|
||||
bool
|
||||
XPCWrappedNativeXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc, bool* defined)
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
{
|
||||
*defined = false;
|
||||
RootedObject holder(cx, singleton.ensureHolder(cx, wrapper));
|
||||
@@ -1407,7 +1394,7 @@ XPCWrappedNativeXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper,
|
||||
int32_t index = GetArrayIndexFromId(cx, id);
|
||||
if (IsArrayIndex(index) && IsWindow(cx, wrapper)) {
|
||||
*defined = true;
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1550,20 +1537,15 @@ DOMXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper, Handl
|
||||
if (!desc.object() || !cacheOnHolder)
|
||||
return true;
|
||||
|
||||
return JS_DefinePropertyById(cx, holder, id, desc.value(),
|
||||
// Descriptors never store JSNatives for
|
||||
// accessors: they have either JSFunctions or
|
||||
// JSPropertyOps.
|
||||
desc.attributes() | JSPROP_PROPOP_ACCESSORS,
|
||||
JS_PROPERTYOP_GETTER(desc.getter()),
|
||||
JS_PROPERTYOP_SETTER(desc.setter())) &&
|
||||
return JS_DefinePropertyById(cx, holder, id, desc) &&
|
||||
JS_GetPropertyDescriptorById(cx, holder, id, desc);
|
||||
}
|
||||
|
||||
bool
|
||||
DOMXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc, bool* defined)
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
{
|
||||
// Check for an indexed property on a Window. If that's happening, do
|
||||
// nothing but claim we defined it so it won't get added as an expando.
|
||||
@@ -1571,12 +1553,12 @@ DOMXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
int32_t index = GetArrayIndexFromId(cx, id);
|
||||
if (IsArrayIndex(index)) {
|
||||
*defined = true;
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> obj(cx, getTargetObject(wrapper));
|
||||
return XrayDefineProperty(cx, wrapper, obj, id, desc, defined);
|
||||
return XrayDefineProperty(cx, wrapper, obj, id, desc, result, defined);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1874,13 +1856,7 @@ XrayWrapper<Base, Traits>::getPropertyDescriptor(JSContext* cx, HandleObject wra
|
||||
if (!desc.object())
|
||||
return true;
|
||||
|
||||
if (!JS_DefinePropertyById(cx, holder, id, desc.value(),
|
||||
// Descriptors never store JSNatives for
|
||||
// accessors: they have either JSFunctions or
|
||||
// JSPropertyOps.
|
||||
desc.attributes() | JSPROP_PROPOP_ACCESSORS,
|
||||
JS_PROPERTYOP_GETTER(desc.getter()),
|
||||
JS_PROPERTYOP_SETTER(desc.setter())) ||
|
||||
if (!JS_DefinePropertyById(cx, holder, id, desc) ||
|
||||
!JS_GetPropertyDescriptorById(cx, holder, id, desc))
|
||||
{
|
||||
return false;
|
||||
@@ -1967,8 +1943,8 @@ RecreateLostWaivers(JSContext* cx, JSPropertyDescriptor* orig,
|
||||
template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::defineProperty(JSContext* cx, HandleObject wrapper,
|
||||
HandleId id, MutableHandle<JSPropertyDescriptor> desc)
|
||||
const
|
||||
HandleId id, MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, wrapper, id, BaseProxyHandler::SET);
|
||||
|
||||
@@ -1990,17 +1966,17 @@ XrayWrapper<Base, Traits>::defineProperty(JSContext* cx, HandleObject wrapper,
|
||||
(existing_desc.isReadonly() && !desc.isReadonly()))
|
||||
{
|
||||
// We should technically report non-configurability in strict mode, but
|
||||
// doing that via JSAPI is a lot of trouble.
|
||||
return true;
|
||||
// doing that via JSAPI used to be a lot of trouble. See bug 1135997.
|
||||
return result.succeed();
|
||||
}
|
||||
if (existing_desc.isReadonly()) {
|
||||
// Same as the above for non-writability.
|
||||
return true;
|
||||
return result.succeed();
|
||||
}
|
||||
}
|
||||
|
||||
bool defined = false;
|
||||
if (!Traits::singleton.defineProperty(cx, wrapper, id, desc, existing_desc, &defined))
|
||||
if (!Traits::singleton.defineProperty(cx, wrapper, id, desc, existing_desc, result, &defined))
|
||||
return false;
|
||||
if (defined)
|
||||
return true;
|
||||
@@ -2025,13 +2001,7 @@ XrayWrapper<Base, Traits>::defineProperty(JSContext* cx, HandleObject wrapper,
|
||||
if (!RecreateLostWaivers(cx, desc.address(), &wrappedDesc))
|
||||
return false;
|
||||
|
||||
return JS_DefinePropertyById(cx, expandoObject, id, wrappedDesc.value(),
|
||||
// Descriptors never store JSNatives for
|
||||
// accessors: they have either JSFunctions
|
||||
// or JSPropertyOps.
|
||||
wrappedDesc.get().attrs | JSPROP_PROPOP_ACCESSORS,
|
||||
JS_PROPERTYOP_GETTER(wrappedDesc.getter()),
|
||||
JS_PROPERTYOP_SETTER(wrappedDesc.setter()));
|
||||
return JS_DefinePropertyById(cx, expandoObject, id, wrappedDesc, result);
|
||||
}
|
||||
|
||||
template <typename Base, typename Traits>
|
||||
@@ -2080,13 +2050,13 @@ template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::set(JSContext* cx, HandleObject wrapper,
|
||||
HandleObject receiver, HandleId id,
|
||||
bool strict, MutableHandleValue vp) const
|
||||
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.
|
||||
return js::BaseProxyHandler::set(cx, wrapper, wrapper, id, strict, vp);
|
||||
return js::BaseProxyHandler::set(cx, wrapper, wrapper, id, vp, result);
|
||||
}
|
||||
|
||||
template <typename Base, typename Traits>
|
||||
|
||||
@@ -126,7 +126,8 @@ public:
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) override;
|
||||
bool defineProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc, bool* defined);
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined);
|
||||
virtual bool enumerateNames(JSContext* cx, JS::HandleObject wrapper, unsigned flags,
|
||||
JS::AutoIdVector& props);
|
||||
static bool call(JSContext* cx, JS::HandleObject wrapper,
|
||||
@@ -177,7 +178,8 @@ public:
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) override;
|
||||
bool defineProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc, bool* defined);
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined);
|
||||
virtual bool enumerateNames(JSContext* cx, JS::HandleObject wrapper, unsigned flags,
|
||||
JS::AutoIdVector& props);
|
||||
static bool call(JSContext* cx, JS::HandleObject wrapper,
|
||||
@@ -219,7 +221,8 @@ public:
|
||||
|
||||
bool defineProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc, bool* defined);
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined);
|
||||
|
||||
virtual bool enumerateNames(JSContext* cx, JS::HandleObject wrapper, unsigned flags,
|
||||
JS::AutoIdVector& props);
|
||||
@@ -336,7 +339,8 @@ public:
|
||||
|
||||
bool defineProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc, bool* defined)
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
{
|
||||
*defined = false;
|
||||
return true;
|
||||
@@ -408,7 +412,8 @@ 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::MutableHandle<JSPropertyDescriptor> desc) const override;
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::AutoIdVector& props) const override;
|
||||
virtual bool delete_(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
@@ -428,7 +433,8 @@ class XrayWrapper : public Base {
|
||||
virtual bool get(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
|
||||
virtual bool set(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id, bool strict, JS::MutableHandle<JS::Value> vp) const override;
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool call(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
const JS::CallArgs& args) const override;
|
||||
virtual bool construct(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
@@ -501,7 +507,8 @@ public:
|
||||
virtual bool get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
|
||||
virtual bool set(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id, bool strict, JS::MutableHandle<JS::Value> vp) const override;
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
|
||||
virtual bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
|
||||
Reference in New Issue
Block a user