From 992cf1f5c31fbce655cd9bc5d0d9a63d7e2035e5 Mon Sep 17 00:00:00 2001 From: "brendan%mozilla.org" Date: Fri, 2 Jun 2006 06:30:05 +0000 Subject: [PATCH] Get value from original object when enumerating prototype objects via for-each-in (339169, r=mrbkap). git-svn-id: svn://10.0.0.236/branches/JS_1_7_ALPHA_BRANCH@198860 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js/src/jsinterp.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/mozilla/js/src/jsinterp.c b/mozilla/js/src/jsinterp.c index f8f9120c4bd..02e6c8ebef3 100644 --- a/mozilla/js/src/jsinterp.c +++ b/mozilla/js/src/jsinterp.c @@ -2679,6 +2679,8 @@ interrupt: (iterobj == obj) ? NULL : &fid, &rval); if (!ok) { + uintN protoFlags; + /* Nothing more to iterate in obj, or some other exception? */ if (!cx->throwing || !VALUE_IS_STOP_ITERATION(cx, cx->exception)) { @@ -2705,14 +2707,23 @@ interrupt: goto end_forinloop; } + /* + * Clear JSITER_FOREACH now that we are up the prototype chain + * from the original object. We can't expect to get the same + * value from a prototype as we would if we started the get at + * the original object, so we must do our own getting, further + * below when testing 'if (flags & JSITER_FOREACH)'. + */ + protoFlags = flags & ~JSITER_FOREACH; + if (flags & JSITER_COMPAT) { - ok = js_NewNativeIterator(cx, obj, flags, vp); + ok = js_NewNativeIterator(cx, obj, protoFlags, vp); if (!ok) goto out; iterobj = JSVAL_TO_OBJECT(*vp); } else { iterobj = js_ValueToIterator(cx, OBJECT_TO_JSVAL(obj), - flags); + protoFlags); if (!iterobj) { JS_ASSERT(!ok); goto out; @@ -2770,6 +2781,18 @@ interrupt: if (flags & JSITER_FOREACH) { /* Clear the local foreach flag set by our prefix bytecode. */ flags = 0; + + /* + * If enumerating up the prototype chain, we suppressed the + * JSITER_FOREACH flag when we created the iterator, because + * the iterator can't get the value for fid without starting + * from origobj. So we must OBJ_GET_PROPERTY here. + */ + if (origobj != obj) { + ok = OBJ_GET_PROPERTY(cx, origobj, fid, &rval); + if (!ok) + goto out; + } } else if (iterobj == obj) { /* Iterators return arbitrary values, not string ids. */ JS_ASSERT(fid == JSVAL_NULL);