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; |
} |