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
......@@ -3186,12 +3186,16 @@ Expression* Parser::BuildIteratorNextResult(Expression* iterator,
throw_call, pos);
}
void Parser::InitializeForEachStatement(ForEachStatement* stmt,
Expression* each, Expression* subject,
Statement* body, int each_keyword_pos) {
Statement* Parser::InitializeForEachStatement(ForEachStatement* stmt,
Expression* each,
Expression* subject,
Statement* body,
int each_keyword_pos) {
ForOfStatement* for_of = stmt->AsForOfStatement();
if (for_of != NULL) {
InitializeForOfStatement(for_of, each, subject, body, each_keyword_pos);
const bool finalize = true;
return InitializeForOfStatement(for_of, each, subject, body, finalize,
each_keyword_pos);
} else {
if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
Variable* temp =
......@@ -3211,38 +3215,49 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt,
}
stmt->AsForInStatement()->Initialize(each, subject, body);
}
return stmt;
}
void Parser::InitializeForOfStatement(ForOfStatement* for_of, Expression* each,
Expression* iterable, Statement* body,
int next_result_pos) {
Statement* Parser::InitializeForOfStatement(ForOfStatement* for_of,
Expression* each,
Expression* iterable,
Statement* body, bool finalize,
int next_result_pos) {
// Create the auxiliary expressions needed for iterating over the iterable,
// and initialize the given ForOfStatement with them.
// If finalize is true, also instrument the loop with code that performs the
// proper ES6 iterator finalization. In that case, the result is not
// immediately a ForOfStatement.
const int nopos = kNoSourcePosition;
auto avfactory = ast_value_factory();
Variable* iterator =
scope_->NewTemporary(ast_value_factory()->dot_iterator_string());
Variable* result =
scope_->NewTemporary(ast_value_factory()->dot_result_string());
Expression* assign_iterator;
Expression* next_result;
Expression* result_done;
Expression* assign_each;
int get_iterator_pos = iterable->position();
Variable* completion = scope_->NewTemporary(avfactory->empty_string());
// iterator = iterable[Symbol.iterator]()
assign_iterator = factory()->NewAssignment(
Token::ASSIGN, factory()->NewVariableProxy(iterator),
GetIterator(iterable, factory(), get_iterator_pos), iterable->position());
Expression* assign_iterator;
{
assign_iterator = factory()->NewAssignment(
Token::ASSIGN, factory()->NewVariableProxy(iterator),
GetIterator(iterable, factory(), iterable->position()),
iterable->position());
}
// !%_IsJSReceiver(result = iterator.next()) &&
// %ThrowIteratorResultNotAnObject(result)
Expression* next_result;
{
// result = iterator.next()
Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
next_result =
BuildIteratorNextResult(iterator_proxy, result, next_result_pos);
}
// result.done
Expression* result_done;
{
Expression* done_literal = factory()->NewStringLiteral(
ast_value_factory()->done_string(), kNoSourcePosition);
......@@ -3251,23 +3266,84 @@ void Parser::InitializeForOfStatement(ForOfStatement* for_of, Expression* each,
factory()->NewProperty(result_proxy, done_literal, kNoSourcePosition);
}
// each = result.value
// result.value
Expression* result_value;
{
Expression* value_literal = factory()->NewStringLiteral(
ast_value_factory()->value_string(), kNoSourcePosition);
Expression* value_literal =
factory()->NewStringLiteral(avfactory->value_string(), nopos);
Expression* result_proxy = factory()->NewVariableProxy(result);
Expression* result_value =
factory()->NewProperty(result_proxy, value_literal, kNoSourcePosition);
assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
kNoSourcePosition);
result_value = factory()->NewProperty(result_proxy, value_literal, nopos);
}
// {{completion = kAbruptCompletion;}}
Statement* set_completion_abrupt;
if (finalize) {
Expression* proxy = factory()->NewVariableProxy(completion);
Expression* assignment = factory()->NewAssignment(
Token::ASSIGN, proxy,
factory()->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
Block* block = factory()->NewBlock(nullptr, 1, true, nopos);
block->statements()->Add(
factory()->NewExpressionStatement(assignment, nopos), zone());
set_completion_abrupt = block;
}
// do { let tmp = #result_value; #set_completion_abrupt; tmp }
// Expression* result_value (gets overwritten)
if (finalize) {
Variable* var_tmp = scope_->NewTemporary(avfactory->empty_string());
Expression* tmp = factory()->NewVariableProxy(var_tmp);
Expression* assignment =
factory()->NewAssignment(Token::ASSIGN, tmp, result_value, nopos);
Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
block->statements()->Add(
factory()->NewExpressionStatement(assignment, nopos), zone());
block->statements()->Add(set_completion_abrupt, zone());
result_value = factory()->NewDoExpression(block, var_tmp, nopos);
}
// each = #result_value;
Expression* assign_each;
{
assign_each =
factory()->NewAssignment(Token::ASSIGN, each, result_value, nopos);
if (each->IsArrayLiteral() || each->IsObjectLiteral()) {
assign_each = PatternRewriter::RewriteDestructuringAssignment(
this, assign_each->AsAssignment(), scope_);
}
}
// {{completion = kNormalCompletion;}}
Statement* set_completion_normal;
if (finalize) {
Expression* proxy = factory()->NewVariableProxy(completion);
Expression* assignment = factory()->NewAssignment(
Token::ASSIGN, proxy,
factory()->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
Block* block = factory()->NewBlock(nullptr, 1, true, nopos);
block->statements()->Add(
factory()->NewExpressionStatement(assignment, nopos), zone());
set_completion_normal = block;
}
// { #loop-body; #set_completion_normal }
// Statement* body (gets overwritten)
if (finalize) {
Block* block = factory()->NewBlock(nullptr, 2, false, nopos);
block->statements()->Add(body, zone());
block->statements()->Add(set_completion_normal, zone());
body = block;
}
for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
assign_each);
return finalize
? ParserTraits::FinalizeForOfStatement(for_of, completion, nopos)
: for_of;
}
Statement* Parser::DesugarLexicalBindingsInForStatement(
......@@ -3652,6 +3728,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
Block* body_block =
factory()->NewBlock(NULL, 3, false, kNoSourcePosition);
Statement* final_loop;
{
ReturnExprScope no_tail_calls(function_state_,
ReturnExprContext::kInsideForInOfBody);
......@@ -3678,8 +3755,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
body_block->statements()->Add(body, zone());
VariableProxy* temp_proxy =
factory()->NewVariableProxy(temp, each_beg_pos, each_end_pos);
InitializeForEachStatement(loop, temp_proxy, enumerable, body_block,
each_keyword_position);
final_loop = InitializeForEachStatement(
loop, temp_proxy, enumerable, body_block, each_keyword_position);
}
body_scope->set_end_position(scanner()->location().end_pos);
body_scope = body_scope->FinalizeBlockScope();
......@@ -3706,12 +3783,6 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
}
}
Statement* final_loop =
loop->IsForOfStatement()
? FinalizeForOfStatement(loop->AsForOfStatement(),
kNoSourcePosition)
: loop;
for_scope->set_end_position(scanner()->location().end_pos);
for_scope = for_scope->FinalizeBlockScope();
// Parsed for-in loop w/ variable declarations.
......@@ -3775,14 +3846,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
// For legacy compat reasons, give for loops similar treatment to
// if statements in allowing a function declaration for a body
Statement* body = ParseScopedStatement(NULL, true, CHECK_OK);
InitializeForEachStatement(loop, expression, enumerable, body,
each_keyword_position);
Statement* final_loop =
loop->IsForOfStatement()
? FinalizeForOfStatement(loop->AsForOfStatement(),
kNoSourcePosition)
: loop;
Statement* final_loop = InitializeForEachStatement(
loop, expression, enumerable, body, each_keyword_position);
for_scope->set_end_position(scanner()->location().end_pos);
for_scope = for_scope->FinalizeBlockScope();
......@@ -5876,9 +5941,10 @@ Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
// for (each of spread) %AppendElement($R, each)
ForEachStatement* loop = factory()->NewForEachStatement(
ForEachStatement::ITERATE, nullptr, kNoSourcePosition);
const bool finalize = false;
InitializeForOfStatement(loop->AsForOfStatement(),
factory()->NewVariableProxy(each), subject,
append_body);
append_body, finalize);
do_block->statements()->Add(loop, zone());
}
}
......@@ -6870,13 +6936,13 @@ void ParserTraits::BuildIteratorCloseForCompletion(
statements->Add(maybe_call_return, zone);
}
Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) {
Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop,
Variable* var_completion,
int pos) {
//
// This function replaces the loop with the following wrapping:
//
// let each;
// let completion = kNormalCompletion;
// completion = kNormalCompletion;
// try {
// try {
// #loop;
......@@ -6890,41 +6956,14 @@ Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) {
// }
// }
//
// where the loop's body is wrapped as follows:
//
// {
// #loop-body
// {{completion = kNormalCompletion;}}
// }
//
// and the loop's assign_each is wrapped as follows
//
// do {
// {{completion = kAbruptCompletion;}}
// #assign-each
// }
// Note that the loop's body and its assign_each already contain appropriate
// assignments to completion (see InitializeForOfStatement).
//
const int nopos = kNoSourcePosition;
auto factory = parser_->factory();
auto avfactory = parser_->ast_value_factory();
auto scope = parser_->scope_;
auto zone = parser_->zone();
Variable* var_completion = scope->NewTemporary(avfactory->empty_string());
// let each;
Variable* var_each = scope->NewTemporary(avfactory->empty_string());
Statement* initialize_each;
{
Expression* proxy = factory->NewVariableProxy(var_each);
Expression* assignment = factory->NewAssignment(
Token::ASSIGN, proxy,
factory->NewUndefinedLiteral(nopos), nopos);
initialize_each =
factory->NewExpressionStatement(assignment, nopos);
}
// !(completion === kNormalCompletion || IS_UNDEFINED(#iterator))
Expression* closing_condition;
{
......@@ -6939,66 +6978,13 @@ Statement* ParserTraits::FinalizeForOfStatement(ForOfStatement* loop, int pos) {
nopos);
}
// {{completion = kNormalCompletion;}}
Statement* set_completion_normal;
Block* final_loop = factory->NewBlock(nullptr, 2, false, nopos);
{
Expression* proxy = factory->NewVariableProxy(var_completion);
Expression* assignment = factory->NewAssignment(
Token::ASSIGN, proxy,
factory->NewSmiLiteral(Parser::kNormalCompletion, nopos), nopos);
Block* block = factory->NewBlock(nullptr, 1, true, nopos);
block->statements()->Add(
factory->NewExpressionStatement(assignment, nopos), zone);
set_completion_normal = block;
}
// {{completion = kAbruptCompletion;}}
Statement* set_completion_abrupt;
{
Expression* proxy = factory->NewVariableProxy(var_completion);
Expression* assignment = factory->NewAssignment(
Token::ASSIGN, proxy,
factory->NewSmiLiteral(Parser::kAbruptCompletion, nopos), nopos);
Block* block = factory->NewBlock(nullptr, 1, true, nopos);
block->statements()->Add(factory->NewExpressionStatement(assignment, nopos),
zone);
set_completion_abrupt = block;
}
// { #loop-body; #set_completion_normal }
Block* new_body = factory->NewBlock(nullptr, 2, false, nopos);
{
new_body->statements()->Add(loop->body(), zone);
new_body->statements()->Add(set_completion_normal, zone);
}
// { #set_completion_abrupt; #assign-each }
Block* new_assign_each = factory->NewBlock(nullptr, 2, false, nopos);
{
new_assign_each->statements()->Add(set_completion_abrupt, zone);
new_assign_each->statements()->Add(
factory->NewExpressionStatement(loop->assign_each(), nopos), zone);
}
// Now put things together.
loop->set_body(new_body);
loop->set_assign_each(
factory->NewDoExpression(new_assign_each, var_each, nopos));
Statement* final_loop;
{
Block* target = factory->NewBlock(nullptr, 3, false, nopos);
target->statements()->Add(initialize_each, zone);
Block* try_block = factory->NewBlock(nullptr, 1, false, nopos);
try_block->statements()->Add(loop, zone);
FinalizeIteratorUse(var_completion, closing_condition, loop->iterator(),
try_block, target);
final_loop = target;
try_block, final_loop);
}
return final_loop;
......
......@@ -458,7 +458,8 @@ class ParserTraits {
void FinalizeIteratorUse(Variable* completion, Expression* condition,
Variable* iter, Block* iterator_use, Block* result);
Statement* FinalizeForOfStatement(ForOfStatement* loop, int pos);
Statement* FinalizeForOfStatement(ForOfStatement* loop, Variable* completion,
int pos);
// Reporting errors.
void ReportMessageAt(Scanner::Location source_location,
......@@ -961,12 +962,13 @@ class Parser : public ParserBase<ParserTraits> {
// Initialize the components of a for-in / for-of statement.
void InitializeForEachStatement(ForEachStatement* stmt, Expression* each,
Expression* subject, Statement* body,
int each_keyword_pos);
void InitializeForOfStatement(ForOfStatement* stmt, Expression* each,
Expression* iterable, Statement* body,
int next_result_pos = kNoSourcePosition);
Statement* InitializeForEachStatement(ForEachStatement* stmt,
Expression* each, Expression* subject,
Statement* body, int each_keyword_pos);
Statement* InitializeForOfStatement(ForOfStatement* stmt, Expression* each,
Expression* iterable, Statement* body,
bool finalize,
int next_result_pos = kNoSourcePosition);
Statement* DesugarLexicalBindingsInForStatement(
Scope* inner_scope, VariableMode mode,
ZoneList<const AstRawString*>* names, ForStatement* loop, Statement* init,
......
......@@ -13,10 +13,9 @@ snippet: "
"
frame size: 16
parameter count: 1
bytecode array length: 284
bytecode array length: 283
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdrUndefined), R(4),
B(LdaZero),
B(Star), R(3),
B(Mov), R(context), R(11),
......@@ -35,16 +34,16 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(2), U8(1),
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(Star), R(3),
B(LdrNamedProperty), R(2), U8(4), U8(11), R(0),
B(Ldar), R(0),
B(Mov), R(4), R(0),
/* 34 E> */ B(StackCheck),
B(Mov), R(0), R(7),
B(LdaZero),
B(Star), R(3),
B(Jump), U8(-48),
B(Jump), U8(-49),
B(Jump), U8(41),
B(Star), R(14),
B(LdaConstant), U8(5),
......@@ -143,9 +142,9 @@ constant pool: [
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
]
handlers: [
[9, 122, 128],
[12, 81, 83],
[201, 211, 213],
[7, 121, 127],
[10, 80, 82],
[200, 210, 212],
]
---
......@@ -155,12 +154,11 @@ snippet: "
"
frame size: 17
parameter count: 1
bytecode array length: 297
bytecode array length: 296
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(7),
B(LdrUndefined), R(4),
B(LdaZero),
B(Star), R(3),
B(Mov), R(context), R(12),
......@@ -177,18 +175,18 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(2), U8(1),
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(Star), R(3),
B(LdrNamedProperty), R(2), U8(4), U8(11), R(0),
B(Ldar), R(0),
B(Mov), R(4), R(0),
/* 54 E> */ B(StackCheck),
B(Mov), R(0), R(8),
/* 73 S> */ B(LdaZero),
B(Star), R(10),
B(Mov), R(0), R(11),
B(Jump), U8(57),
B(Jump), U8(-53),
B(Jump), U8(-54),
B(Jump), U8(41),
B(Star), R(15),
B(LdaConstant), U8(5),
......@@ -292,9 +290,9 @@ constant pool: [
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
]
handlers: [
[13, 125, 131],
[16, 84, 86],
[205, 215, 217],
[11, 124, 130],
[14, 83, 85],
[204, 214, 216],
]
---
......@@ -306,10 +304,9 @@ snippet: "
"
frame size: 16
parameter count: 1
bytecode array length: 300
bytecode array length: 299
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdrUndefined), R(4),
B(LdaZero),
B(Star), R(3),
B(Mov), R(context), R(11),
......@@ -328,11 +325,11 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(2), U8(1),
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(Star), R(3),
B(LdrNamedProperty), R(2), U8(4), U8(11), R(0),
B(Ldar), R(0),
B(Mov), R(4), R(0),
/* 34 E> */ B(StackCheck),
B(Mov), R(0), R(7),
/* 66 S> */ B(LdaSmi), U8(10),
......@@ -345,7 +342,7 @@ bytecodes: [
/* 104 S> */ B(Jump), U8(7),
B(LdaZero),
B(Star), R(3),
B(Jump), U8(-64),
B(Jump), U8(-65),
B(Jump), U8(41),
B(Star), R(14),
B(LdaConstant), U8(5),
......@@ -444,9 +441,9 @@ constant pool: [
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
]
handlers: [
[9, 138, 144],
[12, 97, 99],
[217, 227, 229],
[7, 137, 143],
[10, 96, 98],
[216, 226, 228],
]
---
......@@ -456,13 +453,12 @@ snippet: "
"
frame size: 15
parameter count: 1
bytecode array length: 308
bytecode array length: 309
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(1),
B(Star), R(8),
B(Star), R(6),
B(LdrUndefined), R(3),
B(LdaZero),
B(Star), R(2),
B(Mov), R(context), R(10),
......@@ -481,10 +477,11 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(1), U8(1),
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(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),
/* 62 E> */ B(StackCheck),
/* 88 S> */ B(Nop),
......@@ -492,7 +489,7 @@ bytecodes: [
B(LdaZero),
B(Star), R(8),
B(Jump), U8(57),
B(Jump), U8(-54),
B(Jump), U8(-57),
B(Jump), U8(41),
B(Star), R(13),
B(LdaConstant), U8(7),
......@@ -598,8 +595,8 @@ constant pool: [
InstanceType::ONE_BYTE_INTERNALIZED_STRING_TYPE,
]
handlers: [
[17, 136, 142],
[20, 95, 97],
[216, 226, 228],
[15, 137, 143],
[18, 96, 98],
[217, 227, 229],
]
......@@ -263,115 +263,114 @@ snippet: "
function* f() { for (let x of [42]) yield x }
f();
"
frame size: 17
frame size: 18
parameter count: 1
bytecode array length: 775
bytecode array length: 774
bytecodes: [
B(Ldar), R(new_target),
B(JumpIfUndefined), U8(26),
B(ResumeGenerator), R(new_target),
B(Star), R(3),
B(Star), R(4),
B(LdaZero),
B(TestEqualStrict), R(3),
B(TestEqualStrict), R(4),
B(JumpIfTrue), U8(62),
B(LdaSmi), U8(1),
B(TestEqualStrict), R(3),
B(TestEqualStrict), R(4),
B(JumpIfTrueConstant), U8(3),
B(LdaSmi), U8(76),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kAbort), R(4), U8(1),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kAbort), R(5), U8(1),
B(CallRuntime), U16(Runtime::kNewFunctionContext), R(closure), U8(1),
B(PushContext), R(0),
B(Ldar), R(this),
B(StaContextSlot), R(context), U8(4),
/* 11 E> */ B(StackCheck),
B(Mov), R(context), R(6),
/* 11 E> */ B(LdrContextSlot), R(context), U8(4), R(8),
B(Ldar), R(8),
B(Mov), R(closure), R(7),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(7), U8(2),
B(Mov), R(context), R(7),
/* 11 E> */ B(LdrContextSlot), R(context), U8(4), R(9),
B(Ldar), R(9),
B(Mov), R(closure), R(8),
B(CallRuntime), U16(Runtime::kCreateJSGeneratorObject), R(8), U8(2),
B(StaContextSlot), R(context), U8(5),
B(Star), R(7),
B(LdrContextSlot), R(context), U8(5), R(8),
B(Star), R(8),
B(LdrContextSlot), R(context), U8(5), R(9),
B(LdaZero),
B(SuspendGenerator), R(8),
B(Ldar), R(7),
B(SuspendGenerator), R(9),
B(Ldar), R(8),
/* 44 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(3),
B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(8), U8(1),
B(Star), R(9),
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(8), U8(1),
B(Star), R(4),
B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(9), U8(1),
B(Star), R(10),
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(9), U8(1),
B(Star), R(11),
B(LdaZero),
B(TestEqualStrict), R(10),
B(TestEqualStrict), R(11),
B(JumpIfTrue), U8(31),
B(LdaSmi), U8(2),
B(TestEqualStrict), R(10),
B(TestEqualStrict), R(11),
B(JumpIfTrue), U8(22),
B(Jump), U8(2),
B(LdaTrue),
B(Star), R(12),
B(Mov), R(9), R(11),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(11), U8(2),
B(Star), R(5),
B(Star), R(13),
B(Mov), R(10), R(12),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(12), U8(2),
B(Star), R(6),
B(LdaZero),
B(Star), R(4),
B(Star), R(5),
B(JumpConstant), U8(16),
B(Ldar), R(9),
B(Ldar), R(10),
/* 11 E> */ B(Throw),
B(LdaConstant), U8(0),
B(Star), R(7),
B(Mov), R(closure), R(8),
B(CallRuntime), U16(Runtime::kPushBlockContext), R(7), U8(2),
B(Star), R(8),
B(Mov), R(closure), R(9),
B(CallRuntime), U16(Runtime::kPushBlockContext), R(8), U8(2),
B(PushContext), R(1),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
B(LdaUndefined),
B(StaContextSlot), R(1), U8(10),
B(LdaZero),
B(StaContextSlot), R(1), U8(9),
B(Mov), R(context), R(9),
B(Mov), R(context), R(10),
B(Mov), R(context), R(11),
/* 30 S> */ B(CreateArrayLiteral), U8(1), U8(0), U8(3),
B(Star), R(12),
B(Star), R(13),
B(LdaConstant), U8(2),
/* 30 E> */ B(LdrKeyedProperty), R(12), U8(3), R(11),
/* 30 E> */ B(Call), R(11), R(12), U8(1), U8(1),
/* 30 E> */ B(LdrKeyedProperty), R(13), U8(3), R(12),
/* 30 E> */ B(Call), R(12), R(13), U8(1), U8(1),
/* 30 E> */ B(StaContextSlot), R(1), U8(7),
B(LdaSmi), U8(-2),
B(TestEqual), R(3),
B(TestEqual), R(4),
B(JumpIfTrue), U8(17),
B(LdaSmi), U8(1),
B(TestEqualStrict), R(3),
B(TestEqualStrict), R(4),
B(JumpIfTrueConstant), U8(9),
B(LdaSmi), U8(76),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kAbort), R(11), U8(1),
/* 27 S> */ B(LdrContextSlot), R(1), U8(7), R(13),
B(LdrNamedProperty), R(13), U8(4), U8(7), R(12),
/* 27 E> */ B(Call), R(12), R(13), U8(1), U8(5),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kAbort), R(12), U8(1),
/* 27 S> */ B(LdrContextSlot), R(1), U8(7), R(14),
B(LdrNamedProperty), R(14), U8(4), U8(7), R(13),
/* 27 E> */ B(Call), R(13), R(14), U8(1), U8(5),
/* 27 E> */ B(StaContextSlot), R(1), U8(8),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(11), U8(1),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(12), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(11),
B(LdrContextSlot), R(1), U8(8), R(11),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
B(LdrContextSlot), R(1), U8(8), R(11),
B(LdaNamedProperty), R(11), U8(5), U8(9),
B(LdrContextSlot), R(1), U8(8), R(12),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdrContextSlot), R(1), U8(8), R(12),
B(LdaNamedProperty), R(12), U8(5), U8(9),
B(JumpIfToBooleanTrueConstant), U8(10),
B(LdrContextSlot), R(1), U8(8), R(12),
B(LdaNamedProperty), R(12), U8(6), U8(11),
B(StaContextSlot), R(1), U8(10),
B(LdaSmi), U8(2),
B(StaContextSlot), R(1), U8(9),
B(LdrContextSlot), R(1), U8(8), R(11),
B(LdaNamedProperty), R(11), U8(6), U8(11),
B(StaContextSlot), R(1), U8(6),
B(LdaContextSlot), R(1), U8(10),
B(StaContextSlot), R(1), U8(6),
/* 16 E> */ B(StackCheck),
B(LdaConstant), U8(7),
B(Star), R(11),
B(Mov), R(closure), R(12),
B(CallRuntime), U16(Runtime::kPushBlockContext), R(11), U8(2),
B(Star), R(12),
B(Mov), R(closure), R(13),
B(CallRuntime), U16(Runtime::kPushBlockContext), R(12), U8(2),
B(PushContext), R(2),
B(LdaTheHole),
B(StaContextSlot), R(context), U8(4),
......@@ -380,35 +379,35 @@ bytecodes: [
/* 36 S> */ B(LdaContextSlot), R(context), U8(4),
B(JumpIfNotHole), U8(11),
B(LdaConstant), U8(8),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(13), U8(1),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kThrowReferenceError), R(12), U8(1),
B(Star), R(11),
B(LdaFalse),
B(Star), R(12),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(11), U8(2),
B(Star), R(13),
B(LdrContextSlot), R(1), U8(5), R(11),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(12), U8(2),
B(Star), R(14),
B(LdrContextSlot), R(1), U8(5), R(12),
B(LdaSmi), U8(1),
B(SuspendGenerator), R(11),
B(Ldar), R(13),
B(SuspendGenerator), R(12),
B(Ldar), R(14),
/* 44 S> */ B(Return),
B(LdaSmi), U8(-2),
B(Star), R(3),
B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(11), U8(1),
B(Star), R(12),
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(11), U8(1),
B(Star), R(14),
B(Star), R(4),
B(CallRuntime), U16(Runtime::k_GeneratorGetInputOrDebugPos), R(12), U8(1),
B(Star), R(13),
B(CallRuntime), U16(Runtime::k_GeneratorGetResumeMode), R(12), U8(1),
B(Star), R(15),
B(LdaZero),
B(TestEqualStrict), R(14),
B(TestEqualStrict), R(15),
B(JumpIfTrue), U8(45),
B(LdaSmi), U8(2),
B(TestEqualStrict), R(14),
B(TestEqualStrict), R(15),
B(JumpIfTrue), U8(36),
B(Jump), U8(2),
B(LdaTrue),
B(Star), R(16),
B(Mov), R(12), R(15),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(15), U8(2),
B(Star), R(17),
B(Mov), R(13), R(16),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(16), U8(2),
B(PopContext), R(2),
B(PopContext), R(2),
B(PopContext), R(2),
......@@ -416,167 +415,167 @@ bytecodes: [
B(PopContext), R(2),
B(PopContext), R(2),
B(PopContext), R(2),
B(Star), R(8),
B(Star), R(9),
B(LdaZero),
B(Star), R(7),
B(Star), R(8),
B(Jump), U8(75),
B(Ldar), R(12),
B(Ldar), R(13),
/* 36 E> */ B(Throw),
B(Ldar), R(12),
B(Ldar), R(13),
B(PopContext), R(2),
B(LdaZero),
B(StaContextSlot), R(1), U8(9),
B(Wide), B(Jump), U16(-222),
B(Wide), B(Jump), U16(-225),
B(Jump), U8(46),
B(Star), R(12),
B(Star), R(13),
B(LdaConstant), U8(11),
B(Star), R(12),
B(Mov), R(closure), R(14),
B(CallRuntime), U16(Runtime::kPushCatchContext), R(12), U8(3),
B(Star), R(11),
B(Mov), R(closure), R(13),
B(CallRuntime), U16(Runtime::kPushCatchContext), R(11), U8(3),
B(Star), R(10),
B(PushContext), R(2),
B(LdrContextSlot), R(1), U8(9), R(11),
B(LdrContextSlot), R(0), U8(9), R(12),
B(LdaSmi), U8(2),
B(TestEqualStrict), R(11),
B(TestEqualStrict), R(12),
B(JumpIfFalse), U8(7),
B(LdaSmi), U8(1),
B(StaContextSlot), R(1), U8(9),
B(LdrContextSlot), R(context), U8(4), R(11),
B(CallRuntime), U16(Runtime::kReThrow), R(11), U8(1),
B(StaContextSlot), R(0), U8(9),
B(LdrContextSlot), R(context), U8(4), R(12),
B(CallRuntime), U16(Runtime::kReThrow), R(12), U8(1),
B(PopContext), R(2),
B(LdaSmi), U8(-1),
B(Star), R(7),
B(Jump), U8(8),
B(Star), R(8),
B(Jump), U8(8),
B(Star), R(9),
B(LdaSmi), U8(1),
B(Star), R(7),
B(Star), R(8),
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
B(Star), R(9),
B(LdrContextSlot), R(1), U8(9), R(10),
B(Star), R(10),
B(LdrContextSlot), R(1), U8(9), R(11),
B(LdaZero),
B(TestEqualStrict), R(10),
B(TestEqualStrict), R(11),
B(JumpIfTrue), U8(9),
B(LdrContextSlot), R(1), U8(7), R(10),
B(LdrContextSlot), R(1), U8(7), R(11),
B(LdaUndefined),
B(TestEqualStrict), R(10),
B(TestEqualStrict), R(11),
B(ToBooleanLogicalNot),
B(JumpIfFalseConstant), U8(15),
B(LdrContextSlot), R(1), U8(7), R(10),
B(LdaNamedProperty), R(10), U8(12), U8(13),
B(LdrContextSlot), R(1), U8(7), R(11),
B(LdaNamedProperty), R(11), U8(12), U8(13),
B(StaContextSlot), R(1), U8(11),
B(LdrContextSlot), R(1), U8(11), R(10),
B(LdrContextSlot), R(1), U8(11), R(11),
B(LdaNull),
B(TestEqual), R(10),
B(TestEqual), R(11),
B(JumpIfFalse), U8(4),
B(Jump), U8(124),
B(LdrContextSlot), R(1), U8(9), R(10),
B(LdrContextSlot), R(1), U8(9), R(11),
B(LdaSmi), U8(1),
B(TestEqualStrict), R(10),
B(TestEqualStrict), R(11),
B(JumpIfFalse), U8(78),
B(LdaContextSlot), R(1), U8(11),
B(TypeOf),
B(Star), R(10),
B(Star), R(11),
B(LdaConstant), U8(13),
B(TestEqualStrict), R(10),
B(TestEqualStrict), R(11),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), U16(129),
B(Star), R(10),
B(LdaConstant), U8(14),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kNewTypeError), R(10), U8(2),
B(LdaConstant), U8(14),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kNewTypeError), R(11), U8(2),
B(Throw),
B(Mov), R(context), R(10),
B(LdrContextSlot), R(1), U8(11), R(11),
B(LdrContextSlot), R(1), U8(7), R(12),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(11), U8(2),
B(Mov), R(context), R(11),
B(LdrContextSlot), R(1), U8(11), R(12),
B(LdrContextSlot), R(1), U8(7), R(13),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(12), U8(2),
B(Jump), U8(29),
B(Star), R(12),
B(Star), R(13),
B(LdaConstant), U8(11),
B(Star), R(12),
B(Mov), R(closure), R(14),
B(CallRuntime), U16(Runtime::kPushCatchContext), R(12), U8(3),
B(Star), R(11),
B(Mov), R(closure), R(13),
B(CallRuntime), U16(Runtime::kPushCatchContext), R(11), U8(3),
B(Star), R(10),
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
B(Ldar), R(10),
B(Ldar), R(11),
B(PushContext), R(2),
B(PopContext), R(2),
B(Jump), U8(38),
B(LdrContextSlot), R(1), U8(11), R(10),
B(LdrContextSlot), R(1), U8(7), R(11),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(10), U8(2),
B(LdrContextSlot), R(1), U8(11), R(11),
B(LdrContextSlot), R(1), U8(7), R(12),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(11), U8(2),
B(StaContextSlot), R(1), U8(12),
B(LdrContextSlot), R(1), U8(12), R(10),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(10), U8(1),
B(LdrContextSlot), R(1), U8(12), R(11),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(11), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(11),
B(LdrContextSlot), R(1), U8(12), R(10),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(9), U8(1),
B(LdrContextSlot), R(1), U8(12), R(11),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(10), U8(1),
B(LdaZero),
B(TestEqualStrict), R(7),
B(TestEqualStrict), R(8),
B(JumpIfTrue), U8(10),
B(LdaSmi), U8(1),
B(TestEqualStrict), R(7),
B(TestEqualStrict), R(8),
B(JumpIfTrue), U8(17),
B(Jump), U8(28),
B(PopContext), R(1),
B(PopContext), R(1),
B(LdaSmi), U8(1),
B(Star), R(4),
B(Mov), R(8), R(5),
B(Star), R(5),
B(Mov), R(9), R(6),
B(Jump), U8(47),
B(PopContext), R(1),
B(PopContext), R(1),
B(LdaSmi), U8(2),
B(Star), R(4),
B(Mov), R(8), R(5),
B(Star), R(5),
B(Mov), R(9), R(6),
B(Jump), U8(34),
B(PopContext), R(1),
B(LdrUndefined), R(7),
B(LdrUndefined), R(8),
B(LdaTrue),
B(Star), R(8),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(7), U8(2),
B(Star), R(5),
B(Star), R(9),
B(CallRuntime), U16(Runtime::k_CreateIterResultObject), R(8), U8(2),
B(Star), R(6),
B(LdaSmi), U8(3),
B(Star), R(4),
B(Star), R(5),
B(Jump), U8(14),
B(LdaSmi), U8(-1),
B(Star), R(4),
B(Jump), U8(8),
B(Star), R(5),
B(Jump), U8(8),
B(Star), R(6),
B(LdaSmi), U8(4),
B(Star), R(4),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kInterpreterClearPendingMessage), R(0), U8(0),
B(Star), R(6),
B(LdrContextSlot), R(context), U8(5), R(7),
B(CallRuntime), U16(Runtime::k_GeneratorClose), R(7), U8(1),
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(6), U8(1),
B(Star), R(7),
B(LdrContextSlot), R(context), U8(5), R(8),
B(CallRuntime), U16(Runtime::k_GeneratorClose), R(8), U8(1),
B(CallRuntime), U16(Runtime::kInterpreterSetPendingMessage), R(7), U8(1),
B(LdaZero),
B(TestEqualStrict), R(4),
B(TestEqualStrict), R(5),
B(JumpIfTrue), U8(28),
B(LdaSmi), U8(1),
B(TestEqualStrict), R(4),
B(TestEqualStrict), R(5),
B(JumpIfTrue), U8(25),
B(LdaSmi), U8(2),
B(TestEqualStrict), R(4),
B(TestEqualStrict), R(5),
B(JumpIfTrue), U8(22),
B(LdaSmi), U8(3),
B(TestEqualStrict), R(4),
B(TestEqualStrict), R(5),
B(JumpIfTrue), U8(19),
B(LdaSmi), U8(4),
B(TestEqualStrict), R(4),
B(TestEqualStrict), R(5),
B(JumpIfTrue), U8(16),
B(Jump), U8(17),
B(Ldar), R(5),
B(Ldar), R(6),
/* 44 S> */ B(Return),
B(Ldar), R(5),
B(Ldar), R(6),
/* 44 S> */ B(Return),
B(Ldar), R(5),
B(Ldar), R(6),
B(ReThrow),
B(Ldar), R(5),
B(Ldar), R(6),
/* 44 S> */ B(Return),
B(Ldar), R(5),
B(Ldar), R(6),
B(ReThrow),
B(LdaUndefined),
/* 44 S> */ B(Return),
......@@ -601,9 +600,9 @@ constant pool: [
kInstanceTypeDontCare,
]
handlers: [
[44, 694, 700],
[154, 448, 454],
[157, 402, 404],
[551, 563, 565],
[44, 693, 699],
[150, 447, 453],
[153, 401, 403],
[550, 562, 564],
]
......@@ -966,8 +966,9 @@ function* g() { yield 42; return 88 };
// Next method throws.
{
let closed = false;
g.prototype.next = () => { throw 666; };
g.prototype.return = () => { assertUnreachable() };
g.prototype.return = () => { closed = true; };
assertThrowsEquals(() => {
......@@ -1025,13 +1026,17 @@ function* g() { yield 42; return 88 };
assertThrowsEquals(() => {
(([...x]) => x)(g());
}, 666);
assertFalse(closed);
}
// Value throws.
{
let closed = false;
g.prototype.next = () => ({get value() {throw 666}});
g.prototype.return = () => { assertUnreachable() };
g.prototype.return = () => { closed = true; };
assertThrowsEquals(() => {
......@@ -1089,13 +1094,17 @@ function* g() { yield 42; return 88 };
assertThrowsEquals(() => {
(([...x]) => x)(g());
}, 666);
assertFalse(closed);
}
// Done throws.
{
let closed = false;
g.prototype.next = () => ({get done() {throw 666}});
g.prototype.return = () => { assertUnreachable() };
g.prototype.return = () => { closed = true; };
assertThrowsEquals(() => {
......@@ -1153,6 +1162,9 @@ function* g() { yield 42; return 88 };
assertThrowsEquals(() => {
(([...x]) => x)(g());
}, 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