Bug 1088002 part 2. Change JS_DefineElement, JS_DefineProperty, JS_DefineUCProperty, JS_DefinePropertyById, and JS_DefineProperties to default to using JSNative accessors, not JSPropertyOp accessors. r=waldo

This commit is contained in:
Boris Zbarsky 2014-10-29 15:06:31 -04:00
parent a315a94e41
commit 472292138d
37 changed files with 391 additions and 291 deletions

View File

@ -1195,7 +1195,7 @@ Console::ProcessCallData(ConsoleCallData* aData)
JS::UndefinedHandleValue,
JSPROP_ENUMERATE | JSPROP_SHARED | JSPROP_GETTER |
JSPROP_SETTER,
JS_DATA_TO_FUNC_PTR(JSPropertyOp, funObj.get()),
JS_DATA_TO_FUNC_PTR(JSNative, funObj.get()),
nullptr)) {
return;
}

View File

@ -1034,8 +1034,9 @@ nsDOMClassInfo::ResolveConstructor(JSContext *cx, JSObject *aObj,
// return the Object constructor.
JS::Rooted<jsid> id(cx, sConstructor_id);
if (!::JS_DefinePropertyById(cx, obj, id, val, JSPROP_ENUMERATE,
JS_PropertyStub, JS_StrictPropertyStub)) {
if (!::JS_DefinePropertyById(cx, obj, id, val,
JSPROP_ENUMERATE | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER)) {
return NS_ERROR_UNEXPECTED;
}
@ -1249,8 +1250,12 @@ nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * aProto)
if (!contentDefinedProperty && desc.object() && !desc.value().isUndefined() &&
!JS_DefineUCProperty(cx, global, mData->mNameUTF16,
NS_strlen(mData->mNameUTF16),
desc.value(), desc.attributes(),
desc.getter(), desc.setter())) {
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 NS_ERROR_UNEXPECTED;
}
@ -1452,8 +1457,8 @@ DefineInterfaceConstants(JSContext *cx, JS::Handle<JSObject*> obj, const nsIID *
if (!::JS_DefineProperty(cx, obj, name, v,
JSPROP_ENUMERATE | JSPROP_READONLY |
JSPROP_PERMANENT,
JS_PropertyStub, JS_StrictPropertyStub)) {
JSPROP_PERMANENT | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER)) {
return NS_ERROR_UNEXPECTED;
}
}
@ -2050,8 +2055,9 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx,
// Per ECMA, the prototype property is {DontEnum, DontDelete, ReadOnly}
if (!JS_WrapValue(cx, &v) ||
!JS_DefineProperty(cx, class_obj, "prototype", v,
JSPROP_PERMANENT | JSPROP_READONLY,
JS_PropertyStub, JS_StrictPropertyStub)) {
JSPROP_PERMANENT | JSPROP_READONLY |
JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER)) {
return NS_ERROR_UNEXPECTED;
}
@ -2509,8 +2515,9 @@ LookupComponentsShim(JSContext *cx, JS::Handle<JSObject*> global,
NS_ENSURE_TRUE(interfaces, NS_ERROR_OUT_OF_MEMORY);
bool ok =
JS_DefineProperty(cx, components, "interfaces", interfaces,
JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY,
JS_PropertyStub, JS_StrictPropertyStub);
JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY |
JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER);
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
// Define a bunch of shims from the Ci.nsIDOMFoo to window.Foo for DOM
@ -2532,8 +2539,9 @@ LookupComponentsShim(JSContext *cx, JS::Handle<JSObject*> global,
// Define the shim on the interfaces object.
ok = JS_DefineProperty(cx, interfaces, geckoName, v,
JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY,
JS_PropertyStub, JS_StrictPropertyStub);
JSPROP_ENUMERATE | JSPROP_PERMANENT |
JSPROP_READONLY | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER);
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
}

View File

@ -2590,8 +2590,9 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
if (!aState) {
JS::Rooted<JSObject*> rootedWrapper(cx, GetWrapperPreserveColor());
if (!JS_DefineProperty(cx, newInnerGlobal, "window", rootedWrapper,
JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT,
JS_PropertyStub, JS_StrictPropertyStub)) {
JSPROP_ENUMERATE | JSPROP_READONLY |
JSPROP_PERMANENT | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER)) {
NS_ERROR("can't create the 'window' property");
return NS_ERROR_FAILURE;
}
@ -4526,8 +4527,9 @@ nsGlobalWindow::SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener,
}
if (!JS_WrapObject(aCx, &thisObj) ||
!JS_DefineProperty(aCx, thisObj, "opener", aOpener, JSPROP_ENUMERATE,
JS_PropertyStub, JS_StrictPropertyStub)) {
!JS_DefineProperty(aCx, thisObj, "opener", aOpener,
JSPROP_ENUMERATE | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER)) {
aError.Throw(NS_ERROR_FAILURE);
}
@ -14004,8 +14006,8 @@ nsGlobalWindow::SetConsole(JSContext* aCx, JS::Handle<JS::Value> aValue)
if (!JS_WrapObject(aCx, &thisObj) ||
!JS_DefineProperty(aCx, thisObj, "console", aValue,
JSPROP_ENUMERATE, JS_PropertyStub,
JS_StrictPropertyStub)) {
JSPROP_ENUMERATE | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER)) {
return NS_ERROR_FAILURE;
}

View File

