Bug 1122552 - Introduce [[GetOwnProperty]] object op. r=jorendorff,bz

This commit is contained in:
Tom Schuster 2015-01-22 17:17:26 +01:00
parent d57bb36810
commit dea3c49818
12 changed files with 134 additions and 4 deletions

View File

@ -404,6 +404,7 @@ class CGDOMJSClass(CGThing):
nullptr, /* setGeneric */
nullptr, /* setProperty */
nullptr, /* setElement */
nullptr, /* getOwnPropertyDescriptor */
nullptr, /* getGenericAttributes */
nullptr, /* setGenericAttributes */
nullptr, /* deleteGeneric */

View File

@ -234,6 +234,7 @@ const static js::Class sNPObjectJSWrapperClass =
nullptr, // setGeneric
nullptr, // setProperty
nullptr, // setElement
nullptr, // getOwnPropertyDescriptor
nullptr, // getGenericAttributes
nullptr, // setGenericAttributes
nullptr, // deleteGeneric

View File

@ -199,6 +199,9 @@ typedef bool
(* StrictElementIdOp)(JSContext *cx, JS::HandleObject obj, uint32_t index,
JS::MutableHandleValue vp, bool strict);
typedef bool
(* GetOwnPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
typedef bool
(* GenericAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp);
typedef bool
(* PropertyAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
@ -378,6 +381,7 @@ struct ObjectOps
StrictGenericIdOp setGeneric;
StrictPropertyIdOp setProperty;
StrictElementIdOp setElement;
GetOwnPropertyOp getOwnPropertyDescriptor;
GenericAttributesOp getGenericAttributes;
GenericAttributesOp setGenericAttributes;
DeleteGenericOp deleteGeneric;
@ -391,7 +395,7 @@ struct ObjectOps
#define JS_NULL_OBJECT_OPS \
{nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, \
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, \
nullptr, nullptr, nullptr}
nullptr, nullptr, nullptr, nullptr}
} // namespace js
@ -402,7 +406,7 @@ typedef void (*JSClassInternal)();
struct JSClass {
JS_CLASS_MEMBERS(JSFinalizeOp);
void *reserved[32];
void *reserved[33];
};
#define JSCLASS_HAS_PRIVATE (1<<0) // objects have private slot

View File

@ -2003,6 +2003,66 @@ TypedObject::obj_setArrayElement(JSContext *cx,
return ConvertAndCopyTo(cx, elementType, typedObj, offset, NullPtr(), vp);
}
bool
TypedObject::obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc)
{
Rooted<TypedObject *> typedObj(cx, &obj->as<TypedObject>());
if (!typedObj->isAttached()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_TYPEDOBJECT_HANDLE_UNATTACHED);
return false;
}
Rooted<TypeDescr *> descr(cx, &typedObj->typeDescr());
switch (descr->kind()) {
case type::Scalar:
case type::Reference:
case type::Simd:
break;
case type::Array:
{
uint32_t index;
if (js_IdIsIndex(id, &index)) {
if (!obj_getArrayElement(cx, typedObj, descr, index, desc.value()))
return false;
desc.setAttributes(JSPROP_ENUMERATE | JSPROP_PERMANENT);
desc.object().set(obj);
return true;
}
if (JSID_IS_ATOM(id, cx->names().length)) {
desc.value().setInt32(typedObj->length());
desc.setAttributes(JSPROP_READONLY | JSPROP_PERMANENT);
desc.object().set(obj);
return true;
}
break;
}
case type::Struct:
{
Rooted<StructTypeDescr*> descr(cx, &typedObj->typeDescr().as<StructTypeDescr>());
size_t fieldIndex;
if (!descr->fieldIndex(id, &fieldIndex))
break;
size_t offset = descr->fieldOffset(fieldIndex);
Rooted<TypeDescr*> fieldType(cx, &descr->fieldDescr(fieldIndex));
if (!Reify(cx, fieldType, typedObj, offset, desc.value()))
return false;
desc.setAttributes(JSPROP_ENUMERATE | JSPROP_PERMANENT);
desc.object().set(obj);
return true;
}
}
desc.object().set(nullptr);
return true;
}
bool
TypedObject::obj_getGenericAttributes(JSContext *cx, HandleObject obj,
HandleId id, unsigned *attrsp)
@ -2365,6 +2425,7 @@ LazyArrayBufferTable::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf)
TypedObject::obj_setGeneric, \
TypedObject::obj_setProperty, \
TypedObject::obj_setElement, \
TypedObject::obj_getOwnPropertyDescriptor, \
TypedObject::obj_getGenericAttributes, \
TypedObject::obj_setGenericAttributes, \
TypedObject::obj_deleteGeneric, \

View File

