Bug 829813 - Cleanup API for marking/testing implicit properties, r=billm.

This commit is contained in:
Brian Hackett 2013-01-14 16:15:30 -07:00
parent 49f9c17185
commit f46a1207b1
8 changed files with 40 additions and 32 deletions

View File

@ -159,7 +159,7 @@ obj_toSource(JSContext *cx, unsigned argc, Value *vp)
int valcnt = 0;
if (shape) {
bool doGet = true;
if (obj2->isNative() && !IsImplicitProperty(shape)) {
if (obj2->isNative() && !IsImplicitDenseElement(shape)) {
unsigned attrs = shape->attributes();
if (attrs & JSPROP_GETTER) {
doGet = false;
@ -456,7 +456,7 @@ obj_lookupGetter(JSContext *cx, unsigned argc, Value *vp)
return JS_FALSE;
args.rval().setUndefined();
if (shape) {
if (pobj->isNative() && !IsImplicitProperty(shape)) {
if (pobj->isNative() && !IsImplicitDenseElement(shape)) {
if (shape->hasGetterValue())
args.rval().set(shape->getterValue());
}
@ -492,7 +492,7 @@ obj_lookupSetter(JSContext *cx, unsigned argc, Value *vp)
return JS_FALSE;
args.rval().setUndefined();
if (shape) {
if (pobj->isNative() && !IsImplicitProperty(shape)) {
if (pobj->isNative() && !IsImplicitDenseElement(shape)) {
if (shape->hasSetterValue())
args.rval().set(shape->setterValue());
}

View File

@ -1747,7 +1747,7 @@ ParallelArrayObject::lookupElement(JSContext *cx, HandleObject obj, uint32_t ind
{
// No prototype walking for elements.
if (index < as(obj)->outermostDimension()) {
MarkImplicitPropertyFound(propp);
MarkNonNativePropertyFound(propp);
objp.set(obj);
return true;
}

View File

@ -3572,7 +3572,7 @@ LookupResult(JSContext *cx, HandleObject obj, HandleObject obj2, jsid id,
return JS_TRUE;
}
if (IsImplicitProperty(shape)) {
if (!obj2->isNative()) {
if (obj2->isProxy()) {
AutoPropertyDescriptorRooter desc(cx);
if (!Proxy::getPropertyDescriptor(cx, obj2, id, &desc, 0))
@ -3581,10 +3581,10 @@ LookupResult(JSContext *cx, HandleObject obj, HandleObject obj2, jsid id,
*vp = desc.value;
return true;
}
} else if (obj2->isNative()) {
*vp = obj2->getDenseElement(JSID_TO_INT(id));
return true;
}
} else if (IsImplicitDenseElement(shape)) {
*vp = obj2->getDenseElement(JSID_TO_INT(id));
return true;
} else {
/* Peek at the native property's slot value, without doing a Get. */
if (shape->hasSlot()) {
@ -4062,7 +4062,7 @@ GetPropertyDescriptorById(JSContext *cx, HandleObject obj, HandleId id, unsigned
desc->obj = obj2;
if (obj2->isNative()) {
if (IsImplicitProperty(shape)) {
if (IsImplicitDenseElement(shape)) {
desc->attrs = JSPROP_ENUMERATE;
desc->getter = NULL;
desc->setter = NULL;

View File

@ -1103,7 +1103,7 @@ SuppressDeletedPropertyHelper(JSContext *cx, HandleObject obj, StringPredicate p
if (prop) {
unsigned attrs;
if (obj2->isNative())
attrs = IsImplicitProperty(prop) ? JSPROP_ENUMERATE : prop->attributes();
attrs = GetShapeAttributes(prop);
else if (!JSObject::getGenericAttributes(cx, obj2, id, &attrs))
return false;

View File

@ -631,7 +631,7 @@ DefinePropertyOnObject(JSContext *cx, HandleObject obj, HandleId id, const PropD
shapeHasGetterValue = false,
shapeHasSetterValue = false;
uint8_t shapeAttributes = JSPROP_ENUMERATE;
if (!IsImplicitProperty(shape)) {
if (!IsImplicitDenseElement(shape)) {
shapeDataDescriptor = shape->isDataDescriptor();
shapeAccessorDescriptor = shape->isAccessorDescriptor();
shapeWritable = shape->writable();
@ -672,7 +672,7 @@ DefinePropertyOnObject(JSContext *cx, HandleObject obj, HandleId id, const PropD
* avoid calling a getter; we won't need the value if it's not a
* data descriptor.
*/
if (IsImplicitProperty(shape)) {
if (IsImplicitDenseElement(shape)) {
v = obj->getDenseElement(JSID_TO_INT(id));
} else if (shape->isDataDescriptor()) {
/*
@ -814,8 +814,8 @@ DefinePropertyOnObject(JSContext *cx, HandleObject obj, HandleId id, const PropD
changed |= JSPROP_ENUMERATE;
attrs = (shapeAttributes & ~changed) | (desc.attributes() & changed);
getter = IsImplicitProperty(shape) ? JS_PropertyStub : shape->getter();
setter = IsImplicitProperty(shape) ? JS_StrictPropertyStub : shape->setter();
getter = IsImplicitDenseElement(shape) ? JS_PropertyStub : shape->getter();
setter = IsImplicitDenseElement(shape) ? JS_StrictPropertyStub : shape->setter();
} else if (desc.isDataDescriptor()) {
unsigned unchanged = 0;
if (!desc.hasConfigurable())
@ -3064,7 +3064,7 @@ js::DefineNativeProperty(JSContext *cx, HandleObject obj, HandleId id, HandleVal
if (!baseops::LookupProperty(cx, obj, id, &pobj, &shape))
return false;
if (shape && pobj == obj) {
if (IsImplicitProperty(shape)) {
if (IsImplicitDenseElement(shape)) {
if (!JSObject::sparsifyDenseElement(cx, obj, JSID_TO_INT(id)))
return false;
shape = obj->nativeLookup(cx, id);
@ -3237,7 +3237,7 @@ CallResolveOp(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
}
if (JSID_IS_INT(id) && objp->containsDenseElement(JSID_TO_INT(id))) {
MarkImplicitPropertyFound(propp);
MarkDenseElementFound(propp);
return true;
}
@ -3263,7 +3263,7 @@ LookupPropertyWithFlagsInline(JSContext *cx, HandleObject obj, HandleId id, unsi
{
if (JSID_IS_INT(id) && current->containsDenseElement(JSID_TO_INT(id))) {
objp.set(current);
MarkImplicitPropertyFound(propp);
MarkDenseElementFound(propp);
return true;
}
@ -3549,7 +3549,7 @@ js_GetPropertyHelperInline(JSContext *cx, HandleObject obj, HandleObject receive
: JSObject::getGeneric(cx, obj2, obj2, id, vp);
}
if (IsImplicitProperty(shape)) {
if (IsImplicitDenseElement(shape)) {
vp.set(obj2->getDenseElement(JSID_TO_INT(id)));
return true;
}
@ -3804,7 +3804,7 @@ baseops::SetPropertyHelper(JSContext *cx, HandleObject obj, HandleObject receive
getter = clasp->getProperty;
setter = clasp->setProperty;
if (IsImplicitProperty(shape)) {
if (IsImplicitDenseElement(shape)) {
/* ES5 8.12.4 [[Put]] step 2, for a dense data property on pobj. */
if (pobj != obj)
shape = NULL;
@ -3877,7 +3877,7 @@ baseops::SetPropertyHelper(JSContext *cx, HandleObject obj, HandleObject receive
}
}
if (IsImplicitProperty(shape)) {
if (IsImplicitDenseElement(shape)) {
JSObject::setDenseElementWithType(cx, obj, JSID_TO_INT(id), vp);
return true;
}
@ -4006,7 +4006,7 @@ baseops::SetAttributes(JSContext *cx, HandleObject obj, HandleId id, unsigned *a
return false;
if (!shape)
return true;
if (nobj->isNative() && IsImplicitProperty(shape)) {
if (nobj->isNative() && IsImplicitDenseElement(shape)) {
if (!JSObject::sparsifyDenseElement(cx, nobj, JSID_TO_INT(id)))
return false;
shape = obj->nativeLookup(cx, id);
@ -4025,7 +4025,7 @@ baseops::SetElementAttributes(JSContext *cx, HandleObject obj, uint32_t index, u
return false;
if (!shape)
return true;
if (nobj->isNative() && IsImplicitProperty(shape)) {
if (nobj->isNative() && IsImplicitDenseElement(shape)) {
if (!JSObject::sparsifyDenseElement(cx, obj, index))
return false;
shape = obj->nativeLookup(cx, INT_TO_JSID(index));
@ -4054,7 +4054,7 @@ baseops::DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, MutableHand
GCPoke(cx->runtime);
if (IsImplicitProperty(shape)) {
if (IsImplicitDenseElement(shape)) {
if (!CallJSPropertyOp(cx, obj->getClass()->delProperty, obj, id, rval))
return false;
if (rval.isFalse())
@ -4295,7 +4295,7 @@ js::CheckAccess(JSContext *cx, JSObject *obj_, HandleId id, JSAccessMode mode,
*attrsp = GetShapeAttributes(shape);
if (!writing) {
if (IsImplicitProperty(shape)) {
if (IsImplicitDenseElement(shape)) {
vp.set(pobj->getDenseElement(JSID_TO_INT(id)));
} else {
if (shape->hasSlot())

View File

@ -2551,7 +2551,7 @@ proxy_LookupGeneric(JSContext *cx, HandleObject obj, HandleId id,
return false;
if (found) {
MarkImplicitPropertyFound(propp);
MarkNonNativePropertyFound(propp);
objp.set(obj);
} else {
objp.set(NULL);

View File

@ -496,17 +496,25 @@ BaseShape::markChildren(JSTracer *trc)
/*
* Property lookup hooks on objects are required to return a non-NULL shape to
* signify that the property has been found. For cases where the property is
* not actually represented by a Shape (dense elements, properties of
* non-native objects), use a dummy value.
* not actually represented by a Shape, use a dummy value. This includes all
* properties of non-native objects, and dense elements for native objects.
* Use separate APIs for these two cases.
*/
static inline void
MarkImplicitPropertyFound(MutableHandleShape propp)
MarkNonNativePropertyFound(MutableHandleShape propp)
{
propp.set(reinterpret_cast<Shape*>(1));
}
static inline void
MarkDenseElementFound(MutableHandleShape propp)
{
propp.set(reinterpret_cast<Shape*>(1));
}
static inline bool
IsImplicitProperty(HandleShape prop)
IsImplicitDenseElement(HandleShape prop)
{
return prop.get() == reinterpret_cast<Shape*>(1);
}
@ -514,7 +522,7 @@ IsImplicitProperty(HandleShape prop)
static inline uint8_t
GetShapeAttributes(HandleShape shape)
{
return IsImplicitProperty(shape) ? JSPROP_ENUMERATE : shape->attributes();
return IsImplicitDenseElement(shape) ? JSPROP_ENUMERATE : shape->attributes();
}
} /* namespace js */

View File

@ -1015,7 +1015,7 @@ TypedArray::obj_lookupGeneric(JSContext *cx, HandleObject tarray, HandleId id,
JS_ASSERT(tarray->isTypedArray());
if (isArrayIndex(tarray, id)) {
MarkImplicitPropertyFound(propp);
MarkNonNativePropertyFound(propp);
objp.set(tarray);
return true;
}
@ -1045,7 +1045,7 @@ TypedArray::obj_lookupElement(JSContext *cx, HandleObject tarray, uint32_t index
JS_ASSERT(tarray->isTypedArray());
if (index < length(tarray)) {
MarkImplicitPropertyFound(propp);
MarkNonNativePropertyFound(propp);
objp.set(tarray);
return true;
}