bug 566141 r=brendan

This commit is contained in:
Igor Bukanov 2010-05-25 12:54:55 +02:00
parent f17d997577
commit e496ace8f3
2 changed files with 35 additions and 27 deletions

View File

@ -2248,6 +2248,11 @@ class AutoValueRooter : private AutoGCRooter
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
void set(jsval v) {
JS_ASSERT(tag == JSVAL);
val = v;
}
void setObject(JSObject *obj) {
JS_ASSERT(tag == JSVAL);
val = OBJECT_TO_JSVAL(obj);

View File

@ -248,8 +248,6 @@ MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap)
jsid id;
JSObject *obj2;
JSProperty *prop;
uintN attrs;
jsval val;
JS_CHECK_RECURSION(cx, return NULL);
@ -279,32 +277,37 @@ MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap)
break;
if (!prop)
continue;
ok = obj2->getAttributes(cx, id, prop, &attrs);
if (ok) {
if (obj2->isNative() &&
(attrs & (JSPROP_GETTER | JSPROP_SETTER))) {
JSScopeProperty *sprop = (JSScopeProperty *) prop;
val = JSVAL_VOID;
if (attrs & JSPROP_GETTER)
val = sprop->getterValue();
if (attrs & JSPROP_SETTER) {
if (val != JSVAL_VOID) {
/* Mark the getter, then set val to setter. */
ok = (MarkSharpObjects(cx, JSVAL_TO_OBJECT(val),
NULL)
!= NULL);
}
val = sprop->setterValue();
}
} else {
ok = obj->getProperty(cx, id, &val);
}
bool hasGetter, hasSetter;
AutoValueRooter v(cx, JSVAL_VOID);
AutoValueRooter setter(cx, JSVAL_VOID);
if (obj->isNative()) {
JSScopeProperty *sprop = (JSScopeProperty *) prop;
hasGetter = sprop->hasGetterValue();
hasSetter = sprop->hasSetterValue();
if (hasGetter)
v.set(sprop->getterValue());
if (hasSetter)
setter.set(sprop->setterValue());
JS_UNLOCK_OBJ(cx, obj2);
} else {
obj->dropProperty(cx, prop);
hasGetter = hasSetter = false;
}
obj2->dropProperty(cx, prop);
if (!ok)
break;
if (!JSVAL_IS_PRIMITIVE(val) &&
!MarkSharpObjects(cx, JSVAL_TO_OBJECT(val), NULL)) {
if (hasSetter) {
/* Mark the getter, then set val to setter. */
if (hasGetter && !JSVAL_IS_PRIMITIVE(v.value())) {
ok = !!MarkSharpObjects(cx, JSVAL_TO_OBJECT(v.value()), NULL);
if (!ok)
break;
}
v.set(setter.value());
} else if (!hasGetter) {
ok = obj->getProperty(cx, id, v.addr());
if (!ok)
break;
}
if (!JSVAL_IS_PRIMITIVE(v.value()) &&
!MarkSharpObjects(cx, JSVAL_TO_OBJECT(v.value()), NULL)) {
ok = JS_FALSE;
break;
}