@ -528,8 +528,9 @@ CreateInterfaceObject(JSContext* cx, JS::Handle<JSObject*> global,
namedConstructors->mNargs));
if (!namedConstructor ||
!JS_DefineProperty(cx, namedConstructor, "prototype",
proto, JSPROP_PERMANENT | JSPROP_READONLY,
JS_PropertyStub, JS_StrictPropertyStub) ||
proto,
JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER) ||
(defineOnGlobal &&
!DefineConstructor(cx, global, namedConstructors->mName,
namedConstructor))) {
@ -968,24 +969,24 @@ XrayResolveAttribute(JSContext* cx, JS::Handle<JSObject*> wrapper,
// Because of centralization, we need to make sure we fault in the
// JitInfos as well. At present, until the JSAPI changes, the easiest
// way to do this is wrap them up as functions ourselves.
desc.setAttributes(attrSpec.flags & ~JSPROP_NATIVE_ACCESSORS);
desc.setAttributes(attrSpec.flags);
// They all have getters, so we can just make it.
JS::Rooted<JSFunction*> fun(cx,
JS_NewFunctionById(cx, (JSNative)attrSpec.getter.propertyOp.op,
JS_NewFunctionById(cx, attrSpec.getter.native.op,
0, 0, wrapper, id));
if (!fun)
return false;
SET_JITINFO(fun, attrSpec.getter.propertyOp.info);
SET_JITINFO(fun, attrSpec.getter.native.info);
JSObject *funobj = JS_GetFunctionObject(fun);
desc.setGetterObject(funobj);
desc.attributesRef() |= JSPROP_GETTER;
if (attrSpec.setter.propertyOp.op) {
if (attrSpec.setter.native.op) {
// We have a setter! Make it.
fun = JS_NewFunctionById(cx, (JSNative)attrSpec.setter.propertyOp.op, 1, 0,
fun = JS_NewFunctionById(cx, attrSpec.setter.native.op, 1, 0,
wrapper, id);
if (!fun)
return false;
SET_JITINFO(fun, attrSpec.setter.propertyOp.info);
SET_JITINFO(fun, attrSpec.setter.native.info);
funobj = JS_GetFunctionObject(fun);
desc.setSetterObject(funobj);
desc.attributesRef() |= JSPROP_SETTER;

View File

@ -2412,7 +2412,7 @@ class AttrDefiner(PropertyDefiner):
def flags(attr):
unforgeable = " | JSPROP_PERMANENT" if self.unforgeable else ""
return ("JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS" +
return ("JSPROP_SHARED | JSPROP_ENUMERATE" +
unforgeable)
def getter(attr):
@ -2430,14 +2430,14 @@ class AttrDefiner(PropertyDefiner):
accessor = "GenericBindingGetter"
jitinfo = ("&%s_getterinfo" %
IDLToCIdentifier(attr.identifier.name))
return "{ { JS_CAST_NATIVE_TO(%s, JSPropertyOp), %s } }" % \
return "{ { %s, %s } }" % \
(accessor, jitinfo)
def setter(attr):
if (attr.readonly and
attr.getExtendedAttribute("PutForwards") is None and
attr.getExtendedAttribute("Replaceable") is None):
return "JSOP_NULLWRAPPER"
return "JSNATIVE_WRAPPER(nullptr)"
if self.static:
accessor = 'set_' + IDLToCIdentifier(attr.identifier.name)
jitinfo = "nullptr"
@ -2451,7 +2451,7 @@ class AttrDefiner(PropertyDefiner):
else:
accessor = "GenericBindingSetter"
jitinfo = "&%s_setterinfo" % IDLToCIdentifier(attr.identifier.name)
return "{ { JS_CAST_NATIVE_TO(%s, JSStrictPropertyOp), %s } }" % \
return "{ { %s, %s } }" % \
(accessor, jitinfo)
def specData(attr):
@ -7631,8 +7631,9 @@ class CGNewResolveHook(CGAbstractBindingMethod):
// define it.
if (!desc.value().isUndefined() &&
!JS_DefinePropertyById(cx, obj, id, desc.value(),
desc.attributes(),
desc.getter(), desc.setter())) {
desc.attributes() | JSPROP_PROPOP_ACCESSORS,
JS_PROPERTYOP_GETTER(desc.getter()),
JS_PROPERTYOP_SETTER(desc.setter()))) {
return false;
}
objp.set(obj);
@ -9603,8 +9604,9 @@ class CGResolveOwnPropertyViaNewresolve(CGAbstractBindingMethod):
if (objDesc.object() &&
!objDesc.value().isUndefined() &&
!JS_DefinePropertyById(cx, obj, id, objDesc.value(),
objDesc.attributes(),
objDesc.getter(), objDesc.setter())) {
objDesc.attributes() | JSPROP_PROPOP_ACCESSORS,
JS_PROPERTYOP_GETTER(objDesc.getter()),
JS_PROPERTYOP_SETTER(objDesc.setter()))) {
return false;
}
}

View File

@ -887,8 +887,8 @@ GetOrCreateClassObjectMap(JSContext *cx, JS::Handle<JSObject*> scope, const char
// It's not there. Create and define it.
JS::Rooted<JSObject*> map(cx, JS::NewWeakMapObject(cx));
if (!map || !JS_DefineProperty(cx, scope, mapName, map,
JSPROP_PERMANENT | JSPROP_READONLY,
JS_PropertyStub, JS_StrictPropertyStub))
JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER))
{
return nullptr;
}
@ -1036,8 +1036,8 @@ nsXBLBinding::DoInitJSClass(JSContext *cx,
JSAutoCompartment ac3(cx, holder);
if (!JS_WrapObject(cx, &proto) ||
!JS_DefineProperty(cx, holder, aClassName.get(), proto,
JSPROP_READONLY | JSPROP_PERMANENT,
JS_PropertyStub, JS_StrictPropertyStub))
JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER))
{
return NS_ERROR_OUT_OF_MEMORY;
}

View File

@ -118,8 +118,8 @@ nsXBLProtoImpl::InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding,
// Define it as a property on the scopeObject, using the same name used on
// the content side.
bool ok = JS_DefineProperty(cx, scopeObject, className, propertyHolder,
JSPROP_PERMANENT | JSPROP_READONLY,
JS_PropertyStub, JS_StrictPropertyStub);
JSPROP_PERMANENT | JSPROP_READONLY | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER);
NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
} else {
propertyHolder = targetClassObject;

View File

@ -367,8 +367,8 @@ nsXBLProtoImplField::InstallAccessors(JSContext* aCx,
if (!::JS_DefinePropertyById(aCx, aTargetClassObject, id, JS::UndefinedHandleValue,
AccessorAttributes(),
JS_DATA_TO_FUNC_PTR(JSPropertyOp, get.get()),
JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, set.get()))) {
JS_DATA_TO_FUNC_PTR(JSNative, get.get()),
JS_DATA_TO_FUNC_PTR(JSNative, set.get()))) {
return NS_ERROR_OUT_OF_MEMORY;
}

View File

@ -150,8 +150,8 @@ nsXBLProtoImplProperty::InstallMember(JSContext *aCx,
if (!::JS_DefineUCProperty(aCx, aTargetClassObject,
static_cast<const char16_t*>(mName),
name.Length(), JS::UndefinedHandleValue, mJSAttributes,
JS_DATA_TO_FUNC_PTR(JSPropertyOp, getter.get()),
JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, setter.get())))
JS_DATA_TO_FUNC_PTR(JSNative, getter.get()),
JS_DATA_TO_FUNC_PTR(JSNative, setter.get())))
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;

View File

@ -558,8 +558,9 @@ XPCShellEnvironment::Init()
JS::Rooted<Value> privateVal(cx, PrivateValue(this));
if (!JS_DefineProperty(cx, globalObj, "__XPCShellEnvironment",
privateVal, JSPROP_READONLY | JSPROP_PERMANENT,
JS_PropertyStub, JS_StrictPropertyStub) ||
privateVal,
JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER) ||
!JS_DefineFunctions(cx, globalObj, gGlobalFunctions) ||
!JS_DefineProfilingFunctions(cx, globalObj))
{

View File

@ -180,8 +180,13 @@ WrapperAnswer::RecvDefineProperty(const ObjectId &objId, const JSIDVariant &idVa
return fail(cx, rs);
}
if (!JS_DefinePropertyById(cx, obj, id, desc.value(), desc.attributes(),
desc.getter(), desc.setter()))
if (!JS_DefinePropertyById(cx, obj, id, desc.value(),
// Descrriptors 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 fail(cx, rs);
}

View File

@ -1184,14 +1184,15 @@ ShellObjectMetadataCallback(JSContext *cx, JSObject **pmetadata)
static int createdIndex = 0;
createdIndex++;
if (!JS_DefineProperty(cx, obj, "index", createdIndex, 0,
JS_PropertyStub, JS_StrictPropertyStub))
if (!JS_DefineProperty(cx, obj, "index", createdIndex,
JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER))
{
return false;
}
if (!JS_DefineProperty(cx, obj, "stack", stack, 0,
JS_PropertyStub, JS_StrictPropertyStub))
if (!JS_DefineProperty(cx, obj, "stack", stack, JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER))
{
return false;
}
@ -1203,8 +1204,9 @@ ShellObjectMetadataCallback(JSContext *cx, JSObject **pmetadata)
if (iter.isFunctionFrame() && iter.compartment() == cx->compartment()) {
id = INT_TO_JSID(stackIndex);
RootedObject callee(cx, iter.callee());
if (!JS_DefinePropertyById(cx, stack, id, callee, 0,
JS_PropertyStub, JS_StrictPropertyStub))
if (!JS_DefinePropertyById(cx, stack, id, callee,
JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER))
{
return false;
}

View File

@ -1378,8 +1378,9 @@ JS_InitCTypesClass(JSContext* cx, HandleObject global)
if (!ctypes)
return false;
if (!JS_DefineProperty(cx, global, "ctypes", ctypes, JSPROP_READONLY | JSPROP_PERMANENT,
JS_PropertyStub, JS_StrictPropertyStub)){
if (!JS_DefineProperty(cx, global, "ctypes", ctypes,
JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER)){
return false;
}
@ -4897,8 +4898,9 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb
if (!JS_DefineUCProperty(cx, prototype,
nameChars.twoByteChars(), name->length(), UndefinedHandleValue,
JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT,
StructType::FieldGetter, StructType::FieldSetter))
JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_PROPOP_ACCESSORS,
JS_PROPERTYOP_GETTER(StructType::FieldGetter),
JS_PROPERTYOP_SETTER(StructType::FieldSetter)))
return false;
size_t fieldSize = CType::GetSize(fieldType);

View File

@ -46,15 +46,17 @@ BEGIN_TEST(testAddPropertyHook)
CHECK(obj);
JS::RootedValue arr(cx, OBJECT_TO_JSVAL(obj));
CHECK(JS_DefineProperty(cx, global, "arr", arr, JSPROP_ENUMERATE,
JS_PropertyStub, JS_StrictPropertyStub));
CHECK(JS_DefineProperty(cx, global, "arr", arr,
JSPROP_ENUMERATE | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER));
JS::RootedObject arrObj(cx, &arr.toObject());
for (int i = 0; i < ExpectedCount; ++i) {
obj = JS_NewObject(cx, &AddPropertyClass, JS::NullPtr(), JS::NullPtr());
CHECK(obj);
CHECK(JS_DefineElement(cx, arrObj, i, obj, JSPROP_ENUMERATE,
JS_PropertyStub, JS_StrictPropertyStub));
CHECK(JS_DefineElement(cx, arrObj, i, obj,
JSPROP_ENUMERATE | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER));
}
// Now add a prop to each of the objects, but make sure to do

View File

@ -36,14 +36,14 @@ BEGIN_TEST(testDefineGetterSetterNonEnumerable)
CHECK(JS_DefineProperty(cx, vObject, PROPERTY_NAME,
JS::UndefinedHandleValue,
JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED | JSPROP_ENUMERATE,
JS_DATA_TO_FUNC_PTR(JSPropertyOp, (JSObject*) funGetObj),
JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, (JSObject*) funSetObj)));
JS_DATA_TO_FUNC_PTR(JSNative, (JSObject*) funGetObj),
JS_DATA_TO_FUNC_PTR(JSNative, (JSObject*) funSetObj)));
CHECK(JS_DefineProperty(cx, vObject, PROPERTY_NAME,
JS::UndefinedHandleValue,
JSPROP_GETTER | JSPROP_SETTER | JSPROP_SHARED | JSPROP_PERMANENT,
JS_DATA_TO_FUNC_PTR(JSPropertyOp, (JSObject*) funGetObj),
JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, (JSObject*) funSetObj)));
JS_DATA_TO_FUNC_PTR(JSNative, (JSObject*) funGetObj),
JS_DATA_TO_FUNC_PTR(JSNative, (JSObject*) funSetObj)));
JS::Rooted<JSPropertyDescriptor> desc(cx);
CHECK(JS_GetOwnPropertyDescriptor(cx, vObject, PROPERTY_NAME, &desc));

