Bug 728079 - "Assertion failure: pn2->pn_u.binary.iflags & 0x1" with JS 1.7, for-of loop, and destructuring. r=Waldo.

--HG--
extra : rebase_source : c395a34587756bcc5e418e2ed04ec9d055ab230d
This commit is contained in:
Jason Orendorff 2012-09-13 07:56:52 -05:00
parent 601e6d2e11
commit f5d02cae64
5 changed files with 55 additions and 5 deletions

View File

@ -3093,6 +3093,7 @@ Parser::forStatement()
|| (versionNumber() == JSVERSION_1_7 &&
pn->isOp(JSOP_ITER) &&
!(pn->pn_iflags & JSITER_FOREACH) &&
!forOf &&
(pn1->pn_head->isKind(PNK_OBJECT) ||
(pn1->pn_head->isKind(PNK_ARRAY) &&
pn1->pn_head->pn_count != 2) ||
@ -3106,7 +3107,8 @@ Parser::forStatement()
#if JS_HAS_DESTRUCTURING
((versionNumber() == JSVERSION_1_7 &&
pn->isOp(JSOP_ITER) &&
!(pn->pn_iflags & JSITER_FOREACH))
!(pn->pn_iflags & JSITER_FOREACH) &&
!forOf)
? (!pn1->isKind(PNK_ARRAY) || pn1->pn_count != 2)
: (!pn1->isKind(PNK_ARRAY) && !pn1->isKind(PNK_OBJECT))) &&
#endif
@ -3239,7 +3241,7 @@ Parser::forStatement()
* in JS1.7.
*/
JS_ASSERT(pn->isOp(JSOP_ITER));
if (!(pn->pn_iflags & JSITER_FOREACH))
if (!(pn->pn_iflags & JSITER_FOREACH) && !forOf)
pn->pn_iflags |= JSITER_FOREACH | JSITER_KEYVALUE;
}
break;
@ -5240,7 +5242,10 @@ Parser::comprehensionTail(ParseNode *kid, unsigned blockid, bool isGenexp,
if (!CheckDestructuring(context, &data, pn3, this))
return NULL;
if (versionNumber() == JSVERSION_1_7) {
if (versionNumber() == JSVERSION_1_7 &&
!(pn2->pn_iflags & JSITER_FOREACH) &&
!forOf)
{
/* Destructuring requires [key, value] enumeration in JS1.7. */
if (!pn3->isKind(PNK_ARRAY) || pn3->pn_count != 2) {
reportError(NULL, JSMSG_BAD_FOR_LEFTSIDE);
@ -5249,8 +5254,7 @@ Parser::comprehensionTail(ParseNode *kid, unsigned blockid, bool isGenexp,
JS_ASSERT(pn2->isOp(JSOP_ITER));
JS_ASSERT(pn2->pn_iflags & JSITER_ENUMERATE);
if (!(pn2->pn_iflags & JSITER_FOREACH))
pn2->pn_iflags |= JSITER_FOREACH | JSITER_KEYVALUE;
pn2->pn_iflags |= JSITER_FOREACH | JSITER_KEYVALUE;
}
break;
#endif

View File

@ -0,0 +1,23 @@
// for-of does not trigger the JS 1.7 for-in destructuring special case.
version(170);
var data = [[1, 2, 3], [4, 5, 6, 7]];
function test(vars, expr, result) {
var s = '';
eval("for (" + vars + " of data) s += (" + expr + ") + ';';");
assertEq(s, result);
}
for (var prefix of ["var ", "let ", ""]) {
test(prefix + "[a, b, c]",
"a + ',' + b + ',' + c",
"1,2,3;4,5,6;");
}
test("var [a]", "a", "1;4;");
test("var {length: len}", "len", "3;4;");
test("var {length}", "length", "3;4;");
test("{}", "0", "0;0;");

View File

@ -0,0 +1,15 @@
// for-of in comprehensions does not trigger the JS 1.7 for-in destructuring special case.
version(170);
load(libdir + "asserts.js");
var data = [[1, 2, 3], [4]];
var arr = eval("[a for ([a] of data)]");
assertEq(arr.length, 2);
assertEq(arr[0], 1);
assertEq(arr[1], 4);
arr = eval("[length for ({length} of data)]");
assertEq(arr.length, 2);
assertEq(arr[0], 3);
assertEq(arr[1], 1);

View File

@ -0,0 +1,4 @@
// Cleaned-up version of bug 728079 comment 0.
version(170);
eval("(function f() { return [[b, a] for ([a, b] of c.items())]; })");

View File

@ -0,0 +1,4 @@
// Test case from bug 785989 comment 3.
version(170);
Reflect.parse("for (let [a, b] of c) ;");