mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1113369, part 3 - [[DefineOwnProperty]] ObjectOpResult support. r=Waldo, r=bz in dom, r=dvander in js/ipc, r=bholley in js/xpconnect.
Add an ObjectOpResult out-param for DefineProperty functions everywhere. We leave a few js::DefineProperty() convenience functions with no *result out-param. These have strict behavior: that is, they automatically check the result and throw if it is false. In bug 1125624 these strict signatures may end up being called DefinePropertyOrThrow, as that is what the spec calls it.
This commit is contained in:
parent
143ed465ec
commit
f43c96af4d
@ -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 MOZ_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 MOZ_OVERRIDE;
|
||||
|
@ -1174,13 +1174,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;
|
||||
}
|
||||
|
||||
|
@ -622,8 +622,8 @@ public:
|
||||
virtual bool defineProperty(JSContext* cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc)
|
||||
const MOZ_OVERRIDE;
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext *cx,
|
||||
JS::Handle<JSObject*> proxy,
|
||||
JS::AutoIdVector &props) const MOZ_OVERRIDE;
|
||||
@ -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
|
||||
|
@ -1423,13 +1423,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>
|
||||
|
@ -2456,12 +2456,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
|
||||
|
@ -7684,10 +7684,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;
|
||||
@ -9682,10 +9679,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;
|
||||
}
|
||||
}
|
||||
@ -10221,10 +10215,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
|
||||
@ -10242,7 +10239,7 @@ class CGDOMJSProxyHandler_defineProperty(ClassMethod):
|
||||
if (IsArrayIndex(index)) {
|
||||
*defined = true;
|
||||
$*{callSetter}
|
||||
return true;
|
||||
return opresult.succeed();
|
||||
}
|
||||
""",
|
||||
callSetter=CGProxyIndexedSetter(self.descriptor).define())
|
||||
@ -10255,7 +10252,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)
|
||||
@ -10275,7 +10274,7 @@ class CGDOMJSProxyHandler_defineProperty(ClassMethod):
|
||||
*defined = true;
|
||||
$*{callSetter}
|
||||
|
||||
return true;
|
||||
return opresult.succeed();
|
||||
""",
|
||||
callSetter=CGProxyNamedSetter(self.descriptor).define())
|
||||
else:
|
||||
@ -10291,7 +10290,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(),
|
||||
|
@ -196,18 +196,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);
|
||||
@ -215,8 +212,11 @@ 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
|
||||
|
@ -105,14 +105,15 @@ public:
|
||||
{}
|
||||
|
||||
bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_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 MOZ_OVERRIDE;
|
||||
bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
|
@ -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,
|
||||
@ -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,
|
||||
|
@ -103,11 +103,17 @@ struct ReturnException
|
||||
JSVariant exn;
|
||||
};
|
||||
|
||||
struct ReturnObjectOpResult
|
||||
{
|
||||
uint32_t code;
|
||||
};
|
||||
|
||||
union ReturnStatus
|
||||
{
|
||||
ReturnSuccess;
|
||||
ReturnStopIteration;
|
||||
ReturnException;
|
||||
ReturnObjectOpResult;
|
||||
};
|
||||
|
||||
union JSParam
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
@ -68,6 +67,7 @@ class WrapperAnswer : public virtual JavaScriptShared
|
||||
private:
|
||||
bool fail(JSContext *cx, ReturnStatus *rs);
|
||||
bool ok(ReturnStatus *rs);
|
||||
bool ok(ReturnStatus *rs, const JS::ObjectOpResult &result);
|
||||
};
|
||||
|
||||
} // mozilla
|
||||
|
@ -90,7 +90,8 @@ class CPOWProxyHandler : public BaseProxyHandler
|
||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const MOZ_OVERRIDE;
|
||||
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
|
||||
@ -202,14 +203,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 +230,7 @@ WrapperOwner::defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
|
||||
LOG_STACK();
|
||||
|
||||
return ok(cx, status);
|
||||
return ok(cx, status, result);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -934,6 +937,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);
|
||||
@ -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_;
|
||||
|
@ -118,6 +118,15 @@ class ObjectOpResult
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool) failCantRedefineProp();
|
||||
JS_PUBLIC_API(bool) failReadOnly();
|
||||
JS_PUBLIC_API(bool) failGetterOnly();
|
||||
|
||||
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
|
||||
@ -280,7 +289,8 @@ typedef bool
|
||||
JS::MutableHandleObject objp, JS::MutableHandle<Shape*> propp);
|
||||
typedef bool
|
||||
(* DefinePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs);
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
JS::ObjectOpResult &result);
|
||||
typedef bool
|
||||
(* HasPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *foundp);
|
||||
typedef bool
|
||||
|
@ -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;
|
||||
@ -367,7 +369,8 @@ class JS_FRIEND_API(DirectProxyHandler) : public BaseProxyHandler
|
||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const MOZ_OVERRIDE;
|
||||
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
|
@ -1757,7 +1757,8 @@ ReportPropertyError(JSContext *cx,
|
||||
|
||||
bool
|
||||
TypedObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs)
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
Rooted<TypedObject *> typedObj(cx, &obj->as<TypedObject>());
|
||||
return ReportTypedObjTypeError(cx, JSMSG_OBJECT_NOT_EXTENSIBLE, typedObj);
|
||||
|
@ -529,7 +529,8 @@ class TypedObject : public JSObject
|
||||
MutableHandleObject objp, MutableHandleShape propp);
|
||||
|
||||
static bool obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs);
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result);
|
||||
|
||||
static bool obj_hasProperty(JSContext *cx, HandleObject obj, HandleId id, bool *foundp);
|
||||
|
||||
|
@ -168,6 +168,24 @@ JS::ObjectOpResult::reportStrictErrorOrWarning(JSContext *cx, HandleObject obj,
|
||||
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(int64_t)
|
||||
JS_Now()
|
||||
{
|
||||
@ -2238,6 +2256,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)
|
||||
@ -2494,6 +2539,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)
|
||||
|
198
js/src/jsapi.h
198
js/src/jsapi.h
@ -2510,92 +2510,8 @@ 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;
|
||||
@ -2784,6 +2700,109 @@ 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,6 +2886,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);
|
||||
|
@ -746,42 +746,13 @@ js::ArraySetLength(JSContext *cx, Handle<ArrayObject*> arr, HandleId id,
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
|
@ -133,6 +133,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());
|
||||
}
|
||||
};
|
||||
#endif /* JS_CRASH_DIAGNOSTICS */
|
||||
|
||||
|
@ -1185,7 +1185,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);
|
||||
@ -1197,11 +1197,7 @@ js::DefineOwnProperty(JSContext *cx, JSObject *objArg, jsid idArg,
|
||||
if (descriptor.hasSetterObject())
|
||||
assertSameCompartment(cx, descriptor.setterObject());
|
||||
|
||||
ObjectOpResult success;
|
||||
if (!StandardDefineProperty(cx, obj, id, descriptor, success))
|
||||
return false;
|
||||
*bp = bool(success);
|
||||
return true;
|
||||
return StandardDefineProperty(cx, obj, id, descriptor, result);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
|
@ -361,7 +361,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,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs);
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
JS::ObjectOpResult &result);
|
||||
extern JS_FRIEND_API(bool)
|
||||
proxy_HasProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *foundp);
|
||||
extern JS_FRIEND_API(bool)
|
||||
@ -2710,7 +2711,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 */
|
||||
|
||||
|
@ -471,17 +471,14 @@ DefinePropertyOnObject(JSContext *cx, HandleNativeObject obj, HandleId id, const
|
||||
if (desc.isGenericDescriptor() || desc.isDataDescriptor()) {
|
||||
MOZ_ASSERT(!obj->getOps()->defineProperty);
|
||||
RootedValue v(cx, desc.hasValue() ? desc.value() : UndefinedValue());
|
||||
if (!NativeDefineProperty(cx, obj, id, v, nullptr, nullptr, desc.attributes()))
|
||||
return false;
|
||||
} else {
|
||||
MOZ_ASSERT(desc.isAccessorDescriptor());
|
||||
if (!NativeDefineProperty(cx, obj, id, UndefinedHandleValue,
|
||||
desc.getter(), desc.setter(), desc.attributes()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return NativeDefineProperty(cx, obj, id, v, nullptr, nullptr, desc.attributes(),
|
||||
result);
|
||||
}
|
||||
return result.succeed();
|
||||
|
||||
MOZ_ASSERT(desc.isAccessorDescriptor());
|
||||
|
||||
return NativeDefineProperty(cx, obj, id, UndefinedHandleValue,
|
||||
desc.getter(), desc.setter(), desc.attributes(), result);
|
||||
}
|
||||
|
||||
/* 8.12.9 steps 5-6 (note 5 is merely a special case of 6). */
|
||||
@ -746,9 +743,7 @@ DefinePropertyOnObject(JSContext *cx, HandleNativeObject obj, HandleId id, const
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NativeDefineProperty(cx, obj, id, v, getter, setter, attrs))
|
||||
return false;
|
||||
return result.succeed();
|
||||
return NativeDefineProperty(cx, obj, id, v, getter, setter, attrs, result);
|
||||
}
|
||||
|
||||
/* ES6 20130308 draft 8.4.2.1 [[DefineOwnProperty]] */
|
||||
@ -884,9 +879,7 @@ js::StandardDefineProperty(JSContext *cx, HandleObject obj, HandleId id, const P
|
||||
Rooted<PropertyDescriptor> pd(cx);
|
||||
desc.populatePropertyDescriptor(obj, &pd);
|
||||
pd.object().set(obj);
|
||||
if (!Proxy::defineProperty(cx, obj, id, &pd))
|
||||
return false;
|
||||
return result.succeed();
|
||||
return Proxy::defineProperty(cx, obj, id, &pd, result);
|
||||
}
|
||||
return result.fail(JSMSG_OBJECT_NOT_EXTENSIBLE);
|
||||
}
|
||||
@ -896,8 +889,7 @@ js::StandardDefineProperty(JSContext *cx, HandleObject obj, HandleId id, const P
|
||||
|
||||
bool
|
||||
js::StandardDefineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> descriptor,
|
||||
ObjectOpResult &result)
|
||||
Handle<PropertyDescriptor> descriptor, ObjectOpResult &result)
|
||||
{
|
||||
Rooted<PropDesc> desc(cx);
|
||||
desc.initFromPropertyDescriptor(descriptor);
|
||||
@ -3253,7 +3245,8 @@ js::GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
|
||||
|
||||
bool
|
||||
js::DefineProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs)
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
@ -3263,15 +3256,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,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs)
|
||||
js::DefineProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp 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,
|
||||
JSGetterOp getter, JSSetterOp 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,
|
||||
JSGetterOp getter, JSSetterOp 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,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return DefineProperty(cx, obj, id, value, getter, setter, attrs);
|
||||
|
@ -773,6 +773,22 @@ StandardDefineProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
Handle<PropertyDescriptor> desc);
|
||||
|
||||
extern bool
|
||||
DefineProperty(ExclusiveContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs, ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
DefineProperty(ExclusiveContext *cx, HandleObject obj, PropertyName *name, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs, ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
DefineElement(ExclusiveContext *cx, HandleObject obj, uint32_t index, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, 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,
|
||||
JSGetterOp getter = nullptr,
|
||||
JSSetterOp setter = nullptr,
|
||||
|
@ -117,7 +117,8 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
|
||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject wrapper,
|
||||
AutoIdVector &props) const MOZ_OVERRIDE;
|
||||
virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_OVERRIDE;
|
||||
@ -182,7 +183,8 @@ class JS_FRIEND_API(SecurityWrapper) : public Base
|
||||
bool *bp) const MOZ_OVERRIDE;
|
||||
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool isExtensible(JSContext *cx, HandleObject wrapper, bool *extensible) const MOZ_OVERRIDE;
|
||||
virtual bool preventExtensions(JSContext *cx, HandleObject wrapper, bool *succeeded) const MOZ_OVERRIDE;
|
||||
virtual bool setPrototypeOf(JSContext *cx, HandleObject proxy, HandleObject proto,
|
||||
|
@ -183,7 +183,10 @@ js::SetPropertyIgnoringNamedGetter(JSContext *cx, const BaseProxyHandler *handle
|
||||
|
||||
if (descIsOwn) {
|
||||
MOZ_ASSERT(desc.object() == proxy);
|
||||
return handler->defineProperty(cx, proxy, id, desc);
|
||||
ObjectOpResult result;
|
||||
if (!handler->defineProperty(cx, proxy, id, desc, result))
|
||||
return false;
|
||||
return result.checkStrictErrorOrWarning(cx, proxy, id, strict);
|
||||
}
|
||||
return DefineProperty(cx, receiver, id, desc.value(),
|
||||
desc.getter(), desc.setter(), desc.attributes());
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 MOZ_OVERRIDE;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject wrapper,
|
||||
AutoIdVector &props) const MOZ_OVERRIDE;
|
||||
virtual bool delete_(JSContext *cx, HandleObject wrapper, HandleId id, bool *bp) const MOZ_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());
|
||||
ObjectOpResult ignored;
|
||||
return StandardDefineProperty(cx, target, id, desc, ignored);
|
||||
return StandardDefineProperty(cx, target, id, desc, result);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -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
|
||||
@ -551,7 +554,8 @@ js::proxy_LookupProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
|
||||
bool
|
||||
js::proxy_DefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs)
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
Rooted<PropertyDescriptor> desc(cx);
|
||||
desc.object().set(obj);
|
||||
@ -559,7 +563,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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
// steps 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]]()
|
||||
|
@ -22,7 +22,8 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler {
|
||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const MOZ_OVERRIDE;
|
||||
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_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
|
||||
|
@ -23,7 +23,8 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
|
||||
virtual bool getOwnPropertyDescriptor(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
virtual bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
MutableHandle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, HandleObject proxy,
|
||||
AutoIdVector &props) const MOZ_OVERRIDE;
|
||||
virtual bool delete_(JSContext *cx, HandleObject proxy, HandleId id, bool *bp) const MOZ_OVERRIDE;
|
||||
|
@ -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>
|
||||
|
@ -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, GetterOp getter, SetterOp 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)
|
||||
{
|
||||
|
@ -1139,7 +1139,7 @@ NativeSet(JSContext *cx, HandleNativeObject obj, HandleObject receiver,
|
||||
static inline bool
|
||||
DefinePropertyOrElement(ExclusiveContext *cx, HandleNativeObject obj, HandleId id,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs, HandleValue value,
|
||||
bool callSetterAfterwards, bool setterIsStrict)
|
||||
bool callSetterAfterwards, ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
@ -1153,20 +1153,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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1175,24 +1172,13 @@ DefinePropertyOrElement(ExclusiveContext *cx, HandleNativeObject obj, HandleId i
|
||||
if (id == NameToId(cx->names().length)) {
|
||||
if (!cx->shouldBeJSContext())
|
||||
return false;
|
||||
|
||||
ObjectOpResult success;
|
||||
if (!ArraySetLength(cx->asJSContext(), arr, id, attrs, value, success))
|
||||
return false;
|
||||
if (setterIsStrict && !success) {
|
||||
success.reportError(cx->asJSContext(), arr, id);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1200,7 +1186,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);
|
||||
@ -1222,12 +1208,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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1238,9 +1226,13 @@ 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);
|
||||
|
||||
// FIXME: result should be passed to NativeSet.
|
||||
if (!NativeSet(cx->asJSContext(), obj, obj, shape, false, &nvalue))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
static unsigned
|
||||
@ -1353,7 +1345,8 @@ CheckAccessorRedefinition(ExclusiveContext *cx, HandleObject obj, HandleShape sh
|
||||
|
||||
bool
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, HandleValue value,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs)
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result)
|
||||
{
|
||||
MOZ_ASSERT(getter != JS_PropertyStub);
|
||||
MOZ_ASSERT(setter != JS_StrictPropertyStub);
|
||||
@ -1381,7 +1374,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;
|
||||
@ -1446,11 +1439,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;
|
||||
@ -1497,14 +1490,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>
|
||||
@ -1558,13 +1553,23 @@ js::NativeLookupElement(JSContext *cx, HandleNativeObject obj, uint32_t index,
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeDefineElement(ExclusiveContext *cx, HandleNativeObject obj, uint32_t index, HandleValue value,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs)
|
||||
js::NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyName *name,
|
||||
HandleValue value, GetterOp getter, SetterOp setter,
|
||||
unsigned attrs, ObjectOpResult &result)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs, result);
|
||||
}
|
||||
|
||||
bool
|
||||
js::NativeDefineElement(ExclusiveContext *cx, HandleNativeObject obj, uint32_t index,
|
||||
HandleValue value, GetterOp getter, SetterOp 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);
|
||||
@ -1572,6 +1577,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, JSGetterOp getter, JSSetterOp 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, JSGetterOp getter, JSSetterOp setter,
|
||||
unsigned attrs)
|
||||
{
|
||||
RootedId id(cx, NameToId(name));
|
||||
return NativeDefineProperty(cx, obj, id, value, getter, setter, attrs);
|
||||
}
|
||||
|
||||
@ -2035,7 +2069,10 @@ js::SetPropertyByDefining(JSContext *cx, HandleObject obj, HandleObject receiver
|
||||
return DefineProperty(cx, receiver, id, v, getter, setter, attrs);
|
||||
|
||||
Rooted<NativeObject*> nativeReceiver(cx, &receiver->as<NativeObject>());
|
||||
return DefinePropertyOrElement(cx, nativeReceiver, id, getter, setter, attrs, v, true, strict);
|
||||
ObjectOpResult success;
|
||||
if (!DefinePropertyOrElement(cx, nativeReceiver, id, getter, setter, attrs, v, true, success))
|
||||
return false;
|
||||
return success.checkStrictErrorOrWarning(cx, receiver, id, strict);
|
||||
}
|
||||
|
||||
// When setting |id| for |receiver| and |obj| has no property for id, continue
|
||||
@ -2115,11 +2152,14 @@ SetDenseOrTypedArrayElement(JSContext *cx, HandleNativeObject obj, uint32_t inde
|
||||
return true;
|
||||
}
|
||||
|
||||
bool definesPast;
|
||||
if (!WouldDefinePastNonwritableLength(cx, obj, index, strict, &definesPast))
|
||||
return false;
|
||||
if (definesPast)
|
||||
if (WouldDefinePastNonwritableLength(obj, index)) {
|
||||
if (strict) {
|
||||
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!obj->maybeCopyElementsForWrite(cx))
|
||||
return false;
|
||||
|
@ -1249,16 +1249,28 @@ IsObjectValueInCompartment(Value v, JSCompartment *comp)
|
||||
|
||||
extern bool
|
||||
NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs);
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result);
|
||||
|
||||
inline bool
|
||||
extern bool
|
||||
NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyName *name,
|
||||
HandleValue value, GetterOp getter, SetterOp setter,
|
||||
unsigned attrs);
|
||||
unsigned attrs, ObjectOpResult &result);
|
||||
|
||||
extern bool
|
||||
NativeDefineElement(ExclusiveContext *cx, HandleNativeObject obj, uint32_t index, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs);
|
||||
JSGetterOp getter, JSSetterOp 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,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs);
|
||||
|
||||
extern bool
|
||||
NativeDefineProperty(ExclusiveContext *cx, HandleNativeObject obj, PropertyName *name,
|
||||
HandleValue value, JSGetterOp getter, JSSetterOp setter,
|
||||
unsigned attrs);
|
||||
|
||||
extern bool
|
||||
NativeHasProperty(JSContext *cx, HandleNativeObject obj, HandleId id, bool *foundp);
|
||||
|
@ -471,10 +471,11 @@ with_LookupProperty(JSContext *cx, HandleObject obj, HandleId id,
|
||||
|
||||
static bool
|
||||
with_DefineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
|
||||
JSGetterOp getter, JSSetterOp setter, unsigned attrs)
|
||||
JSGetterOp getter, JSSetterOp 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
|
||||
@ -1626,7 +1627,8 @@ class DebugScopeProxy : public BaseProxyHandler
|
||||
}
|
||||
|
||||
bool defineProperty(JSContext *cx, HandleObject proxy, HandleId id,
|
||||
MutableHandle<PropertyDescriptor> desc) const MOZ_OVERRIDE
|
||||
MutableHandle<PropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const MOZ_OVERRIDE
|
||||
{
|
||||
Rooted<ScopeObject*> scope(cx, &proxy->as<DebugScopeObject>().scope());
|
||||
|
||||
@ -1636,13 +1638,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 MOZ_OVERRIDE
|
||||
|
@ -358,12 +358,13 @@ UnboxedPlainObject::obj_lookupProperty(JSContext *cx, HandleObject obj,
|
||||
|
||||
/* static */ bool
|
||||
UnboxedPlainObject::obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs)
|
||||
GetterOp getter, SetterOp 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
|
||||
|
@ -165,7 +165,8 @@ class UnboxedPlainObject : public JSObject
|
||||
MutableHandleShape propp);
|
||||
|
||||
static bool obj_defineProperty(JSContext *cx, HandleObject obj, HandleId id, HandleValue v,
|
||||
GetterOp getter, SetterOp setter, unsigned attrs);
|
||||
GetterOp getter, SetterOp setter, unsigned attrs,
|
||||
ObjectOpResult &result);
|
||||
|
||||
static bool obj_hasProperty(JSContext *cx, HandleObject obj, HandleId id, bool *foundp);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,14 +148,15 @@ AddonWrapper<Base>::set(JSContext *cx, JS::HandleObject wrapper, JS::HandleObjec
|
||||
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,7 +28,8 @@ class AddonWrapper : public Base {
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
virtual bool defineProperty(JSContext *cx, JS::HandleObject proxy, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_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 MOZ_OVERRIDE;
|
||||
virtual bool get(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const MOZ_OVERRIDE;
|
||||
|
@ -21,11 +21,12 @@ 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
|
||||
|
@ -29,7 +29,8 @@ class ChromeObjectWrapper : public ChromeObjectWrapperBase
|
||||
|
||||
virtual bool defineProperty(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_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 MOZ_OVERRIDE;
|
||||
|
@ -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 MOZ_OVERRIDE;
|
||||
virtual bool defineProperty(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::AutoIdVector &props) const MOZ_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;
|
||||
}
|
||||
@ -1199,13 +1198,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);
|
||||
}
|
||||
|
||||
@ -1260,14 +1253,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
|
||||
@ -1406,7 +1392,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));
|
||||
@ -1416,7 +1403,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;
|
||||
@ -1559,20 +1546,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.
|
||||
@ -1580,12 +1562,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
|
||||
@ -1883,13 +1865,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;
|
||||
@ -1976,8 +1952,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);
|
||||
|
||||
@ -1999,17 +1975,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;
|
||||
@ -2034,13 +2010,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>
|
||||
|
@ -126,7 +126,8 @@ public:
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) MOZ_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) MOZ_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 MOZ_OVERRIDE;
|
||||
virtual bool defineProperty(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) const MOZ_OVERRIDE;
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
JS::ObjectOpResult &result) const MOZ_OVERRIDE;
|
||||
virtual bool ownPropertyKeys(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::AutoIdVector &props) const MOZ_OVERRIDE;
|
||||
virtual bool delete_(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
|
Loading…
Reference in New Issue
Block a user