View File

@ -47,8 +47,8 @@ BEGIN_TEST(testDefinePropertyIgnoredAttributes)
// Try a getter. Allow it to fill in the defaults.
CHECK(JS_DefineProperty(cx, obj, "foo", defineValue,
IgnoreAll | JSPROP_NATIVE_ACCESSORS | JSPROP_SHARED,
(JSPropertyOp)Getter));
IgnoreAll | JSPROP_SHARED,
Getter));
CHECK(JS_GetPropertyDescriptor(cx, obj, "foo", &desc));
@ -58,8 +58,8 @@ BEGIN_TEST(testDefinePropertyIgnoredAttributes)
// Install another configurable property, so we can futz with it.
CHECK(JS_DefineProperty(cx, obj, "bar", defineValue,
AllowConfigure | JSPROP_NATIVE_ACCESSORS | JSPROP_SHARED,
(JSPropertyOp)Getter));
AllowConfigure | JSPROP_SHARED,
Getter));
CHECK(JS_GetPropertyDescriptor(cx, obj, "bar", &desc));
CHECK(CheckDescriptor(desc, false, true, true));
@ -68,9 +68,8 @@ BEGIN_TEST(testDefinePropertyIgnoredAttributes)
CHECK(JS_DefineProperty(cx, obj, "bar", defineValue,
AllowEnumerate |
JSPROP_ENUMERATE |
JSPROP_NATIVE_ACCESSORS |
JSPROP_SHARED,
(JSPropertyOp)Getter));
Getter));
CHECK(JS_GetPropertyDescriptor(cx, obj, "bar", &desc));
CHECK(CheckDescriptor(desc, true, true, true));

View File

