Bug 1097267 - Change to the simpler enumerate hook in the js engine. r=jorendorff

This commit is contained in:
Tom Schuster
2014-12-11 19:31:10 +01:00
parent 1d20d06638
commit e407db072b
9 changed files with 82 additions and 199 deletions

View File

@@ -281,64 +281,57 @@ Snapshot(JSContext *cx, HandleObject pobj_, unsigned flags, AutoIdVector *props)
RootedObject pobj(cx, pobj_);
do {
const Class *clasp = pobj->getClass();
if (pobj->isNative() &&
!pobj->getOps()->enumerate &&
!(clasp->flags & JSCLASS_NEW_ENUMERATE))
{
if (JSEnumerateOp enumerate = clasp->enumerate) {
if (JSNewEnumerateOp enumerate = pobj->getOps()->enumerate) {
// This hook has the full control over what gets enumerated.
AutoIdVector properties(cx);
if (!enumerate(cx, pobj, properties))
return false;
for (size_t n = 0; n < properties.length(); n++) {
if (!Enumerate(cx, pobj, properties[n], true, flags, ht, props))
return false;
}
if (pobj->isNative()) {
if (!EnumerateNativeProperties(cx, pobj.as<NativeObject>(), flags, ht, props))
return false;
}
} else if (pobj->isNative()) {
// Give the object a chance to resolve all lazy properties
if (JSEnumerateOp enumerate = pobj->getClass()->enumerate) {
if (!enumerate(cx, pobj.as<NativeObject>()))
return false;
}
if (!EnumerateNativeProperties(cx, pobj.as<NativeObject>(), flags, ht, props))
return false;
} else {
if (pobj->is<ProxyObject>()) {
AutoIdVector proxyProps(cx);
if (flags & JSITER_OWNONLY) {
if (flags & JSITER_HIDDEN) {
// This gets all property keys, both strings and
// symbols. The call to Enumerate in the loop below
// will filter out unwanted keys, per the flags.
if (!Proxy::ownPropertyKeys(cx, pobj, proxyProps))
return false;
} else {
if (!Proxy::getOwnEnumerablePropertyKeys(cx, pobj, proxyProps))
return false;
}
} else {
if (!Proxy::getEnumerablePropertyKeys(cx, pobj, proxyProps))
} else if (pobj->is<ProxyObject>()) {
AutoIdVector proxyProps(cx);
if (flags & JSITER_OWNONLY) {
if (flags & JSITER_HIDDEN) {
// This gets all property keys, both strings and
// symbols. The call to Enumerate in the loop below
// will filter out unwanted keys, per the flags.
if (!Proxy::ownPropertyKeys(cx, pobj, proxyProps))
return false;
} else {
if (!Proxy::getOwnEnumerablePropertyKeys(cx, pobj, proxyProps))
return false;
}
for (size_t n = 0, len = proxyProps.length(); n < len; n++) {
if (!Enumerate(cx, pobj, proxyProps[n], true, flags, ht, props))
return false;
}
// Proxy objects enumerate the prototype on their own, so we're
// done here.
break;
}
RootedValue state(cx);
RootedId id(cx);
JSIterateOp op = (flags & JSITER_HIDDEN) ? JSENUMERATE_INIT_ALL : JSENUMERATE_INIT;
if (!JSObject::enumerate(cx, pobj, op, &state, &id))
return false;
if (state.isMagic(JS_NATIVE_ENUMERATE)) {
if (!EnumerateNativeProperties(cx, pobj.as<NativeObject>(), flags, ht, props))
return false;
} else {
while (true) {
RootedId id(cx);
if (!JSObject::enumerate(cx, pobj, JSENUMERATE_NEXT, &state, &id))
return false;
if (state.isNull())
break;
if (!Enumerate(cx, pobj, id, true, flags, ht, props))
return false;
}
if (!Proxy::getEnumerablePropertyKeys(cx, pobj, proxyProps))
return false;
}
for (size_t n = 0, len = proxyProps.length(); n < len; n++) {
if (!Enumerate(cx, pobj, proxyProps[n], true, flags, ht, props))
return false;
}
// Proxy objects enumerate the prototype on their own, so we're
// done here.
break;
} else {
MOZ_CRASH("non-native objects must have an enumerate op");
}
if (flags & JSITER_OWNONLY)