Upgrade V8 to 5.1.281.57 DO NOT MERGE
FPIIM-449
Change-Id: Id981b686b4d587ac31697662eb98bb34be42ad90
(cherry picked from commit 3b9bc31999c9787eb726ecdbfd5796bfdec32a18)
diff --git a/src/parsing/pattern-rewriter.cc b/src/parsing/pattern-rewriter.cc
index 768a948..e699255 100644
--- a/src/parsing/pattern-rewriter.cc
+++ b/src/parsing/pattern-rewriter.cc
@@ -17,6 +17,8 @@
ZoneList<const AstRawString*>* names, bool* ok) {
PatternRewriter rewriter;
+ DCHECK(block->ignore_completion_value());
+
rewriter.scope_ = declaration_descriptor->scope;
rewriter.parser_ = declaration_descriptor->parser;
rewriter.context_ = BINDING;
@@ -234,22 +236,20 @@
if (IsImmutableVariableMode(descriptor_->mode)) {
arguments->Add(value, zone());
- value = NULL; // zap the value to avoid the unnecessary assignment
-
// Construct the call to Runtime_InitializeConstGlobal
// and add it to the initialization statement block.
// Note that the function does different things depending on
// the number of arguments (1 or 2).
- initialize =
- factory()->NewCallRuntime(Runtime::kInitializeConstGlobal, arguments,
- descriptor_->initialization_pos);
+ initialize = factory()->NewCallRuntime(Runtime::kInitializeConstGlobal,
+ arguments, value->position());
+ value = NULL; // zap the value to avoid the unnecessary assignment
} else {
// Add language mode.
// We may want to pass singleton to avoid Literal allocations.
LanguageMode language_mode = initialization_scope->language_mode();
- arguments->Add(factory()->NewNumberLiteral(language_mode,
- descriptor_->declaration_pos),
- zone());
+ arguments->Add(
+ factory()->NewNumberLiteral(language_mode, RelocInfo::kNoPosition),
+ zone());
// Be careful not to assign a value to the global variable if
// we're in a with. The initialization value should not
@@ -257,12 +257,11 @@
// which is why we need to generate a separate assignment node.
if (value != NULL && !descriptor_->scope->inside_with()) {
arguments->Add(value, zone());
- value = NULL; // zap the value to avoid the unnecessary assignment
// Construct the call to Runtime_InitializeVarGlobal
// and add it to the initialization statement block.
- initialize =
- factory()->NewCallRuntime(Runtime::kInitializeVarGlobal, arguments,
- descriptor_->declaration_pos);
+ initialize = factory()->NewCallRuntime(Runtime::kInitializeVarGlobal,
+ arguments, value->position());
+ value = NULL; // zap the value to avoid the unnecessary assignment
} else {
initialize = NULL;
}
@@ -270,7 +269,7 @@
if (initialize != NULL) {
block_->statements()->Add(
- factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition),
+ factory()->NewExpressionStatement(initialize, initialize->position()),
zone());
}
} else if (value != nullptr && (descriptor_->mode == CONST_LEGACY ||
@@ -286,7 +285,7 @@
DCHECK_NOT_NULL(proxy->var());
DCHECK_NOT_NULL(value);
// Add break location for destructured sub-pattern.
- int pos = IsSubPattern() ? pattern->position() : RelocInfo::kNoPosition;
+ int pos = IsSubPattern() ? pattern->position() : value->position();
Assignment* assignment =
factory()->NewAssignment(Token::INIT, proxy, value, pos);
block_->statements()->Add(
@@ -303,7 +302,7 @@
// property).
VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name);
// Add break location for destructured sub-pattern.
- int pos = IsSubPattern() ? pattern->position() : RelocInfo::kNoPosition;
+ int pos = IsSubPattern() ? pattern->position() : value->position();
Assignment* assignment =
factory()->NewAssignment(Token::INIT, proxy, value, pos);
block_->statements()->Add(
@@ -365,7 +364,7 @@
PatternContext old_context = SetAssignmentContextIfNeeded(initializer);
int pos = assign->position();
Block* old_block = block_;
- block_ = factory()->NewBlock(nullptr, 8, false, pos);
+ block_ = factory()->NewBlock(nullptr, 8, true, pos);
Variable* temp = nullptr;
Expression* pattern = assign->target();
Expression* old_value = current_value_;
@@ -414,16 +413,27 @@
void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
Variable** temp_var) {
+ DCHECK(block_->ignore_completion_value());
+
auto temp = *temp_var = CreateTempVar(current_value_);
-
- block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
-
auto iterator = CreateTempVar(parser_->GetIterator(
factory()->NewVariableProxy(temp), factory(), RelocInfo::kNoPosition));
auto done = CreateTempVar(
factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition));
auto result = CreateTempVar();
auto v = CreateTempVar();
+ auto completion = CreateTempVar();
+ auto nopos = RelocInfo::kNoPosition;
+
+ // For the purpose of iterator finalization, we temporarily set block_ to a
+ // new block. In the main body of this function, we write to block_ (both
+ // explicitly and implicitly via recursion). At the end of the function, we
+ // wrap this new block in a try-finally statement, restore block_ to its
+ // original value, and add the try-finally statement to block_.
+ auto target = block_;
+ if (FLAG_harmony_iterator_close) {
+ block_ = factory()->NewBlock(nullptr, 8, true, nopos);
+ }
Spread* spread = nullptr;
for (Expression* value : *node->values()) {
@@ -433,88 +443,201 @@
}
PatternContext context = SetInitializerContextIfNeeded(value);
+
// if (!done) {
+ // done = true; // If .next, .done or .value throws, don't close.
// result = IteratorNext(iterator);
- // v = (done = result.done) ? undefined : result.value;
+ // if (result.done) {
+ // v = undefined;
+ // } else {
+ // v = result.value;
+ // done = false;
+ // }
// }
- auto next_block =
- factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition);
- next_block->statements()->Add(factory()->NewExpressionStatement(
- parser_->BuildIteratorNextResult(
- factory()->NewVariableProxy(iterator),
- result, RelocInfo::kNoPosition),
+ Statement* if_not_done;
+ {
+ auto result_done = factory()->NewProperty(
+ factory()->NewVariableProxy(result),
+ factory()->NewStringLiteral(ast_value_factory()->done_string(),
RelocInfo::kNoPosition),
- zone());
+ RelocInfo::kNoPosition);
- auto assign_to_done = factory()->NewAssignment(
- Token::ASSIGN, factory()->NewVariableProxy(done),
- factory()->NewProperty(
- factory()->NewVariableProxy(result),
- factory()->NewStringLiteral(ast_value_factory()->done_string(),
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition);
- auto next_value = factory()->NewConditional(
- assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
- factory()->NewProperty(
- factory()->NewVariableProxy(result),
- factory()->NewStringLiteral(ast_value_factory()->value_string(),
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition);
- next_block->statements()->Add(
- factory()->NewExpressionStatement(
- factory()->NewAssignment(Token::ASSIGN,
- factory()->NewVariableProxy(v), next_value,
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition),
- zone());
+ auto assign_undefined = factory()->NewAssignment(
+ Token::ASSIGN, factory()->NewVariableProxy(v),
+ factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
+ RelocInfo::kNoPosition);
- auto if_statement = factory()->NewIfStatement(
- factory()->NewUnaryOperation(Token::NOT,
- factory()->NewVariableProxy(done),
- RelocInfo::kNoPosition),
- next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition),
- RelocInfo::kNoPosition);
- block_->statements()->Add(if_statement, zone());
+ auto assign_value = factory()->NewAssignment(
+ Token::ASSIGN, factory()->NewVariableProxy(v),
+ factory()->NewProperty(
+ factory()->NewVariableProxy(result),
+ factory()->NewStringLiteral(ast_value_factory()->value_string(),
+ RelocInfo::kNoPosition),
+ RelocInfo::kNoPosition),
+ RelocInfo::kNoPosition);
+
+ auto unset_done = factory()->NewAssignment(
+ Token::ASSIGN, factory()->NewVariableProxy(done),
+ factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition),
+ RelocInfo::kNoPosition);
+
+ auto inner_else =
+ factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition);
+ inner_else->statements()->Add(
+ factory()->NewExpressionStatement(assign_value, nopos), zone());
+ inner_else->statements()->Add(
+ factory()->NewExpressionStatement(unset_done, nopos), zone());
+
+ auto inner_if = factory()->NewIfStatement(
+ result_done,
+ factory()->NewExpressionStatement(assign_undefined, nopos),
+ inner_else, nopos);
+
+ auto next_block =
+ factory()->NewBlock(nullptr, 3, true, RelocInfo::kNoPosition);
+ next_block->statements()->Add(
+ factory()->NewExpressionStatement(
+ factory()->NewAssignment(
+ Token::ASSIGN, factory()->NewVariableProxy(done),
+ factory()->NewBooleanLiteral(true, nopos), nopos),
+ nopos),
+ zone());
+ next_block->statements()->Add(
+ factory()->NewExpressionStatement(
+ parser_->BuildIteratorNextResult(
+ factory()->NewVariableProxy(iterator), result,
+ RelocInfo::kNoPosition),
+ RelocInfo::kNoPosition),
+ zone());
+ next_block->statements()->Add(inner_if, zone());
+
+ if_not_done = factory()->NewIfStatement(
+ factory()->NewUnaryOperation(Token::NOT,
+ factory()->NewVariableProxy(done),
+ RelocInfo::kNoPosition),
+ next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition),
+ RelocInfo::kNoPosition);
+ }
+ block_->statements()->Add(if_not_done, zone());
if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) {
+ if (FLAG_harmony_iterator_close) {
+ // completion = kAbruptCompletion;
+ Expression* proxy = factory()->NewVariableProxy(completion);
+ Expression* assignment = factory()->NewAssignment(
+ Token::ASSIGN, proxy,
+ factory()->NewSmiLiteral(kAbruptCompletion, nopos), nopos);
+ block_->statements()->Add(
+ factory()->NewExpressionStatement(assignment, nopos), zone());
+ }
+
RecurseIntoSubpattern(value, factory()->NewVariableProxy(v));
+
+ if (FLAG_harmony_iterator_close) {
+ // completion = kNormalCompletion;
+ Expression* proxy = factory()->NewVariableProxy(completion);
+ Expression* assignment = factory()->NewAssignment(
+ Token::ASSIGN, proxy,
+ factory()->NewSmiLiteral(kNormalCompletion, nopos), nopos);
+ block_->statements()->Add(
+ factory()->NewExpressionStatement(assignment, nopos), zone());
+ }
}
set_context(context);
}
if (spread != nullptr) {
- // array = [];
- // if (!done) %concat_iterable_to_array(array, iterator);
- auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone());
- auto array = CreateTempVar(factory()->NewArrayLiteral(
- empty_exprs,
- // Reuse pattern's literal index - it is unused since there is no
- // actual literal allocated.
- node->literal_index(), is_strong(scope()->language_mode()),
- RelocInfo::kNoPosition));
+ // A spread can only occur as the last component. It is not handled by
+ // RecurseIntoSubpattern above.
- auto arguments = new (zone()) ZoneList<Expression*>(2, zone());
- arguments->Add(factory()->NewVariableProxy(array), zone());
- arguments->Add(factory()->NewVariableProxy(iterator), zone());
- auto spread_into_array_call =
- factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX,
- arguments, RelocInfo::kNoPosition);
+ // let array = [];
+ // while (!done) {
+ // result = IteratorNext(iterator);
+ // if (result.done) {
+ // done = true;
+ // } else {
+ // %AppendElement(array, result.value);
+ // }
+ // }
- auto if_statement = factory()->NewIfStatement(
- factory()->NewUnaryOperation(Token::NOT,
- factory()->NewVariableProxy(done),
- RelocInfo::kNoPosition),
- factory()->NewExpressionStatement(spread_into_array_call,
- RelocInfo::kNoPosition),
- factory()->NewEmptyStatement(RelocInfo::kNoPosition),
- RelocInfo::kNoPosition);
- block_->statements()->Add(if_statement, zone());
+ // let array = [];
+ Variable* array;
+ {
+ auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone());
+ array = CreateTempVar(factory()->NewArrayLiteral(
+ empty_exprs,
+ // Reuse pattern's literal index - it is unused since there is no
+ // actual literal allocated.
+ node->literal_index(), RelocInfo::kNoPosition));
+ }
+ // result = IteratorNext(iterator);
+ Statement* get_next = factory()->NewExpressionStatement(
+ parser_->BuildIteratorNextResult(factory()->NewVariableProxy(iterator),
+ result, nopos),
+ nopos);
+
+ // done = true;
+ Statement* set_done = factory()->NewExpressionStatement(
+ factory()->NewAssignment(
+ Token::ASSIGN, factory()->NewVariableProxy(done),
+ factory()->NewBooleanLiteral(true, nopos), nopos),
+ nopos);
+
+ // %AppendElement(array, result.value);
+ Statement* append_element;
+ {
+ auto args = new (zone()) ZoneList<Expression*>(2, zone());
+ args->Add(factory()->NewVariableProxy(array), zone());
+ args->Add(factory()->NewProperty(
+ factory()->NewVariableProxy(result),
+ factory()->NewStringLiteral(
+ ast_value_factory()->value_string(), nopos),
+ nopos),
+ zone());
+ append_element = factory()->NewExpressionStatement(
+ factory()->NewCallRuntime(Runtime::kAppendElement, args, nopos),
+ nopos);
+ }
+
+ // if (result.done) { #set_done } else { #append_element }
+ Statement* set_done_or_append;
+ {
+ Expression* result_done =
+ factory()->NewProperty(factory()->NewVariableProxy(result),
+ factory()->NewStringLiteral(
+ ast_value_factory()->done_string(), nopos),
+ nopos);
+ set_done_or_append = factory()->NewIfStatement(result_done, set_done,
+ append_element, nopos);
+ }
+
+ // while (!done) {
+ // #get_next;
+ // #set_done_or_append;
+ // }
+ WhileStatement* loop = factory()->NewWhileStatement(nullptr, nopos);
+ {
+ Expression* condition = factory()->NewUnaryOperation(
+ Token::NOT, factory()->NewVariableProxy(done), nopos);
+ Block* body = factory()->NewBlock(nullptr, 2, true, nopos);
+ body->statements()->Add(get_next, zone());
+ body->statements()->Add(set_done_or_append, zone());
+ loop->Initialize(condition, body);
+ }
+
+ block_->statements()->Add(loop, zone());
RecurseIntoSubpattern(spread->expression(),
factory()->NewVariableProxy(array));
}
+
+ if (FLAG_harmony_iterator_close) {
+ Expression* closing_condition = factory()->NewUnaryOperation(
+ Token::NOT, factory()->NewVariableProxy(done), nopos);
+ parser_->FinalizeIteratorUse(completion, closing_condition, iterator,
+ block_, target);
+ block_ = target;
+ }
}