Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index 409059778a6a5f44606f6d0bed20af710cb797ec..534a37b08fdad890d1fb89c5f5f264a60026a17a 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -3973,8 +3973,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| scope_->DeclareFunctionVar(fvar_declaration); |
| } |
| - // Determine whether the function will be lazily compiled. |
| - // The heuristics are: |
| + // Determine if the function can be parsed lazily. Lazy parsing is different |
| + // from lazy compilation; we need to parse more eagerly than we compile. |
| + |
| + // We can only parse lazily if we also compile lazily. The heuristics for |
| + // lazy compilation are: |
| // - It must not have been prohibited by the caller to Parse (some callers |
| // need a full AST). |
| // - The outer scope must allow lazy compilation of inner functions. |
| @@ -3984,12 +3987,31 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| // compiled. |
| // These are all things we can know at this point, without looking at the |
| // function itself. |
| - bool is_lazily_compiled = (mode() == PARSE_LAZILY && |
| - scope_->AllowsLazyCompilation() && |
| - !parenthesized_function_); |
| + |
| + // In addition, we need to distinguish between these cases: |
| + // (function foo() { |
| + // bar = function() { return 1; } |
| + // })(); |
| + // and |
| + // (function foo() { |
| + // var a = 1; |
| + // bar = function() { return a; } |
| + // })(); |
| + |
| + // Now foo will be parsed eagerly and compiled eagerly (optimization: assume |
| + // parenthesis before the function means that it will be called |
| + // immediately). The inner function *must* be parsed eagerly to resolve the |
| + // possible reference to the variable in foo's scope. However, it's possible |
| + // that it will be compiled lazily. |
| + |
| + // To make this additional case work, both Parser and PreParser implement a |
| + // logic where only top-level functions will be parsed lazily. |
| + bool is_lazily_parsed = (mode() == PARSE_LAZILY && |
| + scope_->AllowsLazyCompilation() && |
| + !parenthesized_function_); |
| parenthesized_function_ = false; // The bit was set for this function only. |
| - if (is_lazily_compiled) { |
| + if (is_lazily_parsed) { |
| int function_block_pos = position(); |
| FunctionEntry entry; |
| if (pre_parse_data_ != NULL) { |
| @@ -4013,7 +4035,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| expected_property_count = entry.property_count(); |
| scope_->SetLanguageMode(entry.language_mode()); |
| } else { |
| - is_lazily_compiled = false; |
| + is_lazily_parsed = false; |
|
Sven Panne
2014/02/19 09:51:11
Mind explosion... o_O Can we add a comment here, t
marja
2014/02/19 12:19:47
This is just an error case, where we do have prepa
|
| } |
| } else { |
| // With no preparser data, we partially parse the function, without |
| @@ -4050,7 +4072,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral( |
| } |
| } |
| - if (!is_lazily_compiled) { |
| + if (!is_lazily_parsed) { |
| + // Everything inside an eagerly parsed function will be parsed eagerly |
| + // (see comment above). |
| ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| body = new(zone()) ZoneList<Statement*>(8, zone()); |
| if (fvar != NULL) { |