@ -12,11 +12,13 @@ BEGIN_TEST(testSetProperty_NativeGetterStubSetter)
JS::RootedObject obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
CHECK(obj);
CHECK(JS_DefineProperty(cx, global, "globalProp", obj, JSPROP_ENUMERATE,
JS_PropertyStub, JS_StrictPropertyStub));
CHECK(JS_DefineProperty(cx, global, "globalProp", obj,
JSPROP_ENUMERATE | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER));
CHECK(JS_DefineProperty(cx, obj, "prop", JS::UndefinedHandleValue, JSPROP_SHARED,
NativeGet, JS_StrictPropertyStub));
CHECK(JS_DefineProperty(cx, obj, "prop", JS::UndefinedHandleValue,
JSPROP_SHARED | JSPROP_PROPOP_ACCESSORS,
JS_PROPERTYOP_GETTER(NativeGet), JS_STUBSETTER));
EXEC("'use strict'; \n"
"var error, passed = false; \n"

View File

@ -2803,31 +2803,22 @@ JS_AlreadyHasOwnUCProperty(JSContext *cx, HandleObject obj, const char16_t *name
* Wrapper functions to create wrappers with no corresponding JSJitInfo from API
* function arguments.
*/
static JSPropertyOpWrapper
GetterWrapper(JSPropertyOp getter)
static JSNativeWrapper
NativeOpWrapper(Native native)
{
JSPropertyOpWrapper ret;
ret.op = getter;
ret.info = nullptr;
return ret;
}
static JSStrictPropertyOpWrapper
SetterWrapper(JSStrictPropertyOp setter)
{
JSStrictPropertyOpWrapper ret;
ret.op = setter;
JSNativeWrapper ret;
ret.op = native;
ret.info = nullptr;
return ret;
}
static bool
DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
const JSPropertyOpWrapper &get, const JSStrictPropertyOpWrapper &set,
const JSNativeWrapper &get, const JSNativeWrapper &set,
unsigned attrs, unsigned flags)
{
PropertyOp getter = get.op;
StrictPropertyOp setter = set.op;
JSPropertyOp getter = JS_CAST_NATIVE_TO(get.op, JSPropertyOp);
JSStrictPropertyOp setter = JS_CAST_NATIVE_TO(set.op, JSStrictPropertyOp);
// JSPROP_READONLY has no meaning when accessors are involved. Ideally we'd
// throw if this happens, but we've accepted it for long enough that it's
@ -2840,13 +2831,11 @@ DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue val
// than JSNatives. However, we might be pulling this property descriptor off
// of something with JSNative property descriptors. If we are, wrap them in
// JS Function objects.
if (attrs & JSPROP_NATIVE_ACCESSORS) {
MOZ_ASSERT(!(attrs & (JSPROP_GETTER | JSPROP_SETTER)));
if (!(attrs & JSPROP_PROPOP_ACCESSORS)) {
JSFunction::Flags zeroFlags = JSAPIToJSFunctionFlags(0);
RootedAtom atom(cx, JSID_IS_ATOM(id) ? JSID_TO_ATOM(id) : nullptr);
attrs &= ~JSPROP_NATIVE_ACCESSORS;
if (getter) {
if (getter && !(attrs & JSPROP_GETTER)) {
RootedObject global(cx, (JSObject*) &obj->global());
JSFunction *getobj = NewFunction(cx, NullPtr(), (Native) getter, 0,
zeroFlags, global, atom);
@ -2859,7 +2848,7 @@ DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue val
getter = JS_DATA_TO_FUNC_PTR(PropertyOp, getobj);
attrs |= JSPROP_GETTER;
}
if (setter) {
if (setter && !(attrs & JSPROP_SETTER)) {
// Root just the getter, since the setter is not yet a JSObject.
AutoRooterGetterSetter getRoot(cx, JSPROP_GETTER, &getter, nullptr);
RootedObject global(cx, (JSObject*) &obj->global());
@ -2874,9 +2863,10 @@ DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue val
setter = JS_DATA_TO_FUNC_PTR(StrictPropertyOp, setobj);
attrs |= JSPROP_SETTER;
}
} else {
attrs &= ~JSPROP_PROPOP_ACCESSORS;
}
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, id, value,
@ -2892,60 +2882,63 @@ DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue val
JS_PUBLIC_API(bool)
JS_DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleValue value,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
return DefinePropertyById(cx, obj, id, value, GetterWrapper(getter), SetterWrapper(setter),
return DefinePropertyById(cx, obj, id, value,
NativeOpWrapper(getter), NativeOpWrapper(setter),
attrs, 0);
}
JS_PUBLIC_API(bool)
JS_DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleObject valueArg,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
RootedValue value(cx, ObjectValue(*valueArg));
return DefinePropertyById(cx, obj, id, value, GetterWrapper(getter), SetterWrapper(setter),
return DefinePropertyById(cx, obj, id, value,
NativeOpWrapper(getter), NativeOpWrapper(setter),
attrs, 0);
}
JS_PUBLIC_API(bool)
JS_DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, HandleString valueArg,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
RootedValue value(cx, StringValue(valueArg));
return DefinePropertyById(cx, obj, id, value, GetterWrapper(getter), SetterWrapper(setter),
return DefinePropertyById(cx, obj, id, value,
NativeOpWrapper(getter), NativeOpWrapper(setter),
attrs, 0);
}
JS_PUBLIC_API(bool)
JS_DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, int32_t valueArg,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
Value value = Int32Value(valueArg);
return DefinePropertyById(cx, obj, id, HandleValue::fromMarkedLocation(&value),
GetterWrapper(getter), SetterWrapper(setter), attrs, 0);
NativeOpWrapper(getter), NativeOpWrapper(setter), attrs, 0);
}
JS_PUBLIC_API(bool)
JS_DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, uint32_t valueArg,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
Value value = UINT_TO_JSVAL(valueArg);
return DefinePropertyById(cx, obj, id, HandleValue::fromMarkedLocation(&value),
GetterWrapper(getter), SetterWrapper(setter), attrs, 0);
NativeOpWrapper(getter), NativeOpWrapper(setter), attrs, 0);
}
JS_PUBLIC_API(bool)
JS_DefinePropertyById(JSContext *cx, HandleObject obj, HandleId id, double valueArg,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
Value value = NumberValue(valueArg);
return DefinePropertyById(cx, obj, id, HandleValue::fromMarkedLocation(&value),
GetterWrapper(getter), SetterWrapper(setter), attrs, 0);
NativeOpWrapper(getter), NativeOpWrapper(setter), attrs, 0);
}
static bool
DefineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue value,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);
AssertHeapIsIdle(cx);
@ -2953,20 +2946,21 @@ DefineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue value
RootedId id(cx);
if (!IndexToId(cx, index, &id))
return false;
return DefinePropertyById(cx, obj, id, value, GetterWrapper(getter), SetterWrapper(setter),
return DefinePropertyById(cx, obj, id, value,
NativeOpWrapper(getter), NativeOpWrapper(setter),
attrs, 0);
}
JS_PUBLIC_API(bool)
JS_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleValue value,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
return DefineElement(cx, obj, index, value, attrs, getter, setter);
}
JS_PUBLIC_API(bool)
JS_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleObject valueArg,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
RootedValue value(cx, ObjectValue(*valueArg));
return DefineElement(cx, obj, index, value, attrs, getter, setter);
@ -2974,7 +2968,7 @@ JS_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleObject v
JS_PUBLIC_API(bool)
JS_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleString valueArg,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
RootedValue value(cx, StringValue(valueArg));
return DefineElement(cx, obj, index, value, attrs, getter, setter);
@ -2982,7 +2976,7 @@ JS_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, HandleString v
JS_PUBLIC_API(bool)
JS_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, int32_t valueArg,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
Value value = Int32Value(valueArg);
return DefineElement(cx, obj, index, HandleValue::fromMarkedLocation(&value),
@ -2991,7 +2985,7 @@ JS_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, int32_t valueA
JS_PUBLIC_API(bool)
JS_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, uint32_t valueArg,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
Value value = UINT_TO_JSVAL(valueArg);
return DefineElement(cx, obj, index, HandleValue::fromMarkedLocation(&value),
@ -3000,7 +2994,7 @@ JS_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, uint32_t value
JS_PUBLIC_API(bool)
JS_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, double valueArg,
unsigned attrs, JSPropertyOp getter, JSStrictPropertyOp setter)
unsigned attrs, Native getter, Native setter)
{
Value value = NumberValue(valueArg);
return DefineElement(cx, obj, index, HandleValue::fromMarkedLocation(&value),
@ -3009,11 +3003,11 @@ JS_DefineElement(JSContext *cx, HandleObject obj, uint32_t index, double valueAr
static bool
DefineProperty(JSContext *cx, HandleObject obj, const char *name, HandleValue value,
const JSPropertyOpWrapper &getter, const JSStrictPropertyOpWrapper &setter,
const JSNativeWrapper &getter, const JSNativeWrapper &setter,
unsigned attrs, unsigned flags)
{
AutoRooterGetterSetter gsRoot(cx, attrs, const_cast<JSPropertyOp *>(&getter.op),
const_cast<JSStrictPropertyOp *>(&setter.op));
AutoRooterGetterSetter gsRoot(cx, attrs, const_cast<JSNative *>(&getter.op),
const_cast<JSNative *>(&setter.op));
RootedId id(cx);
if (attrs & JSPROP_INDEX) {
@ -3047,7 +3041,7 @@ DefineSelfHostedProperty(JSContext *cx, HandleObject obj, HandleId id,
return false;
MOZ_ASSERT(getterValue.isObject() && getterValue.toObject().is<JSFunction>());
RootedFunction getterFunc(cx, &getterValue.toObject().as<JSFunction>());
JSPropertyOp getterOp = JS_DATA_TO_FUNC_PTR(PropertyOp, getterFunc.get());
JSNative getterOp = JS_DATA_TO_FUNC_PTR(JSNative, getterFunc.get());
RootedFunction setterFunc(cx);
if (setterName) {
@ -3061,75 +3055,75 @@ DefineSelfHostedProperty(JSContext *cx, HandleObject obj, HandleId id,
MOZ_ASSERT(setterValue.isObject() && setterValue.toObject().is<JSFunction>());
setterFunc = &getterValue.toObject().as<JSFunction>();
}
JSStrictPropertyOp setterOp = JS_DATA_TO_FUNC_PTR(StrictPropertyOp, setterFunc.get());
JSNative setterOp = JS_DATA_TO_FUNC_PTR(JSNative, setterFunc.get());
return DefinePropertyById(cx, obj, id, JS::UndefinedHandleValue,
GetterWrapper(getterOp), SetterWrapper(setterOp),
NativeOpWrapper(getterOp), NativeOpWrapper(setterOp),
attrs, flags);
}
JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext *cx, HandleObject obj, const char *name, HandleValue value,
unsigned attrs,
PropertyOp getter /* = nullptr */, JSStrictPropertyOp setter /* = nullptr */)
Native getter /* = nullptr */, Native setter /* = nullptr */)
{
return DefineProperty(cx, obj, name, value, GetterWrapper(getter), SetterWrapper(setter),
return DefineProperty(cx, obj, name, value, NativeOpWrapper(getter), NativeOpWrapper(setter),
attrs, 0);
}
JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext *cx, HandleObject obj, const char *name, HandleObject valueArg,
unsigned attrs,
PropertyOp getter /* = nullptr */, JSStrictPropertyOp setter /* = nullptr */)
Native getter /* = nullptr */, Native setter /* = nullptr */)
{
RootedValue value(cx, ObjectValue(*valueArg));
return DefineProperty(cx, obj, name, value, GetterWrapper(getter), SetterWrapper(setter),
return DefineProperty(cx, obj, name, value, NativeOpWrapper(getter), NativeOpWrapper(setter),
attrs, 0);
}
JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext *cx, HandleObject obj, const char *name, HandleString valueArg,
unsigned attrs,
PropertyOp getter /* = nullptr */, JSStrictPropertyOp setter /* = nullptr */)
Native getter /* = nullptr */, Native setter /* = nullptr */)
{
RootedValue value(cx, StringValue(valueArg));
return DefineProperty(cx, obj, name, value, GetterWrapper(getter), SetterWrapper(setter),
return DefineProperty(cx, obj, name, value, NativeOpWrapper(getter), NativeOpWrapper(setter),
attrs, 0);
}
JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext *cx, HandleObject obj, const char *name, int32_t valueArg,
unsigned attrs,
PropertyOp getter /* = nullptr */, JSStrictPropertyOp setter /* = nullptr */)
Native getter /* = nullptr */, Native setter /* = nullptr */)
{
Value value = Int32Value(valueArg);
return DefineProperty(cx, obj, name, HandleValue::fromMarkedLocation(&value),
GetterWrapper(getter), SetterWrapper(setter), attrs, 0);
NativeOpWrapper(getter), NativeOpWrapper(setter), attrs, 0);
}
JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext *cx, HandleObject obj, const char *name, uint32_t valueArg,
unsigned attrs,
PropertyOp getter /* = nullptr */, JSStrictPropertyOp setter /* = nullptr */)
Native getter /* = nullptr */, Native setter /* = nullptr */)
{
Value value = UINT_TO_JSVAL(valueArg);
return DefineProperty(cx, obj, name, HandleValue::fromMarkedLocation(&value),
GetterWrapper(getter), SetterWrapper(setter), attrs, 0);
NativeOpWrapper(getter), NativeOpWrapper(setter), attrs, 0);
}
JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext *cx, HandleObject obj, const char *name, double valueArg,
unsigned attrs,
PropertyOp getter /* = nullptr */, JSStrictPropertyOp setter /* = nullptr */)
Native getter /* = nullptr */, Native setter /* = nullptr */)
{
Value value = NumberValue(valueArg);
return DefineProperty(cx, obj, name, HandleValue::fromMarkedLocation(&value),
GetterWrapper(getter), SetterWrapper(setter), attrs, 0);
NativeOpWrapper(getter), NativeOpWrapper(setter), attrs, 0);
}
static bool
DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
const Value &value_, PropertyOp getter, StrictPropertyOp setter, unsigned attrs,
const Value &value_, Native getter, Native setter, unsigned attrs,
unsigned flags)
{
RootedValue value(cx, value_);
@ -3138,14 +3132,14 @@ DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t n
if (!atom)
return false;
RootedId id(cx, AtomToId(atom));
return DefinePropertyById(cx, obj, id, value, GetterWrapper(getter), SetterWrapper(setter),
return DefinePropertyById(cx, obj, id, value, NativeOpWrapper(getter), NativeOpWrapper(setter),
attrs, flags);
}
JS_PUBLIC_API(bool)
JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
HandleValue value, unsigned attrs,
JSPropertyOp getter, JSStrictPropertyOp setter)
Native getter, Native setter)
{
return DefineUCProperty(cx, obj, name, namelen, value, getter, setter, attrs, 0);
}
@ -3153,7 +3147,7 @@ JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_
JS_PUBLIC_API(bool)
JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
HandleObject valueArg, unsigned attrs,
JSPropertyOp getter, JSStrictPropertyOp setter)
Native getter, Native setter)
{
RootedValue value(cx, ObjectValue(*valueArg));
return DefineUCProperty(cx, obj, name, namelen, value, getter, setter, attrs, 0);
@ -3162,7 +3156,7 @@ JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_
JS_PUBLIC_API(bool)
JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
HandleString valueArg, unsigned attrs,
JSPropertyOp getter, JSStrictPropertyOp setter)
Native getter, Native setter)
{
RootedValue value(cx, StringValue(valueArg));
return DefineUCProperty(cx, obj, name, namelen, value, getter, setter, attrs, 0);
@ -3171,7 +3165,7 @@ JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_
JS_PUBLIC_API(bool)
JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
int32_t valueArg, unsigned attrs,
JSPropertyOp getter, JSStrictPropertyOp setter)
Native getter, Native setter)
{
Value value = Int32Value(valueArg);
return DefineUCProperty(cx, obj, name, namelen, HandleValue::fromMarkedLocation(&value),
@ -3181,7 +3175,7 @@ JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_
JS_PUBLIC_API(bool)
JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
uint32_t valueArg, unsigned attrs,
JSPropertyOp getter, JSStrictPropertyOp setter)
Native getter, Native setter)
{
Value value = UINT_TO_JSVAL(valueArg);
return DefineUCProperty(cx, obj, name, namelen, HandleValue::fromMarkedLocation(&value),
@ -3191,7 +3185,7 @@ JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_
JS_PUBLIC_API(bool)
JS_DefineUCProperty(JSContext *cx, HandleObject obj, const char16_t *name, size_t namelen,
double valueArg, unsigned attrs,
JSPropertyOp getter, JSStrictPropertyOp setter)
Native getter, Native setter)
{
Value value = NumberValue(valueArg);
return DefineUCProperty(cx, obj, name, namelen, HandleValue::fromMarkedLocation(&value),
@ -3215,7 +3209,7 @@ JS_DefineObject(JSContext *cx, HandleObject obj, const char *name, const JSClass
return nullptr;
RootedValue nobjValue(cx, ObjectValue(*nobj));
if (!DefineProperty(cx, obj, name, nobjValue, GetterWrapper(nullptr), SetterWrapper(nullptr),
if (!DefineProperty(cx, obj, name, nobjValue, NativeOpWrapper(nullptr), NativeOpWrapper(nullptr),
attrs, 0)) {
return nullptr;
}
@ -3240,8 +3234,8 @@ DefineConstScalar(JSContext *cx, HandleObject obj, const JSConstScalarSpec<T> *c
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
JSPropertyOpWrapper noget = GetterWrapper(nullptr);
JSStrictPropertyOpWrapper noset = SetterWrapper(nullptr);
JSNativeWrapper noget = NativeOpWrapper(nullptr);
JSNativeWrapper noset = NativeOpWrapper(nullptr);
unsigned attrs = JSPROP_READONLY | JSPROP_PERMANENT;
for (; cds->name; cds++) {
RootedValue value(cx, ValueFromScalar(cds->val));
@ -3306,27 +3300,13 @@ JS_DefineProperties(JSContext *cx, HandleObject obj, const JSPropertySpec *ps)
if (!PropertySpecNameToId(cx, ps->name, &id))
return false;
if (ps->flags & JSPROP_NATIVE_ACCESSORS) {
// If you declare native accessors, then you should have a native
// getter.
MOZ_ASSERT(ps->getter.propertyOp.op);
// If you do not have a self-hosted getter, you should not have a
// self-hosted setter. This is the closest approximation to that
// assertion we can have with our setup.
MOZ_ASSERT_IF(ps->setter.propertyOp.info, ps->setter.propertyOp.op);
if (!ps->isSelfHosted()) {
if (!DefinePropertyById(cx, obj, id, JS::UndefinedHandleValue,
ps->getter.propertyOp, ps->setter.propertyOp, ps->flags, 0))
ps->getter.native, ps->setter.native, ps->flags, 0))
{
return false;
}
} else {
// If you have self-hosted getter/setter, you can't have a
// native one.
MOZ_ASSERT(!ps->getter.propertyOp.op && !ps->setter.propertyOp.op);
MOZ_ASSERT(ps->flags & JSPROP_GETTER);
if (!DefineSelfHostedProperty(cx, obj, id,
ps->getter.selfHosted.funname,
ps->setter.selfHosted.funname,

View File

@ -964,8 +964,9 @@ class MOZ_STACK_CLASS SourceBufferHolder MOZ_FINAL
JSPROP_GETTER nor JSPROP_SETTER is
set. */
#define JSPROP_PERMANENT 0x04 /* property cannot be deleted */
#define JSPROP_NATIVE_ACCESSORS 0x08 /* set in JSPropertyDescriptor.flags
if getters/setters are JSNatives */
#define JSPROP_PROPOP_ACCESSORS 0x08 /* Passed to JS_Define(UC)Property* and
JS_DefineElement if getters/setters
are JSPropertyOp/JSStrictPropertyOp */
#define JSPROP_GETTER 0x10 /* property holds getter function */
#define JSPROP_SETTER 0x20 /* property holds setter function */
#define JSPROP_SHARED 0x40 /* don't allocate a value slot for this
@ -2390,22 +2391,9 @@ typedef JSConstScalarSpec<int32_t> JSConstIntegerSpec;
struct JSJitInfo;
/*
* Wrappers to replace {Strict,}PropertyOp for JSPropertySpecs. This will allow
* us to pass one JSJitInfo per function with the property spec, without
* additional field overhead.
*/
typedef struct JSStrictPropertyOpWrapper {
JSStrictPropertyOp op;
const JSJitInfo *info;
} JSStrictPropertyOpWrapper;
typedef struct JSPropertyOpWrapper {
JSPropertyOp op;
const JSJitInfo *info;
} JSPropertyOpWrapper;
/*
* Wrapper to do as above, but for JSNatives for JSFunctionSpecs.
* Wrapper to relace JSNative for JSPropertySpecs and JSFunctionSpecs. This will
* allow us to pass one JSJitInfo per function with the property/function spec,
* without additional field overhead.
*/
typedef struct JSNativeWrapper {
JSNative op;
@ -2416,8 +2404,7 @@ typedef struct JSNativeWrapper {
* Macro static initializers which make it easy to pass no JSJitInfo as part of a
* JSPropertySpec or JSFunctionSpec.
*/
#define JSOP_WRAPPER(op) { {op, nullptr} }
#define JSOP_NULLWRAPPER JSOP_WRAPPER(nullptr)
#define JSNATIVE_WRAPPER(native) { {native, nullptr} }
/*
* To define an array element rather than a named property member, cast the
@ -2433,22 +2420,45 @@ struct JSPropertySpec {
const char *name;
uint8_t flags;
union {
JSPropertyOpWrapper propertyOp;
JSNativeWrapper native;
SelfHostedWrapper selfHosted;
} getter;
union {
JSStrictPropertyOpWrapper propertyOp;
JSNativeWrapper native;
SelfHostedWrapper selfHosted;
} setter;
static_assert(sizeof(SelfHostedWrapper) == sizeof(JSPropertyOpWrapper),
"JSPropertySpec::getter must be compact");
static_assert(sizeof(SelfHostedWrapper) == sizeof(JSStrictPropertyOpWrapper),
"JSPropertySpec::setter must be compact");
static_assert(offsetof(SelfHostedWrapper, funname) == offsetof(JSPropertyOpWrapper, info),
bool isSelfHosted() const {
#ifdef DEBUG
// Verify that our accessors match our JSPROP_GETTER flag.
if (flags & JSPROP_GETTER)
checkAccessorsAreSelfHosted();
else
checkAccessorsAreNative();
#endif
return (flags & JSPROP_GETTER);
}
static_assert(sizeof(SelfHostedWrapper) == sizeof(JSNativeWrapper),
"JSPropertySpec::getter/setter must be compact");
static_assert(offsetof(SelfHostedWrapper, funname) == offsetof(JSNativeWrapper, info),
"JS_SELF_HOSTED* macros below require that "
"SelfHostedWrapper::funname overlay "
"JSPropertyOpWrapper::info");
"JSNativeWrapper::info");
private:
void checkAccessorsAreNative() const {
MOZ_ASSERT(getter.native.op);
// We may not have a setter at all. So all we can assert here, for the
// native case is that if we have a jitinfo for the setter then we have
// a setter op too. This is good enough to make sure we don't have a
// SelfHostedWrapper for the setter.
MOZ_ASSERT_IF(setter.native.info, setter.native.op);
}
void checkAccessorsAreSelfHosted() const {
MOZ_ASSERT(!getter.selfHosted.unused);
MOZ_ASSERT(!setter.selfHosted.unused);
}
};
namespace JS {
@ -2462,6 +2472,13 @@ template<size_t N>
inline int
CheckIsCharacterLiteral(const char (&arr)[N]);
/* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_GETTER only. */
inline int CheckIsPropertyOp(JSPropertyOp op);
/* NEVER DEFINED, DON'T USE. For use by JS_PROPERTYOP_SETTER only. */
inline int CheckIsStrictPropertyOp(JSStrictPropertyOp op);
} // namespace detail
} // namespace JS
@ -2474,37 +2491,47 @@ CheckIsCharacterLiteral(const char (&arr)[N]);
reinterpret_cast<To>(s))
#define JS_CHECK_ACCESSOR_FLAGS(flags) \
(static_cast<mozilla::EnableIf<!((flags) & (JSPROP_READONLY | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS))>::Type>(0), \
(static_cast<mozilla::EnableIf<!((flags) & (JSPROP_READONLY | JSPROP_SHARED | JSPROP_PROPOP_ACCESSORS))>::Type>(0), \
(flags))
#define JS_PROPERTYOP_GETTER(v) \
(static_cast<void>(sizeof(JS::detail::CheckIsPropertyOp(v))), \
reinterpret_cast<JSNative>(v))
#define JS_PROPERTYOP_SETTER(v) \
(static_cast<void>(sizeof(JS::detail::CheckIsStrictPropertyOp(v))), \
reinterpret_cast<JSNative>(v))
#define JS_STUBGETTER JS_PROPERTYOP_GETTER(JS_PropertyStub)
#define JS_STUBSETTER JS_PROPERTYOP_SETTER(JS_StrictPropertyStub)
/*
* JSPropertySpec uses JSAPI JSPropertyOp and JSStrictPropertyOp in function
* signatures. These macros encapsulate the definition of JSNative-backed
* JSPropertySpecs, performing type-safe casts on the getter/setter functions
* and adding the necessary property flags to trigger interpretation as
* JSNatives.
* JSPropertySpec uses JSNativeWrapper. These macros encapsulate the definition
* of JSNative-backed JSPropertySpecs, by defining the JSNativeWrappers for
* them.
*/
#define JS_PSG(name, getter, flags) \
{name, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \
JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \
JSOP_NULLWRAPPER}
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED), \
JSNATIVE_WRAPPER(getter), \
JSNATIVE_WRAPPER(nullptr)}
#define JS_PSGS(name, getter, setter, flags) \
{name, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \
JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \
JSOP_WRAPPER(JS_CAST_NATIVE_TO(setter, JSStrictPropertyOp))}
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED), \
JSNATIVE_WRAPPER(getter), \
JSNATIVE_WRAPPER(setter)}
#define JS_SELF_HOSTED_GET(name, getterName, flags) \
{name, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER), \
{ nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) }, \
JSOP_NULLWRAPPER }
JSNATIVE_WRAPPER(nullptr) }
#define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \
{name, \
uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER), \
{ nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) }, \
{ nullptr, JS_CAST_STRING_TO(setterName, const JSJitInfo *) } }
#define JS_PS_END { nullptr, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }
#define JS_PS_END { nullptr, 0, JSNATIVE_WRAPPER(nullptr), JSNATIVE_WRAPPER(nullptr) }
/*
* To define a native function, set call to a JSNativeWrapper. To define a
@ -2880,62 +2907,62 @@ JS_DefineProperties(JSContext *cx, JS::HandleObject obj, const JSPropertySpec *p
extern JS_PUBLIC_API(bool)
JS_DefineProperty(JSContext *cx, JS::HandleObject obj, const char *name, JS::HandleValue value,
unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
JSNative getter = nullptr, JSNative setter = nullptr);
extern JS_PUBLIC_API(bool)
JS_AlreadyHasOwnProperty(JSContext *cx, JS::HandleObject obj, const char *name,
@ -2985,7 +3012,6 @@ class PropertyDescriptorOperations
bool isEnumerable() const { return desc()->attrs & JSPROP_ENUMERATE; }
bool isReadonly() const { return desc()->attrs & JSPROP_READONLY; }
bool isPermanent() const { return desc()->attrs & JSPROP_PERMANENT; }
bool hasNativeAccessors() const { return desc()->attrs & JSPROP_NATIVE_ACCESSORS; }
bool hasGetterObject() const { return desc()->attrs & JSPROP_GETTER; }
bool hasSetterObject() const { return desc()->attrs & JSPROP_SETTER; }
bool hasGetterOrSetterObject() const { return desc()->attrs & (JSPROP_GETTER | JSPROP_SETTER); }
@ -3185,32 +3211,32 @@ JS_DeletePropertyById2(JSContext *cx, JS::HandleObject obj, JS::HandleId id, boo
extern JS_PUBLIC_API(bool)
JS_DefineUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name, size_t namelen,
JS::HandleValue value, unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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::HandleObject value, unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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::HandleString value, unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
int32_t value, unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
uint32_t value, unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
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,
double value, unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
JSNative getter = nullptr, JSNative setter = nullptr);
extern JS_PUBLIC_API(bool)
JS_AlreadyHasOwnUCProperty(JSContext *cx, JS::HandleObject obj, const char16_t *name,
@ -3261,32 +3287,32 @@ JS_SetArrayLength(JSContext *cx, JS::Handle<JSObject*> obj, uint32_t length);
extern JS_PUBLIC_API(bool)
JS_DefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value,
unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
JSNative getter = nullptr, JSNative setter = nullptr);
extern JS_PUBLIC_API(bool)
JS_DefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleObject value,
unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
JSNative getter = nullptr, JSNative setter = nullptr);
extern JS_PUBLIC_API(bool)
JS_DefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleString value,
unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
JSNative getter = nullptr, JSNative setter = nullptr);
extern JS_PUBLIC_API(bool)
JS_DefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, int32_t value,
unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
JSNative getter = nullptr, JSNative setter = nullptr);
extern JS_PUBLIC_API(bool)
JS_DefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, uint32_t value,
unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
JSNative getter = nullptr, JSNative setter = nullptr);
extern JS_PUBLIC_API(bool)
JS_DefineElement(JSContext *cx, JS::HandleObject obj, uint32_t index, double value,
unsigned attrs,
JSPropertyOp getter = nullptr, JSStrictPropertyOp setter = nullptr);
JSNative getter = nullptr, JSNative setter = nullptr);
extern JS_PUBLIC_API(bool)
JS_AlreadyHasOwnElement(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *foundp);

View File

@ -288,8 +288,9 @@ DefineHelpProperty(JSContext *cx, HandleObject obj, const char *prop, const char
RootedAtom atom(cx, Atomize(cx, value, strlen(value)));
if (!atom)
return false;
return JS_DefineProperty(cx, obj, prop, atom, JSPROP_READONLY | JSPROP_PERMANENT,
JS_PropertyStub, JS_StrictPropertyStub);
return JS_DefineProperty(cx, obj, prop, atom,
JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER);
}
JS_FRIEND_API(bool)

View File

@ -1567,8 +1567,8 @@ js_InitMathClass(JSContext *cx, HandleObject obj)
if (!Math)
return nullptr;
if (!JS_DefineProperty(cx, obj, js_Math_str, Math, 0,
JS_PropertyStub, JS_StrictPropertyStub))
if (!JS_DefineProperty(cx, obj, js_Math_str, Math, JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER))
{
return nullptr;
}

View File

@ -3009,7 +3009,7 @@ JSObject::defineGeneric(ExclusiveContext *cx, HandleObject obj,
HandleId id, HandleValue value,
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs)
{
MOZ_ASSERT(!(attrs & JSPROP_NATIVE_ACCESSORS));
MOZ_ASSERT(!(attrs & JSPROP_PROPOP_ACCESSORS));
js::DefineGenericOp op = obj->getOps()->defineGeneric;
if (op) {
if (!cx->shouldBeJSContext())

View File

@ -913,8 +913,9 @@ js_InitJSONClass(JSContext *cx, HandleObject obj)
if (!JSON)
return nullptr;
if (!JS_DefineProperty(cx, global, js_JSON_str, JSON, 0,
JS_PropertyStub, JS_StrictPropertyStub))
if (!JS_DefineProperty(cx, global, js_JSON_str, JSON,
JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER))
return nullptr;
if (!JS_DefineFunctions(cx, JSON, json_static_methods))

View File

@ -3541,8 +3541,8 @@ JS_InitReflect(JSContext *cx, HandleObject obj)
if (!Reflect)
return nullptr;
if (!JS_DefineProperty(cx, obj, "Reflect", Reflect, 0,
JS_PropertyStub, JS_StrictPropertyStub)) {
if (!JS_DefineProperty(cx, obj, "Reflect", Reflect, JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER)) {
return nullptr;
}

View File

@ -132,8 +132,6 @@ static const JSPropertySpec pm_props[] = {
// If this were C++ these would be "static const" members.
static const uint8_t PM_CATTRS = JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT;
#define CONSTANT(name) { #name, PerfMeasurement::name }
static const struct pm_const {
@ -233,6 +231,9 @@ namespace JS {
JSObject*
RegisterPerfMeasurement(JSContext *cx, HandleObject globalArg)
{
static const uint8_t PM_CATTRS =
JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_PROPOP_ACCESSORS;
RootedObject global(cx, globalArg);
RootedObject prototype(cx);
prototype = JS_InitClass(cx, global, js::NullPtr() /* parent */,
@ -248,7 +249,7 @@ RegisterPerfMeasurement(JSContext *cx, HandleObject globalArg)
for (const pm_const *c = pm_consts; c->name; c++) {
if (!JS_DefineProperty(cx, ctor, c->name, c->value, PM_CATTRS,
JS_PropertyStub, JS_StrictPropertyStub))
JS_STUBGETTER, JS_STUBSETTER))
return 0;
}

