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), | |
546 current_function_state_(NULL), | 545 current_function_state_(NULL), |
547 target_stack_(NULL), | 546 target_stack_(NULL), |
548 extension_(info->extension()), | 547 extension_(info->extension()), |
549 pre_parse_data_(NULL), | 548 pre_parse_data_(NULL), |
550 fni_(NULL), | 549 fni_(NULL), |
551 allow_natives_syntax_(false), | 550 allow_natives_syntax_(false), |
552 allow_lazy_(false), | 551 allow_lazy_(false), |
553 allow_generators_(false), | 552 allow_generators_(false), |
554 allow_for_of_(false), | 553 allow_for_of_(false), |
555 stack_overflow_(false), | 554 stack_overflow_(false), |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); | 615 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); |
617 | 616 |
618 Handle<String> no_name = isolate()->factory()->empty_string(); | 617 Handle<String> no_name = isolate()->factory()->empty_string(); |
619 | 618 |
620 FunctionLiteral* result = NULL; | 619 FunctionLiteral* result = NULL; |
621 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 620 { Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
622 info->SetGlobalScope(scope); | 621 info->SetGlobalScope(scope); |
623 if (!info->context().is_null()) { | 622 if (!info->context().is_null()) { |
624 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 623 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
625 } | 624 } |
626 original_scope_ = scope; | |
627 if (info->is_eval()) { | 625 if (info->is_eval()) { |
628 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { | 626 if (!scope->is_global_scope() || info->language_mode() != CLASSIC_MODE) { |
629 scope = NewScope(scope, EVAL_SCOPE); | 627 scope = NewScope(scope, EVAL_SCOPE); |
630 } | 628 } |
631 } else if (info->is_global()) { | 629 } else if (info->is_global()) { |
632 scope = NewScope(scope, GLOBAL_SCOPE); | 630 scope = NewScope(scope, GLOBAL_SCOPE); |
633 } | 631 } |
634 scope->set_start_position(0); | 632 scope->set_start_position(0); |
635 scope->set_end_position(source->length()); | 633 scope->set_end_position(source->length()); |
636 | 634 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 FunctionLiteral* result = NULL; | 742 FunctionLiteral* result = NULL; |
745 | 743 |
746 { | 744 { |
747 // Parse the function literal. | 745 // Parse the function literal. |
748 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); | 746 Scope* scope = NewScope(top_scope_, GLOBAL_SCOPE); |
749 info()->SetGlobalScope(scope); | 747 info()->SetGlobalScope(scope); |
750 if (!info()->closure().is_null()) { | 748 if (!info()->closure().is_null()) { |
751 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, | 749 scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope, |
752 zone()); | 750 zone()); |
753 } | 751 } |
754 original_scope_ = scope; | |
755 FunctionState function_state(this, scope, isolate()); | 752 FunctionState function_state(this, scope, isolate()); |
756 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); | 753 ASSERT(scope->language_mode() != STRICT_MODE || !info()->is_classic_mode()); |
757 ASSERT(scope->language_mode() != EXTENDED_MODE || | 754 ASSERT(scope->language_mode() != EXTENDED_MODE || |
758 info()->is_extended_mode()); | 755 info()->is_extended_mode()); |
759 ASSERT(info()->language_mode() == shared_info->language_mode()); | 756 ASSERT(info()->language_mode() == shared_info->language_mode()); |
760 scope->SetLanguageMode(shared_info->language_mode()); | 757 scope->SetLanguageMode(shared_info->language_mode()); |
761 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 758 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
762 ? (shared_info->is_anonymous() | 759 ? (shared_info->is_anonymous() |
763 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 760 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
764 : FunctionLiteral::NAMED_EXPRESSION) | 761 : FunctionLiteral::NAMED_EXPRESSION) |
(...skipping 3510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4275 | 4272 |
4276 // We want a non-null handle as the function name. | 4273 // We want a non-null handle as the function name. |
4277 if (should_infer_name) { | 4274 if (should_infer_name) { |
4278 function_name = isolate()->factory()->empty_string(); | 4275 function_name = isolate()->factory()->empty_string(); |
4279 } | 4276 } |
4280 | 4277 |
4281 int num_parameters = 0; | 4278 int num_parameters = 0; |
4282 // Function declarations are function scoped in normal mode, so they are | 4279 // Function declarations are function scoped in normal mode, so they are |
4283 // hoisted. In harmony block scoping mode they are block scoped, so they | 4280 // hoisted. In harmony block scoping mode they are block scoped, so they |
4284 // are not hoisted. | 4281 // 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(); | |
4311 Scope* scope = | 4282 Scope* scope = |
4312 function_type == FunctionLiteral::DECLARATION && !is_extended_mode() && | 4283 (function_type == FunctionLiteral::DECLARATION && !is_extended_mode()) |
4313 (original_scope_ == original_declaration_scope || | 4284 ? NewScope(top_scope_->DeclarationScope(), FUNCTION_SCOPE) |
4314 declaration_scope != original_declaration_scope) | 4285 : NewScope(top_scope_, FUNCTION_SCOPE); |
4315 ? NewScope(declaration_scope, FUNCTION_SCOPE) | |
4316 : NewScope(top_scope_, FUNCTION_SCOPE); | |
4317 ZoneList<Statement*>* body = NULL; | 4286 ZoneList<Statement*>* body = NULL; |
4318 int materialized_literal_count = -1; | 4287 int materialized_literal_count = -1; |
4319 int expected_property_count = -1; | 4288 int expected_property_count = -1; |
4320 int handler_count = 0; | 4289 int handler_count = 0; |
4321 FunctionLiteral::ParameterFlag duplicate_parameters = | 4290 FunctionLiteral::ParameterFlag duplicate_parameters = |
4322 FunctionLiteral::kNoDuplicateParameters; | 4291 FunctionLiteral::kNoDuplicateParameters; |
4323 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | 4292 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ |
4324 ? FunctionLiteral::kIsParenthesized | 4293 ? FunctionLiteral::kIsParenthesized |
4325 : FunctionLiteral::kNotParenthesized; | 4294 : FunctionLiteral::kNotParenthesized; |
4326 FunctionLiteral::IsGeneratorFlag generator = is_generator | 4295 FunctionLiteral::IsGeneratorFlag generator = is_generator |
(...skipping 1637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5964 ASSERT(info()->isolate()->has_pending_exception()); | 5933 ASSERT(info()->isolate()->has_pending_exception()); |
5965 } else { | 5934 } else { |
5966 result = ParseProgram(); | 5935 result = ParseProgram(); |
5967 } | 5936 } |
5968 } | 5937 } |
5969 info()->SetFunction(result); | 5938 info()->SetFunction(result); |
5970 return (result != NULL); | 5939 return (result != NULL); |
5971 } | 5940 } |
5972 | 5941 |
5973 } } // namespace v8::internal | 5942 } } // namespace v8::internal |
OLD | NEW |