Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 534 | 534 |
| 535 // ---------------------------------------------------------------------------- | 535 // ---------------------------------------------------------------------------- |
| 536 // Implementation of Parser | 536 // Implementation of Parser |
| 537 | 537 |
| 538 Parser::Parser(CompilationInfo* info) | 538 Parser::Parser(CompilationInfo* info) |
| 539 : isolate_(info->isolate()), | 539 : isolate_(info->isolate()), |
| 540 symbol_cache_(0, info->zone()), | 540 symbol_cache_(0, info->zone()), |
| 541 script_(info->script()), | 541 script_(info->script()), |
| 542 scanner_(isolate_->unicode_cache()), | 542 scanner_(isolate_->unicode_cache()), |
| 543 reusable_preparser_(NULL), | 543 reusable_preparser_(NULL), |
| 544 top_scope_(NULL), | 544 top_scope_(NULL), |
|
Michael Starzinger
2013/08/23 08:56:30
Missing initialization of original_scope_(NULL) he
rossberg
2013/08/23 09:09:21
Done.
| |
| 545 current_function_state_(NULL), | 545 current_function_state_(NULL), |
| 546 target_stack_(NULL), | 546 target_stack_(NULL), |
| 547 extension_(info->extension()), | 547 extension_(info->extension()), |
| 548 pre_parse_data_(NULL), | 548 pre_parse_data_(NULL), |
| 549 fni_(NULL), | 549 fni_(NULL), |
| 550 allow_natives_syntax_(false), | 550 allow_natives_syntax_(false), |
| 551 allow_lazy_(false), | 551 allow_lazy_(false), |
| 552 allow_generators_(false), | 552 allow_generators_(false), |
| 553 allow_for_of_(false), | 553 allow_for_of_(false), |
| 554 stack_overflow_(false), | 554 stack_overflow_(false), |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 615 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); | 615 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); |
| 616 | 616 |
| 617 Handle<String> no_name = isolate()->factory()->empty_string(); | 617 Handle<String> no_name = isolate()->factory()->empty_string(); |
| 618 | 618 |
| 619 FunctionLiteral* result = NULL; | 619 FunctionLiteral* result = NULL; |
| 620 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 620 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
| 621 info->SetGlobalScope(scope); | 621 info->SetGlobalScope(scope); |
| 622 if (!info->context().is_null()) { | 622 if (!info->context().is_null()) { |
| 623 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 623 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
| 624 } | 624 } |
| 625 original_scope_ = scope; | |
| 625 if (info->is_eval()) { | 626 if (info->is_eval()) { |
| 626 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { | 627 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { |
| 627 scope = NewScope(scope, EVAL_SCOPE); | 628 scope = NewScope(scope, EVAL_SCOPE); |
| 628 } | 629 } |
| 629 } else if (info->is_global()) { | 630 } else if (info->is_global()) { |
| 630 scope = NewScope(scope, GLOBAL_SCOPE); | 631 scope = NewScope(scope, GLOBAL_SCOPE); |
| 631 } | 632 } |
| 632 scope->set_start_position(0); | 633 scope->set_start_position(0); |
| 633 scope->set_end_position(source->length()); | 634 scope->set_end_position(source->length()); |
| 634 | 635 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 742 FunctionLiteral* result = NULL; | 743 FunctionLiteral* result = NULL; |
| 743 | 744 |
| 744 { | 745 { |
| 745 // Parse the function literal. | 746 // Parse the function literal. |
| 746 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 747 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
| 747 info()->SetGlobalScope(scope); | 748 info()->SetGlobalScope(scope); |
| 748 if (!info()->closure().is_null()) { | 749 if (!info()->closure().is_null()) { |
| 749 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 750 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
| 750 zone()); | 751 zone()); |
| 751 } | 752 } |
| 753 original_scope_ = scope; | |
| 752 FunctionState function_state(this, scope, isolate()); | 754 FunctionState function_state(this, scope, isolate()); |
| 753 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); | 755 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); |
| 754 ASSERT(scope->language_mode() != EXTENDED_MODE || | 756 ASSERT(scope->language_mode() != EXTENDED_MODE || |
| 755 info()->is_extended_mode()); | 757 info()->is_extended_mode()); |
| 756 ASSERT(info()->language_mode() == shared_info->language_mode()); | 758 ASSERT(info()->language_mode() == shared_info->language_mode()); |
| 757 scope->SetLanguageMode(shared_info->language_mode()); | 759 scope->SetLanguageMode(shared_info->language_mode()); |
| 758 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 760 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
| 759 ? (shared_info->is_anonymous() | 761 ? (shared_info->is_anonymous() |
| 760 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 762 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 761 : FunctionLiteral::NAMED_EXPRESSION) | 763 : FunctionLiteral::NAMED_EXPRESSION) |
| (...skipping 3510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4272 | 4274 |
| 4273 // We want a non-null handle as the function name. | 4275 // We want a non-null handle as the function name. |
| 4274 if (should_infer_name) { | 4276 if (should_infer_name) { |
| 4275 function_name = isolate()->factory()->empty_string(); | 4277 function_name = isolate()->factory()->empty_string(); |
| 4276 } | 4278 } |
| 4277 | 4279 |
| 4278 int num_parameters = 0; | 4280 int num_parameters = 0; |
| 4279 // Function declarations are function scoped in normal mode, so they are | 4281 // Function declarations are function scoped in normal mode, so they are |
| 4280 // hoisted. In harmony block scoping mode they are block scoped, so they | 4282 // hoisted. In harmony block scoping mode they are block scoped, so they |
| 4281 // are not hoisted. | 4283 // are not hoisted. |
| 4284 // | |
| 4285 // One tricky case are function declarations in a local sloppy-mode eval: | |
| 4286 // their declaration is hoisted, but they still see the local scope. E.g., | |
| 4287 // | |
| 4288 // function() { | |
| 4289 // var x=0 | |
| 4290 // try {throw 1} catch (x) { eval("function g() { return x }") } | |
|
Michael Starzinger
2013/08/23 08:56:30
nit: A few white spaces missing here and in the li
rossberg
2013/08/23 09:09:21
Done.
| |
| 4291 // return g() | |
| 4292 // } | |
| 4293 // | |
| 4294 // needs to return 1. To distinguish such cases, we need to detect | |
| 4295 // (1) whether a function stems from a sloppy eval, and | |
| 4296 // (2) whether it actually hoists across the eval. | |
| 4297 // Unfortunately, we do not represent sloppy eval scopes, so we do not have | |
| 4298 // either information available directly, especially not when lazily compiling | |
| 4299 // a function like 'g'. We hence rely on the following invariants: | |
| 4300 // - (1) is the case iff the innermost scope of the deserialized scope chain | |
| 4301 // under which we compile is _not_ a declaration scope. This holds because | |
| 4302 // in all normal cases, function declarations are fully hoisted to a | |
| 4303 // declaration scope and compiled relative to that. | |
| 4304 // - (2) is the case iff the current declaration scope is still the original | |
| 4305 // one relative to the deserialized scope chain. Otherwise we must be | |
| 4306 // compiling a function in an inner declaration scope in the eval, e.g. a | |
| 4307 // nested function, and hoisting works normally relative to that. | |
| 4308 Scope* declaration_scope = top_scope_->DeclarationScope(); | |
| 4309 Scope* original_declaration_scope = original_scope_->DeclarationScope(); | |
| 4282 Scope* scope = | 4310 Scope* scope = |
| 4283 (function_type == FunctionLiteral::DECLARATION && !is_extended_mode()) | 4311 function_type == FunctionLiteral::DECLARATION && !is_extended_mode() && |
| 4284 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) | 4312 (original_scope_ == original_declaration_scope || |
| 4285 : NewScope(top_scope_, FUNCTION_SCOPE); | 4313 declaration_scope != original_declaration_scope) |
| 4314 ? NewScope(declaration_scope, FUNCTION_SCOPE) | |
| 4315 : NewScope(top_scope_, FUNCTION_SCOPE); | |
| 4286 ZoneList<Statement*>* body = NULL; | 4316 ZoneList<Statement*>* body = NULL; |
| 4287 int materialized_literal_count = -1; | 4317 int materialized_literal_count = -1; |
| 4288 int expected_property_count = -1; | 4318 int expected_property_count = -1; |
| 4289 int handler_count = 0; | 4319 int handler_count = 0; |
| 4290 FunctionLiteral::ParameterFlag duplicate_parameters = | 4320 FunctionLiteral::ParameterFlag duplicate_parameters = |
| 4291 FunctionLiteral::kNoDuplicateParameters; | 4321 FunctionLiteral::kNoDuplicateParameters; |
| 4292 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 4322 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
| 4293 ? FunctionLiteral::kIsParenthesized | 4323 ? FunctionLiteral::kIsParenthesized |
| 4294 : FunctionLiteral::kNotParenthesized; | 4324 : FunctionLiteral::kNotParenthesized; |
| 4295 FunctionLiteral::IsGeneratorFlag generator = is_generator | 4325 FunctionLiteral::IsGeneratorFlag generator = is_generator |
| (...skipping 1637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5933 ASSERT(info()->isolate()->has_pending_exception()); | 5963 ASSERT(info()->isolate()->has_pending_exception()); |
| 5934 } else { | 5964 } else { |
| 5935 result = ParseProgram(); | 5965 result = ParseProgram(); |
| 5936 } | 5966 } |
| 5937 } | 5967 } |
| 5938 info()->SetFunction(result); | 5968 info()->SetFunction(result); |
| 5939 return (result != NULL); | 5969 return (result != NULL); |
| 5940 } | 5970 } |
| 5941 | 5971 |
| 5942 } } // namespace v8::internal | 5972 } } // namespace v8::internal |
| OLD | NEW |