View File

@ -39,8 +39,15 @@ DirectProxyHandler::defineProperty(JSContext *cx, HandleObject proxy, HandleId i
assertEnteredPolicy(cx, proxy, id, SET);
RootedObject target(cx, proxy->as<ProxyObject>().target());
RootedValue v(cx, desc.value());
return CheckDefineProperty(cx, target, id, v, desc.attributes(), desc.getter(), desc.setter()) &&
JS_DefinePropertyById(cx, target, id, v, desc.attributes(), desc.getter(), desc.setter());
return CheckDefineProperty(cx, target, id, v, desc.attributes(),
desc.getter(), desc.setter()) &&
JS_DefinePropertyById(cx, target, id, v,
// 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()));
}
bool

View File

@ -893,8 +893,8 @@ js_InitProxyClass(JSContext *cx, HandleObject obj)
if (!JS_DefineFunctions(cx, ctor, static_methods))
return nullptr;
if (!JS_DefineProperty(cx, obj, "Proxy", ctor, 0,
JS_PropertyStub, JS_StrictPropertyStub)) {
if (!JS_DefineProperty(cx, obj, "Proxy", ctor, JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER)) {
return nullptr;
}

View File

@ -5071,9 +5071,9 @@ static const JSJitInfo doFoo_methodinfo = {
static const JSPropertySpec dom_props[] = {
{"x",
JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS,
{ { (JSPropertyOp)dom_genericGetter, &dom_x_getterinfo } },
{ { (JSStrictPropertyOp)dom_genericSetter, &dom_x_setterinfo } }
JSPROP_SHARED | JSPROP_ENUMERATE,
{ { dom_genericGetter, &dom_x_getterinfo } },
{ { dom_genericSetter, &dom_x_setterinfo } }
},
JS_PS_END
};

View File

@ -1392,7 +1392,7 @@ bool
js::DefineNativeProperty(ExclusiveContext *cx, HandleNativeObject obj, HandleId id, HandleValue value,
PropertyOp getter, StrictPropertyOp setter, unsigned attrs)
{
MOZ_ASSERT(!(attrs & JSPROP_NATIVE_ACCESSORS));
MOZ_ASSERT(!(attrs & JSPROP_PROPOP_ACCESSORS));
AutoRooterGetterSetter gsRoot(cx, attrs, &getter, &setter);

View File

@ -1677,7 +1677,13 @@ class DebugScopeProxy : public BaseProxyHandler
if (found)
return Throw(cx, id, JSMSG_CANT_REDEFINE_PROP);
return JS_DefinePropertyById(cx, scope, id, desc.value(), desc.attributes(), desc.getter(), desc.setter());
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()));
}
bool getScopePropertyNames(JSContext *cx, HandleObject proxy, AutoIdVector &props,

View File

@ -222,6 +222,18 @@ AutoRooterGetterSetter::AutoRooterGetterSetter(ThreadSafeContext *cx, uint8_t at
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
inline
AutoRooterGetterSetter::AutoRooterGetterSetter(ThreadSafeContext *cx, uint8_t attrs,
JSNative *pgetter, JSNative *psetter
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
{
if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
inner.emplace(cx, attrs, reinterpret_cast<PropertyOp *>(pgetter),
reinterpret_cast<StrictPropertyOp *>(psetter));
}
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
static inline uint8_t
GetShapeAttributes(JSObject *obj, Shape *shape)
{

View File

@ -1084,6 +1084,9 @@ class AutoRooterGetterSetter
inline AutoRooterGetterSetter(ThreadSafeContext *cx, uint8_t attrs,
PropertyOp *pgetter, StrictPropertyOp *psetter
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
inline AutoRooterGetterSetter(ThreadSafeContext *cx, uint8_t attrs,
JSNative *pgetter, JSNative *psetter
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
private:
mozilla::Maybe<Inner> inner;

View File

@ -424,8 +424,9 @@ ExportFunction(JSContext *cx, HandleValue vfunction, HandleValue vscope, HandleV
// defineAs was set, we also need to define it as a property on
// the target.
if (!JSID_IS_VOID(options.defineAs)) {
if (!JS_DefinePropertyById(cx, targetScope, id, rval, JSPROP_ENUMERATE,
JS_PropertyStub, JS_StrictPropertyStub)) {
if (!JS_DefinePropertyById(cx, targetScope, id, rval,
JSPROP_ENUMERATE | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER)) {
return false;
}
}
@ -468,8 +469,9 @@ CreateObjectIn(JSContext *cx, HandleValue vobj, CreateObjectInOptions &options,
return false;
if (define) {
if (!JS_DefinePropertyById(cx, scope, options.defineAs, obj, JSPROP_ENUMERATE,
JS_PropertyStub, JS_StrictPropertyStub))
if (!JS_DefinePropertyById(cx, scope, options.defineAs, obj,
JSPROP_ENUMERATE | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER))
return false;
}
}

View File

@ -443,8 +443,10 @@ sandbox_addProperty(JSContext *cx, HandleObject obj, HandleId id, MutableHandleV
if (!JS_GetPropertyDescriptorById(cx, obj, id, &pd))
return false;
unsigned attrs = pd.attributes() & ~(JSPROP_GETTER | JSPROP_SETTER);
if (!JS_DefinePropertyById(cx, obj, id, vp, attrs,
writeToProto_getProperty, writeToProto_setProperty))
if (!JS_DefinePropertyById(cx, obj, id, vp,
attrs | JSPROP_PROPOP_ACCESSORS,
JS_PROPERTYOP_GETTER(writeToProto_getProperty),
JS_PROPERTYOP_SETTER(writeToProto_setProperty)))
return false;
return true;

View File

@ -1503,8 +1503,8 @@ XRE_XPCShellMain(int argc, char **argv, char **envp)
gWorkingDirectory = &workingDirectory;
JS_DefineProperty(cx, glob, "__LOCATION__", JS::UndefinedHandleValue,
JSPROP_NATIVE_ACCESSORS | JSPROP_SHARED,
JS_CAST_NATIVE_TO(GetLocationProperty, JSPropertyOp),
JSPROP_SHARED,
GetLocationProperty,
nullptr);
// We are almost certainly going to run script here, so we need an

View File

@ -314,7 +314,7 @@ DefinePropertyIfFound(XPCCallContext& ccx,
if (resolved)
*resolved = true;
return JS_DefinePropertyById(ccx, obj, id, UndefinedHandleValue, propFlags,
JS_DATA_TO_FUNC_PTR(JSPropertyOp, funobj.get()),
JS_DATA_TO_FUNC_PTR(JSNative, funobj.get()),
nullptr);
}
@ -363,8 +363,13 @@ DefinePropertyIfFound(XPCCallContext& ccx,
AutoResolveName arn(ccx, id);
if (resolved)
*resolved = true;
return JS_DefinePropertyById(ccx, obj, id, desc.value(), desc.attributes(),
desc.getter(), desc.setter());
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()));
}
}
@ -393,11 +398,11 @@ DefinePropertyIfFound(XPCCallContext& ccx,
propFlags |= JSPROP_GETTER | JSPROP_SHARED;
propFlags &= ~JSPROP_READONLY;
JSObject* funobj = funval.toObjectOrNull();
JSPropertyOp getter = JS_DATA_TO_FUNC_PTR(JSPropertyOp, funobj);
JSStrictPropertyOp setter;
JSNative getter = JS_DATA_TO_FUNC_PTR(JSNative, funobj);
JSNative setter;
if (member->IsWritableAttribute()) {
propFlags |= JSPROP_SETTER;
setter = JS_DATA_TO_FUNC_PTR(JSStrictPropertyOp, funobj);
setter = JS_DATA_TO_FUNC_PTR(JSNative, funobj);
} else {
setter = nullptr;
}

View File

@ -501,16 +501,15 @@ JSXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper,
}
if (psMatch) {
desc.value().setUndefined();
// Note that this is also kind of an abuse of JSPROP_NATIVE_ACCESSORS.
// See bug 992977.
RootedFunction getterObj(cx);
RootedFunction setterObj(cx);
unsigned flags = psMatch->flags;
if (flags & JSPROP_NATIVE_ACCESSORS) {
desc.setGetter(psMatch->getter.propertyOp.op);
desc.setSetter(psMatch->setter.propertyOp.op);
if (!psMatch->isSelfHosted()) {
desc.setGetter(JS_CAST_NATIVE_TO(psMatch->getter.native.op,
JSPropertyOp));
desc.setSetter(JS_CAST_NATIVE_TO(psMatch->setter.native.op,
JSStrictPropertyOp));
} else {
MOZ_ASSERT(flags & JSPROP_GETTER);
getterObj = JS::GetSelfHostedFunction(cx, psMatch->getter.selfHosted.funname, id, 0);
if (!getterObj)
return false;
@ -534,8 +533,14 @@ JSXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper,
// pass along JITInfo. It's probably ok though, since Xrays are already
// pretty slow.
return JS_DefinePropertyById(cx, holder, id,
UndefinedHandleValue, desc.attributes(),
desc.getter(), desc.setter()) &&
UndefinedHandleValue,
// This particular descriptor, unlike most,
// actually stores JSNatives directly,
// since we just set it up. Do NOT pass
// JSPROP_PROPOP_ACCESSORS here!
desc.attributes(),
JS_PROPERTYOP_GETTER(desc.getter()),
JS_PROPERTYOP_SETTER(desc.setter())) &&
JS_GetPropertyDescriptorById(cx, holder, id, desc);
}
@ -613,8 +618,9 @@ 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_PropertyStub, JS_StrictPropertyStub))
!JS_DefinePropertyById(cx, target, id, desc.value(),
desc.attributes() | JSPROP_PROPOP_ACCESSORS,
JS_STUBGETTER, JS_STUBSETTER))
{
return false;
}
@ -726,7 +732,7 @@ JSXrayTraits::enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flags
// to be any self-hosted accessors anywhere in SpiderMonkey, let alone in on an
// Xrayable class, so we can't test it. Assert against it to make sure that we get
// test coverage in test_XrayToJS.xul when the time comes.
MOZ_ASSERT(ps->flags & JSPROP_NATIVE_ACCESSORS,
MOZ_ASSERT(!ps->isSelfHosted(),
"Self-hosted accessor added to Xrayable class - ping the XPConnect "
"module owner about adding test coverage");
@ -1181,8 +1187,13 @@ XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext *cx, HandleObject wr
FillPropertyDescriptor(desc, wrapper, 0,
ObjectValue(*JS_GetFunctionObject(toString)));
return JS_DefinePropertyById(cx, holder, id, desc.value(), desc.attributes(),
desc.getter(), desc.setter()) &&
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())) &&
JS_GetPropertyDescriptorById(cx, holder, id, desc);
}
@ -1238,8 +1249,13 @@ XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext *cx, HandleObject wr
desc.setSetterObject(&fval.toObject());
// Define the property.
return JS_DefinePropertyById(cx, holder, id, desc.value(), desc.attributes(),
desc.getter(), desc.setter());
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()));
}
static bool
@ -1320,10 +1336,8 @@ XrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper,
if (!JS_AlreadyHasOwnPropertyById(cx, holder, id, &found))
return false;
if (!found && !JS_DefinePropertyById(cx, holder, id, UndefinedHandleValue,
JSPROP_ENUMERATE | JSPROP_SHARED |
JSPROP_NATIVE_ACCESSORS,
JS_CAST_NATIVE_TO(wrappedJSObject_getter,
JSPropertyOp))) {
JSPROP_ENUMERATE | JSPROP_SHARED,
wrappedJSObject_getter)) {
return false;
}
if (!JS_GetPropertyDescriptorById(cx, holder, id, desc))
@ -1534,8 +1548,13 @@ DOMXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper, Handl
if (!desc.object() || !cacheOnHolder)
return true;
return JS_DefinePropertyById(cx, holder, id, desc.value(), desc.attributes(),
desc.getter(), desc.setter()) &&
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())) &&
JS_GetPropertyDescriptorById(cx, holder, id, desc);
}
@ -1854,8 +1873,13 @@ XrayWrapper<Base, Traits>::getPropertyDescriptor(JSContext *cx, HandleObject wra
if (!desc.object())
return true;
if (!JS_DefinePropertyById(cx, holder, id, desc.value(), desc.attributes(),
desc.getter(), desc.setter()) ||
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())) ||
!JS_GetPropertyDescriptorById(cx, holder, id, desc))
{
return false;
@ -2001,8 +2025,12 @@ XrayWrapper<Base, Traits>::defineProperty(JSContext *cx, HandleObject wrapper,
return false;
return JS_DefinePropertyById(cx, expandoObject, id, wrappedDesc.value(),
wrappedDesc.get().attrs,
wrappedDesc.getter(), wrappedDesc.setter());
// 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()));
}
template <typename Base, typename Traits>