@ -564,6 +564,9 @@ class TypedObject : public JSObject
static bool obj_setElement(JSContext *cx, HandleObject obj, uint32_t index,
MutableHandleValue vp, bool strict);
static bool obj_getOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc);
static bool obj_getGenericAttributes(JSContext *cx, HandleObject obj,
HandleId id, unsigned *attrsp);
static bool obj_setGenericAttributes(JSContext *cx, HandleObject obj,

View File

@ -301,6 +301,7 @@ namespace js {
js::proxy_SetGeneric, \
js::proxy_SetProperty, \
js::proxy_SetElement, \
js::proxy_GetOwnPropertyDescriptor, \
js::proxy_GetGenericAttributes, \
js::proxy_SetGenericAttributes, \
js::proxy_DeleteGeneric, \
@ -364,6 +365,9 @@ extern JS_FRIEND_API(bool)
proxy_SetElement(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::MutableHandleValue vp,
bool strict);
extern JS_FRIEND_API(bool)
proxy_GetOwnPropertyDescriptor(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
JS::MutableHandle<JSPropertyDescriptor> desc);
extern JS_FRIEND_API(bool)
proxy_GetGenericAttributes(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp);
extern JS_FRIEND_API(bool)
proxy_SetGenericAttributes(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp);

View File

@ -3196,8 +3196,8 @@ bool
js::GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<PropertyDescriptor> desc)
{
if (obj->is<ProxyObject>())
return Proxy::getOwnPropertyDescriptor(cx, obj, id, desc);
if (GetOwnPropertyOp op = obj->getOps()->getOwnPropertyDescriptor)
return op(cx, obj, id, desc);
RootedObject pobj(cx);
RootedShape shape(cx);

View File

@ -667,6 +667,13 @@ js::proxy_SetElement(JSContext *cx, HandleObject obj, uint32_t index,
return proxy_SetGeneric(cx, obj, id, vp, strict);
}
bool
js::proxy_GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc)
{
return Proxy::getOwnPropertyDescriptor(cx, obj, id, desc);
}
bool
js::proxy_GetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
{

View File

@ -0,0 +1,28 @@
// |reftest| skip-if(!this.hasOwnProperty("TypedObject"))
var BUGNUMBER = 1122552;
var summary = 'Introduce [[GetOwnProperty]] object op';
var StructType = TypedObject.StructType;
var uint8 = TypedObject.uint8;
function runTests() {
print(BUGNUMBER + ": " + summary);
var PixelType = new StructType({x: uint8, y: uint8});
var pixel = new PixelType({x: 15, y: 16});
var desc = Object.getOwnPropertyDescriptor(pixel, 'x');
assertEq(typeof desc, "object");
assertEq(desc.value, 15);
assertEq(desc.enumerable, true);
assertEq(desc.writable, true);
assertEq(desc.configurable, false);
desc = Object.getOwnPropertyDescriptor(pixel, 'dummy');
assertEq(typeof desc, "undefined");
reportCompare(true, true);
print("Tests complete");
}
runTests();

View File

@ -562,6 +562,14 @@ with_SetElement(JSContext *cx, HandleObject obj, uint32_t index,
return SetElement(cx, actual, actual, index, vp, strict);
}
static bool
with_GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc)
{
RootedObject actual(cx, &obj->as<DynamicWithObject>().object());
return GetOwnPropertyDescriptor(cx, obj, id, desc);
}
static bool
with_GetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
{
@ -627,6 +635,7 @@ const Class DynamicWithObject::class_ = {
with_SetGeneric,
with_SetProperty,
with_SetElement,
with_GetOwnPropertyDescriptor,
with_GetGenericAttributes,
with_SetGenericAttributes,
with_DeleteGeneric,
@ -1064,6 +1073,14 @@ uninitialized_SetElement(JSContext *cx, HandleObject obj, uint32_t index,
return uninitialized_SetGeneric(cx, obj, id, vp, strict);
}
static bool
uninitialized_GetOwnPropertyDescriptor(JSContext *cx, HandleObject obj, HandleId id,
MutableHandle<JSPropertyDescriptor> desc)
{
ReportUninitializedLexicalId(cx, id);
return false;
}
static bool
uninitialized_GetGenericAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *attrsp)
{
@ -1116,6 +1133,7 @@ const Class UninitializedLexicalObject::class_ = {
uninitialized_SetGeneric,
uninitialized_SetProperty,
uninitialized_SetElement,
uninitialized_GetOwnPropertyDescriptor,
uninitialized_GetGenericAttributes,
uninitialized_SetGenericAttributes,
uninitialized_DeleteGeneric,

View File

@ -693,6 +693,7 @@ const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
nullptr, // setGeneric
nullptr, // setProperty
nullptr, // setElement
nullptr, // getOwnPropertyDescriptor
nullptr, // getGenericAttributes
nullptr, // setGenericAttributes
nullptr, // deleteGeneric

View File

@ -986,6 +986,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
nullptr, /* setGeneric */ \
nullptr, /* setProperty */ \
nullptr, /* setElement */ \
nullptr, /* getOwnPropertyDescriptor */ \
nullptr, /* getGenericAttributes */ \
nullptr, /* setGenericAttributes */ \
nullptr, /* deleteGeneric */ \
@ -1009,6 +1010,7 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS::HandleObject obj);
nullptr, /* setGeneric */ \
nullptr, /* setProperty */ \
nullptr, /* setElement */ \
nullptr, /* getOwnPropertyDescriptor */ \
nullptr, /* getGenericAttributes */ \
nullptr, /* setGenericAttributes */ \
nullptr, /* deleteGeneric */ \