[INFER] Inherit shadowed properties correctly after splicePrototype, bug 621126.

This commit is contained in:
Brian Hackett 2010-12-23 17:54:03 -05:00
parent 0f5a5837ad
commit 5b9156630b
6 changed files with 46 additions and 14 deletions

View File

@ -0,0 +1,5 @@
/* Inheritance of shadowed function properties from Object.prototype. */
delete Function.prototype.toString;
assertEq(Function.prototype.toString, Object.prototype.toString);

View File

@ -127,12 +127,32 @@ TypeIdStringImpl(jsid id)
}
void
TypeObject::splicePrototype(JSObject *proto)
TypeObject::splicePrototype(JSContext *cx, JSObject *proto)
{
JS_ASSERT(!this->proto);
this->proto = proto;
this->instanceNext = proto->getType()->instanceList;
proto->getType()->instanceList = this;
/*
* Note: we require (but do not assert) that any property in the prototype
* or its own prototypes must not share a name with a property already
* added to an instance of this object.
*/
#ifdef JS_TYPE_INFERENCE
if (propertyCount >= 2) {
unsigned capacity = HashSetCapacity(propertyCount);
for (unsigned i = 0; i < capacity; i++) {
Property *prop = propertySet[i];
if (prop)
getFromPrototypes(cx, prop);
}
} else if (propertyCount == 1) {
Property *prop = (Property *) propertySet;
getFromPrototypes(cx, prop);
}
#endif
}
} } /* namespace js::types */

View File

@ -1449,9 +1449,9 @@ js_InitFunctionAndObjectClasses(JSContext *cx, JSObject *obj)
return NULL;
/* Function.prototype and the global object delegate to Object.prototype. */
fun_proto->getType()->splicePrototype(obj_proto);
fun_proto->getType()->splicePrototype(cx, obj_proto);
if (!obj->getProto())
obj->getType()->splicePrototype(obj_proto);
obj->getType()->splicePrototype(cx, obj_proto);
return fun_proto;
}

View File

@ -1616,6 +1616,20 @@ TypeObject::storeToInstances(JSContext *cx, Property *base)
}
}
void
TypeObject::getFromPrototypes(JSContext *cx, Property *base)
{
JSObject *obj = proto;
while (obj) {
TypeObject *object = obj->getType();
Property *p =
HashSetLookup<jsid,Property,Property>(object->propertySet, object->propertyCount, base->id);
if (p)
p->ownTypes.addSubset(cx, *object->pool, &base->types);
obj = obj->getProto();
}
}
void
TypeObject::addProperty(JSContext *cx, jsid id, Property *&base)
{
@ -1641,15 +1655,7 @@ TypeObject::addProperty(JSContext *cx, jsid id, Property *&base)
storeToInstances(cx, base);
/* Pull in this property from all prototypes up the chain. */
JSObject *obj = proto;
while (obj) {
TypeObject *object = obj->getType();
Property *p =
HashSetLookup<jsid,Property,Property>(object->propertySet, object->propertyCount, id);
if (p)
p->ownTypes.addSubset(cx, *object->pool, &base->types);
obj = obj->getProto();
}
getFromPrototypes(cx, base);
}
void

View File

@ -494,7 +494,7 @@ struct TypeObject
inline const char * name();
/* Mark proto as the prototype of this object and all instances. */
void splicePrototype(JSObject *proto);
void splicePrototype(JSContext *cx, JSObject *proto);
/* Helpers */
@ -502,6 +502,7 @@ struct TypeObject
void addProperty(JSContext *cx, jsid id, Property *&prop);
void markUnknown(JSContext *cx);
void storeToInstances(JSContext *cx, Property *base);
void getFromPrototypes(JSContext *cx, Property *base);
void print(JSContext *cx);
void trace(JSTracer *trc);

View File

@ -3973,7 +3973,7 @@ js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
/* Bootstrap Function.prototype (see also JS_InitStandardClasses). */
if (ctor->getClass() == clasp)
ctor->getType()->splicePrototype(proto);
ctor->getType()->splicePrototype(cx, proto);
}
/* Add properties and methods to the prototype and the constructor. */