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 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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), |
| 545 original_scope_(NULL), |
545 current_function_state_(NULL), | 546 current_function_state_(NULL), |
546 target_stack_(NULL), | 547 target_stack_(NULL), |
547 extension_(info->extension()), | 548 extension_(info->extension()), |
548 pre_parse_data_(NULL), | 549 pre_parse_data_(NULL), |
549 fni_(NULL), | 550 fni_(NULL), |
550 allow_natives_syntax_(false), | 551 allow_natives_syntax_(false), |
551 allow_lazy_(false), | 552 allow_lazy_(false), |
552 allow_generators_(false), | 553 allow_generators_(false), |
553 allow_for_of_(false), | 554 allow_for_of_(false), |
554 stack_overflow_(false), | 555 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(); | 616 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); |
616 | 617 |
617 Handle<String> no_name = isolate()->factory()->empty_string(); | 618 Handle<String> no_name = isolate()->factory()->empty_string(); |
618 | 619 |
619 FunctionLiteral* result = NULL; | 620 FunctionLiteral* result = NULL; |
620 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 621 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
621 info->SetGlobalScope(scope); | 622 info->SetGlobalScope(scope); |
622 if (!info->context().is_null()) { | 623 if (!info->context().is_null()) { |
623 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 624 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
624 } | 625 } |
| 626 original_scope_ = scope; |
625 if (info->is_eval()) { | 627 if (info->is_eval()) { |
626 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { | 628 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { |
627 scope = NewScope(scope, EVAL_SCOPE); | 629 scope = NewScope(scope, EVAL_SCOPE); |
628 } | 630 } |
629 } else if (info->is_global()) { | 631 } else if (info->is_global()) { |
630 scope = NewScope(scope, GLOBAL_SCOPE); | 632 scope = NewScope(scope, GLOBAL_SCOPE); |
631 } | 633 } |
632 scope->set_start_position(0); | 634 scope->set_start_position(0); |
633 scope->set_end_position(source->length()); | 635 scope->set_end_position(source->length()); |
634 | 636 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 FunctionLiteral* result = NULL; | 744 FunctionLiteral* result = NULL; |
743 | 745 |
744 { | 746 { |
745 // Parse the function literal. | 747 // Parse the function literal. |
746 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 748 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
747 info()->SetGlobalScope(scope); | 749 info()->SetGlobalScope(scope); |
748 if (!info()->closure().is_null()) { | 750 if (!info()->closure().is_null()) { |
749 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 751 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
750 zone()); | 752 zone()); |
751 } | 753 } |
| 754 original_scope_ = scope; |
752 FunctionState function_state(this, scope, isolate()); | 755 FunctionState function_state(this, scope, isolate()); |
753 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); | 756 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); |
754 ASSERT(scope->language_mode() != EXTENDED_MODE || | 757 ASSERT(scope->language_mode() != EXTENDED_MODE || |
755 info()->is_extended_mode()); | 758 info()->is_extended_mode()); |
756 ASSERT(info()->language_mode() == shared_info->language_mode()); | 759 ASSERT(info()->language_mode() == shared_info->language_mode()); |
757 scope->SetLanguageMode(shared_info->language_mode()); | 760 scope->SetLanguageMode(shared_info->language_mode()); |
758 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 761 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
759 ? (shared_info->is_anonymous() | 762 ? (shared_info->is_anonymous() |
760 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 763 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
761 : FunctionLiteral::NAMED_EXPRESSION) | 764 : FunctionLiteral::NAMED_EXPRESSION) |
(...skipping 3510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4272 | 4275 |
4273 // We want a non-null handle as the function name. | 4276 // We want a non-null handle as the function name. |
4274 if (should_infer_name) { | 4277 if (should_infer_name) { |
4275 function_name = isolate()->factory()->empty_string(); | 4278 function_name = isolate()->factory()->empty_string(); |
4276 } | 4279 } |
4277 | 4280 |
4278 int num_parameters = 0; | 4281 int num_parameters = 0; |
4279 // Function declarations are function scoped in normal mode, so they are | 4282 // Function declarations are function scoped in normal mode, so they are |
4280 // hoisted. In harmony block scoping mode they are block scoped, so they | 4283 // hoisted. In harmony block scoping mode they are block scoped, so they |
4281 // are not hoisted. | 4284 // are not hoisted. |
| 4285 // |
| 4286 // One tricky case are function declarations in a local sloppy-mode eval: |
| 4287 // their declaration is hoisted, but they still see the local scope. E.g., |
| 4288 // |
| 4289 // function() { |
| 4290 // var x = 0 |
| 4291 // try { throw 1 } catch (x) { eval("function g() { return x }") } |
| 4292 // return g() |
| 4293 // } |
| 4294 // |
| 4295 // needs to return 1. To distinguish such cases, we need to detect |
| 4296 // (1) whether a function stems from a sloppy eval, and |
| 4297 // (2) whether it actually hoists across the eval. |
| 4298 // Unfortunately, we do not represent sloppy eval scopes, so we do not have |
| 4299 // either information available directly, especially not when lazily compiling |
| 4300 // a function like 'g'. We hence rely on the following invariants: |
| 4301 // - (1) is the case iff the innermost scope of the deserialized scope chain |
| 4302 // under which we compile is _not_ a declaration scope. This holds because |
| 4303 // in all normal cases, function declarations are fully hoisted to a |
| 4304 // declaration scope and compiled relative to that. |
| 4305 // - (2) is the case iff the current declaration scope is still the original |
| 4306 // one relative to the deserialized scope chain. Otherwise we must be |
| 4307 // compiling a function in an inner declaration scope in the eval, e.g. a |
| 4308 // nested function, and hoisting works normally relative to that. |
| 4309 Scope* declaration_scope = top_scope_->DeclarationScope(); |
| 4310 Scope* original_declaration_scope = original_scope_->DeclarationScope(); |
4282 Scope* scope = | 4311 Scope* scope = |
4283 (function_type == FunctionLiteral::DECLARATION && !is_extended_mode()) | 4312 function_type == FunctionLiteral::DECLARATION && !is_extended_mode() && |
4284 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) | 4313 (original_scope_ == original_declaration_scope || |
4285 : NewScope(top_scope_, FUNCTION_SCOPE); | 4314 declaration_scope != original_declaration_scope) |
| 4315 ? NewScope(declaration_scope, FUNCTION_SCOPE) |
| 4316 : NewScope(top_scope_, FUNCTION_SCOPE); |
4286 ZoneList<Statement*>* body = NULL; | 4317 ZoneList<Statement*>* body = NULL; |
4287 int materialized_literal_count = -1; | 4318 int materialized_literal_count = -1; |
4288 int expected_property_count = -1; | 4319 int expected_property_count = -1; |
4289 int handler_count = 0; | 4320 int handler_count = 0; |
4290 FunctionLiteral::ParameterFlag duplicate_parameters = | 4321 FunctionLiteral::ParameterFlag duplicate_parameters = |
4291 FunctionLiteral::kNoDuplicateParameters; | 4322 FunctionLiteral::kNoDuplicateParameters; |
4292 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 4323 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
4293 ? FunctionLiteral::kIsParenthesized | 4324 ? FunctionLiteral::kIsParenthesized |
4294 : FunctionLiteral::kNotParenthesized; | 4325 : FunctionLiteral::kNotParenthesized; |
4295 FunctionLiteral::IsGeneratorFlag generator = is_generator | 4326 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()); | 5964 ASSERT(info()->isolate()->has_pending_exception()); |
5934 } else { | 5965 } else { |
5935 result = ParseProgram(); | 5966 result = ParseProgram(); |
5936 } | 5967 } |
5937 } | 5968 } |
5938 info()->SetFunction(result); | 5969 info()->SetFunction(result); |
5939 return (result != NULL); | 5970 return (result != NULL); |
5940 } | 5971 } |
5941 | 5972 |
5942 } } // namespace v8::internal | 5973 } } // namespace v8::internal |
OLD | NEW |