Commit d3aefe8c authored by neis's avatar neis Committed by Commit bot

[parser] Fix bug in for-of desugaring.

When reading the value property of an iterator result fails, we must not close the iterator.
This was not discovered earlier because the tests had a subtle bug.

This CL fixes both the desugaring and the tests.

BUG=

Review-Url: https://codereview.chromium.org/2119353002
Cr-Commit-Position: refs/heads/master@{#37571}
parent 1829eb66
This diff is collapsed.
...@@ -458,7 +458,8 @@ class ParserTraits { ...@@ -458,7 +458,8 @@ class ParserTraits {
void FinalizeIteratorUse(Variable* completion, Expression* condition, void FinalizeIteratorUse(Variable* completion, Expression* condition,
Variable* iter, Block* iterator_use, Block* result); Variable* iter, Block* iterator_use, Block* result);
Statement* FinalizeForOfStatement(ForOfStatement* loop, int pos); Statement* FinalizeForOfStatement(ForOfStatement* loop, Variable* completion,
int pos);
// Reporting errors. // Reporting errors.
void ReportMessageAt(Scanner::Location source_location, void ReportMessageAt(Scanner::Location source_location,
...@@ -961,12 +962,13 @@ class Parser : public ParserBase<ParserTraits> { ...@@ -961,12 +962,13 @@ class Parser : public ParserBase<ParserTraits> {
// Initialize the components of a for-in / for-of statement. // Initialize the components of a for-in / for-of statement.
void InitializeForEachStatement(ForEachStatement* stmt, Expression* each, Statement* InitializeForEachStatement(ForEachStatement* stmt,
Expression* subject, Statement* body, Expression* each, Expression* subject,
int each_keyword_pos); Statement* body, int each_keyword_pos);
void InitializeForOfStatement(ForOfStatement* stmt, Expression* each, Statement* InitializeForOfStatement(ForOfStatement* stmt, Expression* each,
Expression* iterable, Statement* body, Expression* iterable, Statement* body,
int next_result_pos = kNoSourcePosition); bool finalize,
int next_result_pos = kNoSourcePosition);
Statement* DesugarLexicalBindingsInForStatement( Statement* DesugarLexicalBindingsInForStatement(
Scope* inner_scope, VariableMode mode, Scope* inner_scope, VariableMode mode,
ZoneList<const AstRawString*>* names, ForStatement* loop, Statement* init, ZoneList<const AstRawString*>* names, ForStatement* loop, Statement* init,
......
...@@ -13,10 +13,9 @@ snippet: " ...@@ -13,10 +13,9 @@ snippet: "
" "
frame size: 16 frame size: 16
parameter count: 1 parameter count: 1
bytecode array length: 284 bytecode array length: 283
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
B(LdrUndefined), R(4),
B(LdaZero), B(LdaZero),
B(Star), R(3), B(Star), R(3),
B(Mov), R(context), R(11), B(Mov), R(context), R(11),
...@@ -35,16 +34,16 @@ bytecodes: [ ...@@ -35,16 +34,16 @@ bytecodes: [
B(JumpIfFalse), U8(7), B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(2), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(2), U8(1),
B(LdaNamedProperty), R(2), U8(3), U8(9), B(LdaNamedProperty), R(2), U8(3), U8(9),
B(JumpIfToBooleanTrue), U8(22), B(JumpIfToBooleanTrue), U8(23),
B(LdrNamedProperty), R(2), U8(4), U8(11), R(4),
B(LdaSmi), U8(2), B(LdaSmi), U8(2),
B(Star), R(3), B(Star), R(3),
B(LdrNamedProperty), R(2), U8(4), U8(11), R(0), B(Mov), R(4), R(0),
B(Ldar), R(0),
/* 34 E> */ B(StackCheck), /* 34 E> */ B(StackCheck),
B(Mov), R(0), R(7), B(Mov), R(0), R(7),
B(LdaZero), B(LdaZero),
B(Star), R(3), B(Star), R(3),
B(Jump), U8(-48), B(Jump), U8(-49),
B(Jump), U8(41), B(Jump), U8(41),
B(Star), R(14), B(Star), R(14),
B(LdaConstant), U8(5), B(LdaConstant), U8(5),
...@@ -143,9 +142,9 @@ constant pool: [ ...@@ -143,9 +142,9 @@ constant pool: [
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
] ]
handlers: [ handlers: [
[9, 122, 128], [7, 121, 127],
[12, 81, 83], [10, 80, 82],
[201, 211, 213], [200, 210, 212],
] ]
--- ---
...@@ -155,12 +154,11 @@ snippet: " ...@@ -155,12 +154,11 @@ snippet: "
" "
frame size: 17 frame size: 17
parameter count: 1 parameter count: 1
bytecode array length: 297 bytecode array length: 296
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0), /* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(7), B(Star), R(7),
B(LdrUndefined), R(4),
B(LdaZero), B(LdaZero),
B(Star), R(3), B(Star), R(3),
B(Mov), R(context), R(12), B(Mov), R(context), R(12),
...@@ -177,18 +175,18 @@ bytecodes: [ ...@@ -177,18 +175,18 @@ bytecodes: [
B(JumpIfFalse), U8(7), B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(2), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(2), U8(1),
B(LdaNamedProperty), R(2), U8(3), U8(9), B(LdaNamedProperty), R(2), U8(3), U8(9),
B(JumpIfToBooleanTrue), U8(27), B(JumpIfToBooleanTrue), U8(28),
B(LdrNamedProperty), R(2), U8(4), U8(11), R(4),
B(LdaSmi), U8(2), B(LdaSmi), U8(2),
B(Star), R(3), B(Star), R(3),
B(LdrNamedProperty), R(2), U8(4), U8(11), R(0), B(Mov), R(4), R(0),
B(Ldar), R(0),
/* 54 E> */ B(StackCheck), /* 54 E> */ B(StackCheck),
B(Mov), R(0), R(8), B(Mov), R(0), R(8),
/* 73 S> */ B(LdaZero), /* 73 S> */ B(LdaZero),
B(Star), R(10), B(Star), R(10),
B(Mov), R(0), R(11), B(Mov), R(0), R(11),
B(Jump), U8(57), B(Jump), U8(57),
B(Jump), U8(-53), B(Jump), U8(-54),
B(Jump), U8(41), B(Jump), U8(41),
B(Star), R(15), B(Star), R(15),
B(LdaConstant), U8(5), B(LdaConstant), U8(5),
...@@ -292,9 +290,9 @@ constant pool: [ ...@@ -292,9 +290,9 @@ constant pool: [
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
] ]
handlers: [ handlers: [
[13, 125, 131], [11, 124, 130],
[16, 84, 86], [14, 83, 85],
[205, 215, 217], [204, 214, 216],
] ]
--- ---
...@@ -306,10 +304,9 @@ snippet: " ...@@ -306,10 +304,9 @@ snippet: "
" "
frame size: 16 frame size: 16
parameter count: 1 parameter count: 1
bytecode array length: 300 bytecode array length: 299
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
B(LdrUndefined), R(4),
B(LdaZero), B(LdaZero),
B(Star), R(3), B(Star), R(3),
B(Mov), R(context), R(11), B(Mov), R(context), R(11),
...@@ -328,11 +325,11 @@ bytecodes: [ ...@@ -328,11 +325,11 @@ bytecodes: [
B(JumpIfFalse), U8(7), B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(2), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(2), U8(1),
B(LdaNamedProperty), R(2), U8(3), U8(9), B(LdaNamedProperty), R(2), U8(3), U8(9),
B(JumpIfToBooleanTrue), U8(38), B(JumpIfToBooleanTrue), U8(39),
B(LdrNamedProperty), R(2), U8(4), U8(11), R(4),
B(LdaSmi), U8(2), B(LdaSmi), U8(2),
B(Star), R(3), B(Star), R(3),
B(LdrNamedProperty), R(2), U8(4), U8(11), R(0), B(Mov), R(4), R(0),
B(Ldar), R(0),
/* 34 E> */ B(StackCheck), /* 34 E> */ B(StackCheck),
B(Mov), R(0), R(7), B(Mov), R(0), R(7),
/* 66 S> */ B(LdaSmi), U8(10), /* 66 S> */ B(LdaSmi), U8(10),
...@@ -345,7 +342,7 @@ bytecodes: [ ...@@ -345,7 +342,7 @@ bytecodes: [
/* 104 S> */ B(Jump), U8(7), /* 104 S> */ B(Jump), U8(7),
B(LdaZero), B(LdaZero),
B(Star), R(3), B(Star), R(3),
B(Jump), U8(-64), B(Jump), U8(-65),
B(Jump), U8(41), B(Jump), U8(41),
B(Star), R(14), B(Star), R(14),
B(LdaConstant), U8(5), B(LdaConstant), U8(5),
...@@ -444,9 +441,9 @@ constant pool: [ ...@@ -444,9 +441,9 @@ constant pool: [
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
] ]
handlers: [ handlers: [
[9, 138, 144], [7, 137, 143],
[12, 97, 99], [10, 96, 98],
[217, 227, 229], [216, 226, 228],
] ]
--- ---
...@@ -456,13 +453,12 @@ snippet: " ...@@ -456,13 +453,12 @@ snippet: "
" "
frame size: 15 frame size: 15
parameter count: 1 parameter count: 1
bytecode array length: 308 bytecode array length: 309
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1), /* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1),
B(Star), R(8), B(Star), R(8),
B(Star), R(6), B(Star), R(6),
B(LdrUndefined), R(3),
B(LdaZero), B(LdaZero),
B(Star), R(2), B(Star), R(2),
B(Mov), R(context), R(10), B(Mov), R(context), R(10),
...@@ -481,10 +477,11 @@ bytecodes: [ ...@@ -481,10 +477,11 @@ bytecodes: [
B(JumpIfFalse), U8(7), B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(1), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(1), U8(1),
B(LdaNamedProperty), R(1), U8(4), U8(9), B(LdaNamedProperty), R(1), U8(4), U8(9),
B(JumpIfToBooleanTrue), U8(28), B(JumpIfToBooleanTrue), U8(31),
/* 67 E> */ B(LdrNamedProperty), R(1), U8(5), U8(11), R(3),
B(LdaSmi), U8(2), B(LdaSmi), U8(2),
B(Star), R(2), B(Star), R(2),
/* 67 E> */ B(LdaNamedProperty), R(1), U8(5), U8(11), B(Ldar), R(3),
B(StaNamedPropertySloppy), R(6), U8(6), U8(13), B(StaNamedPropertySloppy), R(6), U8(6), U8(13),
/* 62 E> */ B(StackCheck), /* 62 E> */ B(StackCheck),
/* 88 S> */ B(Nop), /* 88 S> */ B(Nop),
...@@ -492,7 +489,7 @@ bytecodes: [ ...@@ -492,7 +489,7 @@ bytecodes: [
B(LdaZero), B(LdaZero),
B(Star), R(8), B(Star), R(8),
B(Jump), U8(57), B(Jump), U8(57),
B(Jump), U8(-54), B(Jump), U8(-57),
B(Jump), U8(41), B(Jump), U8(41),
B(Star), R(13), B(Star), R(13),
B(LdaConstant), U8(7), B(LdaConstant), U8(7),
...@@ -598,8 +595,8 @@ constant pool: [ ...@@ -598,8 +595,8 @@ constant pool: [
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE, InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
] ]
handlers: [ handlers: [
[17, 136, 142], [15, 137, 143],
[20, 95, 97], [18, 96, 98],
[216, 226, 228], [217, 227, 229],
] ]
...@@ -966,8 +966,9 @@ function* g() { yield 42; return 88 }; ...@@ -966,8 +966,9 @@ function* g() { yield 42; return 88 };
// Next method throws. // Next method throws.
{ {
let closed = false;
g.prototype.next = () => { throw 666; }; g.prototype.next = () => { throw 666; };
g.prototype.return = () => { assertUnreachable() }; g.prototype.return = () => { closed = true; };
assertThrowsEquals(() => { assertThrowsEquals(() => {
...@@ -1025,13 +1026,17 @@ function* g() { yield 42; return 88 }; ...@@ -1025,13 +1026,17 @@ function* g() { yield 42; return 88 };
assertThrowsEquals(() => { assertThrowsEquals(() => {
(([...x]) => x)(g()); (([...x]) => x)(g());
}, 666); }, 666);
assertFalse(closed);
} }
// Value throws. // Value throws.
{ {
let closed = false;
g.prototype.next = () => ({get value() {throw 666}}); g.prototype.next = () => ({get value() {throw 666}});
g.prototype.return = () => { assertUnreachable() }; g.prototype.return = () => { closed = true; };
assertThrowsEquals(() => { assertThrowsEquals(() => {
...@@ -1089,13 +1094,17 @@ function* g() { yield 42; return 88 }; ...@@ -1089,13 +1094,17 @@ function* g() { yield 42; return 88 };
assertThrowsEquals(() => { assertThrowsEquals(() => {
(([...x]) => x)(g()); (([...x]) => x)(g());
}, 666); }, 666);
assertFalse(closed);
} }
// Done throws. // Done throws.
{ {
let closed = false;
g.prototype.next = () => ({get done() {throw 666}}); g.prototype.next = () => ({get done() {throw 666}});
g.prototype.return = () => { assertUnreachable() }; g.prototype.return = () => { closed = true; };
assertThrowsEquals(() => { assertThrowsEquals(() => {
...@@ -1153,6 +1162,9 @@ function* g() { yield 42; return 88 }; ...@@ -1153,6 +1162,9 @@ function* g() { yield 42; return 88 };
assertThrowsEquals(() => { assertThrowsEquals(() => {
(([...x]) => x)(g()); (([...x]) => x)(g());
}, 666); }, 666);
assertFalse(closed);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment