Chromium Code Reviews| Index: src/parser.cc |
| diff --git a/src/parser.cc b/src/parser.cc |
| index 3bfc94fbd1ac9392d0e2f42726cc5cf4b13882ab..ed6ff493133e54de3a27a2a267a5f2198b0e69e7 100644 |
| --- a/src/parser.cc |
| +++ b/src/parser.cc |
| @@ -3641,7 +3641,10 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, |
| } |
| int num_parameters = 0; |
| - Scope* scope = NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
| + // Function declarations are hoisted. |
| + Scope* scope = (type == DECLARATION) |
| + ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) |
| + : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
| ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); |
| int materialized_literal_count; |
| int expected_property_count; |
| @@ -3715,36 +3718,43 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, |
| RelocInfo::kNoPosition))); |
| } |
| - // Determine if the function will be lazily compiled. The mode can |
| - // only be PARSE_LAZILY if the --lazy flag is true. |
| + // Determine if the function will be lazily compiled. The mode can only |
| + // be PARSE_LAZILY if the --lazy flag is true. We will not lazily |
| + // compile if we do not have preparser data for the function. |
| bool is_lazily_compiled = (mode() == PARSE_LAZILY && |
| top_scope_->outer_scope()->is_global_scope() && |
| top_scope_->HasTrivialOuterContext() && |
| - !parenthesized_function_); |
| + !parenthesized_function_ && |
| + pre_data() != NULL); |
| parenthesized_function_ = false; // The bit was set for this function only. |
| - int function_block_pos = scanner().location().beg_pos; |
| - if (is_lazily_compiled && pre_data() != NULL) { |
| + if (is_lazily_compiled) { |
| + int function_block_pos = scanner().location().beg_pos; |
| FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); |
| if (!entry.is_valid()) { |
| - ReportInvalidPreparseData(name, CHECK_OK); |
| - } |
| - end_pos = entry.end_pos(); |
| - if (end_pos <= function_block_pos) { |
| - // End position greater than end of stream is safe, and hard to check. |
| - ReportInvalidPreparseData(name, CHECK_OK); |
| + // There is no preparser data for the function, we will not lazily |
| + // compile after all. |
| + is_lazily_compiled = false; |
|
Lasse Reichstein
2011/08/03 09:05:17
This handles false positives (from the parser's pe
Kevin Millikin (Chromium)
2011/08/03 09:09:49
Thanks for pointing that out, I hadn't realized it
|
| + } else { |
| + end_pos = entry.end_pos(); |
| + if (end_pos <= function_block_pos) { |
| + // End position greater than end of stream is safe, and hard to check. |
| + ReportInvalidPreparseData(name, CHECK_OK); |
| + } |
| + isolate()->counters()->total_preparse_skipped()->Increment( |
| + end_pos - function_block_pos); |
| + // Seek to position just before terminal '}'. |
| + scanner().SeekForward(end_pos - 1); |
| + materialized_literal_count = entry.literal_count(); |
| + expected_property_count = entry.property_count(); |
| + if (entry.strict_mode()) top_scope_->EnableStrictMode(); |
| + only_simple_this_property_assignments = false; |
| + this_property_assignments = isolate()->factory()->empty_fixed_array(); |
| + Expect(Token::RBRACE, CHECK_OK); |
| } |
| - isolate()->counters()->total_preparse_skipped()->Increment( |
| - end_pos - function_block_pos); |
| - // Seek to position just before terminal '}'. |
| - scanner().SeekForward(end_pos - 1); |
| - materialized_literal_count = entry.literal_count(); |
| - expected_property_count = entry.property_count(); |
| - if (entry.strict_mode()) top_scope_->EnableStrictMode(); |
| - only_simple_this_property_assignments = false; |
| - this_property_assignments = isolate()->factory()->empty_fixed_array(); |
| - Expect(Token::RBRACE, CHECK_OK); |
| - } else { |
| + } |
| + |
| + if (!is_lazily_compiled) { |
| ParseSourceElements(body, Token::RBRACE, CHECK_OK); |
| materialized_literal_count = lexical_scope.materialized_literal_count(); |