Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index ae1a8c14c7d6e0e16def6f0e99897519c7afefdf..e8f3a64190e462c97e6c900432f8d982ec24d1b5 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -4039,31 +4039,6 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| formals_end_position, CHECK_OK); |
| Expect(Token::LBRACE, CHECK_OK); |
| - // If we have a named function expression, we add a local variable |
| - // declaration to the body of the function with the name of the |
| - // function and let it refer to the function itself (closure). |
| - // NOTE: We create a proxy and resolve it here so that in the |
| - // future we can change the AST to only refer to VariableProxies |
| - // instead of Variables and Proxis as is the case now. |
| - Variable* fvar = NULL; |
| - Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
| - if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| - bool use_strict_const = is_strict(language_mode) || |
| - (!allow_legacy_const() && allow_harmony_sloppy()); |
| - if (use_strict_const) { |
| - fvar_init_op = Token::INIT_CONST; |
| - } |
| - VariableMode fvar_mode = use_strict_const ? CONST : CONST_LEGACY; |
| - DCHECK(function_name != NULL); |
| - fvar = new (zone()) |
| - Variable(scope_, function_name, fvar_mode, Variable::NORMAL, |
| - kCreatedInitialized, kNotAssigned); |
| - VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| - VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| - proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
| - scope_->DeclareFunctionVar(fvar_declaration); |
| - } |
| - |
| // Determine if the function can be parsed lazily. Lazy parsing is different |
| // from lazy compilation; we need to parse more eagerly than we compile. |
| @@ -4127,8 +4102,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| } |
| } |
| if (!is_lazily_parsed) { |
| - body = ParseEagerFunctionBody(function_name, pos, formals, fvar, |
| - fvar_init_op, kind, CHECK_OK); |
| + body = ParseEagerFunctionBody(function_name, pos, formals, kind, |
| + function_type, CHECK_OK); |
| materialized_literal_count = function_state.materialized_literal_count(); |
| expected_property_count = function_state.expected_property_count(); |
| } |
| @@ -4344,23 +4319,24 @@ Block* Parser::BuildParameterInitializationBlock( |
| ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| const AstRawString* function_name, int pos, |
| - const ParserFormalParameters& parameters, Variable* fvar, |
| - Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
| + const ParserFormalParameters& parameters, FunctionKind kind, |
| + FunctionLiteral::FunctionType function_type, bool* ok) { |
| // Everything inside an eagerly parsed function will be parsed eagerly |
| // (see comment above). |
| ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| ZoneList<Statement*>* result = new(zone()) ZoneList<Statement*>(8, zone()); |
| - if (fvar != NULL) { |
| - VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name); |
| - fproxy->BindTo(fvar); |
| - result->Add(factory()->NewExpressionStatement( |
| - factory()->NewAssignment(fvar_init_op, |
| - fproxy, |
| - factory()->NewThisFunction(pos), |
| - RelocInfo::kNoPosition), |
| - RelocInfo::kNoPosition), zone()); |
| - } |
| + static const int kFunctionNameAssignmentIndex = 0; |
| + if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| + DCHECK(function_name != NULL); |
| + // If we have a named function expression, we add a local variable |
| + // declaration to the body of the function with the name of the |
| + // function and let it refer to the function itself (closure). |
| + // Not having parsed the function body, the language mode may still change, |
| + // so we reserve a spot and create the actual const assignment later. |
| + DCHECK_EQ(kFunctionNameAssignmentIndex, result->length()); |
| + result->Add(NULL, zone()); |
| + } |
| // For concise constructors, check that they are constructed, |
| // not called. |
| @@ -4445,6 +4421,37 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
| result->Add(inner_block, zone()); |
| } |
| + if (function_type == FunctionLiteral::NAMED_EXPRESSION) { |
| + // Now that we know the language mode, we can create the const assignment |
| + // in the previously reserved spot. |
| + // NOTE: We create a proxy and resolve it here so that in the |
| + // future we can change the AST to only refer to VariableProxies |
| + // instead of Variables and Proxies as is the case now. |
| + Token::Value fvar_init_op = Token::INIT_CONST_LEGACY; |
| + bool use_strict_const = is_strict(scope_->language_mode()) || |
| + (!allow_legacy_const() && allow_harmony_sloppy()); |
| + if (use_strict_const) { |
| + fvar_init_op = Token::INIT_CONST; |
| + } |
| + VariableMode fvar_mode = use_strict_const ? CONST : CONST_LEGACY; |
|
rossberg
2015/08/04 09:47:36
Wait, I thought the idea was that this should alwa
|
| + Variable* fvar = new (zone()) |
| + Variable(scope_, function_name, fvar_mode, Variable::NORMAL, |
| + kCreatedInitialized, kNotAssigned); |
| + VariableProxy* proxy = factory()->NewVariableProxy(fvar); |
| + VariableDeclaration* fvar_declaration = factory()->NewVariableDeclaration( |
| + proxy, fvar_mode, scope_, RelocInfo::kNoPosition); |
| + scope_->DeclareFunctionVar(fvar_declaration); |
| + |
| + VariableProxy* fproxy = scope_->NewUnresolved(factory(), function_name); |
| + fproxy->BindTo(fvar); |
| + result->Set(kFunctionNameAssignmentIndex, |
| + factory()->NewExpressionStatement( |
| + factory()->NewAssignment(fvar_init_op, fproxy, |
| + factory()->NewThisFunction(pos), |
| + RelocInfo::kNoPosition), |
| + RelocInfo::kNoPosition)); |
| + } |
| + |
| return result; |
| } |