| Index: src/parser.cc
|
| diff --git a/src/parser.cc b/src/parser.cc
|
| index c1ae28577974f5e91f9aa87864bdcd7b6886e46c..7acb3cde58d697d7480895c3b9606150d81cc581 100644
|
| --- a/src/parser.cc
|
| +++ b/src/parser.cc
|
| @@ -2828,7 +2828,7 @@ Statement* Parser::ParseReturnStatement(bool* ok) {
|
| //
|
| // return (temp = expr) === undefined ? this :
|
| // %_IsSpecObject(temp) ? temp : throw new TypeError(...);
|
| - Variable* temp = scope_->DeclarationScope()->NewTemporary(
|
| + Variable* temp = scope_->TempScope()->NewTemporary(
|
| ast_value_factory()->empty_string());
|
| Assignment* assign = factory()->NewAssignment(
|
| Token::ASSIGN, factory()->NewVariableProxy(temp), return_value, pos);
|
| @@ -3182,9 +3182,9 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt,
|
| ForOfStatement* for_of = stmt->AsForOfStatement();
|
|
|
| if (for_of != NULL) {
|
| - Variable* iterator = scope_->DeclarationScope()->NewTemporary(
|
| + Variable* iterator = scope_->TempScope()->NewTemporary(
|
| ast_value_factory()->dot_iterator_string());
|
| - Variable* result = scope_->DeclarationScope()->NewTemporary(
|
| + Variable* result = scope_->TempScope()->NewTemporary(
|
| ast_value_factory()->dot_result_string());
|
|
|
| Expression* assign_iterator;
|
| @@ -3300,7 +3300,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
|
| // make statement: temp_x = x.
|
| for (int i = 0; i < names->length(); i++) {
|
| VariableProxy* proxy = NewUnresolved(names->at(i), LET);
|
| - Variable* temp = scope_->DeclarationScope()->NewTemporary(temp_name);
|
| + Variable* temp = scope_->TempScope()->NewTemporary(temp_name);
|
| VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
|
| Assignment* assignment = factory()->NewAssignment(
|
| Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
|
| @@ -3313,7 +3313,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
|
| Variable* first = NULL;
|
| // Make statement: first = 1.
|
| if (next) {
|
| - first = scope_->DeclarationScope()->NewTemporary(temp_name);
|
| + first = scope_->TempScope()->NewTemporary(temp_name);
|
| VariableProxy* first_proxy = factory()->NewVariableProxy(first);
|
| Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
|
| Assignment* assignment = factory()->NewAssignment(
|
| @@ -3393,7 +3393,7 @@ Statement* Parser::DesugarLexicalBindingsInForStatement(
|
| ignore_completion_block->AddStatement(clear_first_or_next, zone());
|
| }
|
|
|
| - Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
|
| + Variable* flag = scope_->TempScope()->NewTemporary(temp_name);
|
| // Make statement: flag = 1.
|
| {
|
| VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
|
| @@ -3579,7 +3579,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
|
| // let x; // for TDZ
|
| // }
|
|
|
| - Variable* temp = scope_->DeclarationScope()->NewTemporary(
|
| + Variable* temp = scope_->TempScope()->NewTemporary(
|
| ast_value_factory()->dot_for_string());
|
| ForEachStatement* loop =
|
| factory()->NewForEachStatement(mode, labels, stmt_pos);
|
| @@ -4012,7 +4012,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| // Calling a generator returns a generator object. That object is stored
|
| // in a temporary variable, a definition that is used by "yield"
|
| // expressions. This also marks the FunctionState as a generator.
|
| - Variable* temp = scope_->DeclarationScope()->NewTemporary(
|
| + Variable* temp = scope_->TempScope()->NewTemporary(
|
| ast_value_factory()->dot_generator_object_string());
|
| function_state.set_generator_object_variable(temp);
|
| }
|
| @@ -4173,11 +4173,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
| if (should_be_used_once_hint)
|
| function_literal->set_should_be_used_once_hint();
|
|
|
| - if (scope->has_rest_parameter()) {
|
| - // TODO(caitp): enable optimization of functions with rest params
|
| - function_literal->set_dont_optimize_reason(kRestParameter);
|
| - }
|
| -
|
| if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
|
| return function_literal;
|
| }
|
| @@ -4309,6 +4304,7 @@ Statement* Parser::BuildAssertIsCoercible(Variable* var) {
|
|
|
| bool Parser::IsSimpleParameterList(
|
| const ParserFormalParameterParsingState& formal_parameters) {
|
| + if (formal_parameters.has_rest) return false;
|
| for (auto parameter : formal_parameters.params) {
|
| if (parameter.pattern != nullptr) return false;
|
| }
|
| @@ -4341,6 +4337,99 @@ Block* Parser::BuildParameterInitializationBlock(
|
| PatternRewriter::DeclareAndInitializeVariables(init_block, &descriptor,
|
| &decl, nullptr, CHECK_OK);
|
| }
|
| + if (formal_parameters.has_rest) {
|
| + auto rest_parameter = formal_parameters.params.last();
|
| + int rest_index = formal_parameters.params.length() - 1;
|
| + DCHECK_NULL(rest_parameter.pattern);
|
| +
|
| + // DESUGAR:
|
| + // let <rest_params> = [];
|
| + // for (int i = <rest_index>; i < <arguments.length>; ++i) {
|
| + // %AddElement(<rest_params>, <rest_params.length>, arguments[i++]);
|
| + // }
|
| + VariableProxy* proxy = factory()->NewVariableProxy(rest_parameter.var);
|
| + Declaration* declaration = factory()->NewVariableDeclaration(
|
| + proxy, VAR, scope_, RelocInfo::kNoPosition);
|
| + Variable* var = this->Declare(declaration, DeclarationDescriptor::PARAMETER,
|
| + false, CHECK_OK);
|
| + proxy = factory()->NewVariableProxy(var);
|
| +
|
| + // TODO(@caitp): use an array literal to avoid escaping the object and
|
| + // needing 2 runtime functions which do the same thing.
|
| + auto empty_values = new (zone()) ZoneList<Expression*>(0, zone());
|
| + Expression* empty_array = factory()->NewCallRuntime(
|
| + is_strong(language_mode())
|
| + ? ast_value_factory()->strong_empty_array_string()
|
| + : ast_value_factory()->empty_array_string(),
|
| + nullptr, empty_values, RelocInfo::kNoPosition);
|
| +
|
| + Assignment* init_array = factory()->NewAssignment(
|
| + Token::INIT_VAR, proxy, empty_array, RelocInfo::kNoPosition);
|
| +
|
| + auto loop = factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
|
| +
|
| + // argument_index = rest_index
|
| + Variable* argument_index =
|
| + scope_->NewTemporary(ast_value_factory()->dot_string());
|
| + auto init = factory()->NewExpressionStatement(
|
| + factory()->NewAssignment(
|
| + Token::INIT_VAR, factory()->NewVariableProxy(argument_index),
|
| + factory()->NewSmiLiteral(rest_index, RelocInfo::kNoPosition),
|
| + RelocInfo::kNoPosition),
|
| + RelocInfo::kNoPosition);
|
| +
|
| + auto arguments_length = Runtime::FunctionForId(Runtime::kArgumentsLength);
|
| + auto empty_arguments = new (zone()) ZoneList<Expression*>(0, zone());
|
| +
|
| + // argument_index < %_ArgumentsLength()
|
| + auto cond = factory()->NewCompareOperation(
|
| + Token::LT, factory()->NewVariableProxy(argument_index),
|
| + factory()->NewCallRuntime(ast_value_factory()->empty_string(),
|
| + arguments_length, empty_arguments,
|
| + RelocInfo::kNoPosition),
|
| + RelocInfo::kNoPosition);
|
| +
|
| + // ++argument_index
|
| + auto next = factory()->NewExpressionStatement(
|
| + factory()->NewCountOperation(
|
| + Token::INC, true, factory()->NewVariableProxy(argument_index),
|
| + RelocInfo::kNoPosition),
|
| + RelocInfo::kNoPosition);
|
| +
|
| + auto arguments = Runtime::FunctionForId(Runtime::kArguments);
|
| + // %_Arguments(<argument_index>)
|
| + auto arguments_args = new (zone()) ZoneList<Expression*>(1, zone());
|
| + arguments_args->Add(factory()->NewVariableProxy(argument_index), zone());
|
| +
|
| + // %AddElement(
|
| + // <restParam>, <restParam.length>, %_Arguments(<argument_index>));
|
| + auto add_element = Runtime::FunctionForId(Runtime::kAddElement);
|
| + auto add_element_args = new (zone()) ZoneList<Expression*>(3, zone());
|
| + add_element_args->Add(factory()->NewVariableProxy(var), zone());
|
| + add_element_args->Add(
|
| + factory()->NewProperty(
|
| + factory()->NewVariableProxy(var),
|
| + factory()->NewStringLiteral(ast_value_factory()->length_string(),
|
| + RelocInfo::kNoPosition),
|
| + RelocInfo::kNoPosition),
|
| + zone());
|
| + add_element_args->Add(factory()->NewCallRuntime(
|
| + ast_value_factory()->empty_string(), arguments,
|
| + arguments_args, RelocInfo::kNoPosition),
|
| + zone());
|
| +
|
| + auto body = factory()->NewExpressionStatement(
|
| + factory()->NewCallRuntime(ast_value_factory()->empty_string(),
|
| + add_element, add_element_args,
|
| + RelocInfo::kNoPosition),
|
| + RelocInfo::kNoPosition);
|
| +
|
| + loop->Initialize(init, cond, next, body);
|
| + init_block->AddStatement(
|
| + factory()->NewExpressionStatement(init_array, RelocInfo::kNoPosition),
|
| + zone());
|
| + init_block->AddStatement(loop, zone());
|
| + }
|
| return init_block;
|
| }
|
|
|
| @@ -5964,8 +6053,8 @@ Expression* Parser::SpreadCall(Expression* function,
|
| args->InsertAt(0, function, zone());
|
| args->InsertAt(1, home, zone());
|
| } else {
|
| - Variable* temp =
|
| - scope_->NewTemporary(ast_value_factory()->empty_string());
|
| + Variable* temp = scope_->TempScope()->NewTemporary(
|
| + ast_value_factory()->empty_string());
|
| VariableProxy* obj = factory()->NewVariableProxy(temp);
|
| Assignment* assign_obj = factory()->NewAssignment(
|
| Token::ASSIGN, obj, function->AsProperty()->obj(),
|
|
|