| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 scanner_.Initialize(&stream); | 629 scanner_.Initialize(&stream); |
| 630 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); | 630 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope); |
| 631 } | 631 } |
| 632 } | 632 } |
| 633 | 633 |
| 634 | 634 |
| 635 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, | 635 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, |
| 636 bool in_global_context, | 636 bool in_global_context, |
| 637 StrictModeFlag strict_mode, | 637 StrictModeFlag strict_mode, |
| 638 ZoneScope* zone_scope) { | 638 ZoneScope* zone_scope) { |
| 639 ASSERT(top_scope_ == NULL); |
| 639 ASSERT(target_stack_ == NULL); | 640 ASSERT(target_stack_ == NULL); |
| 640 if (pre_data_ != NULL) pre_data_->Initialize(); | 641 if (pre_data_ != NULL) pre_data_->Initialize(); |
| 641 | 642 |
| 642 // Compute the parsing mode. | 643 // Compute the parsing mode. |
| 643 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; | 644 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; |
| 644 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | 645 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; |
| 645 | 646 |
| 646 Scope::Type type = | 647 Scope::Type type = |
| 647 in_global_context | 648 in_global_context |
| 648 ? Scope::GLOBAL_SCOPE | 649 ? Scope::GLOBAL_SCOPE |
| 649 : Scope::EVAL_SCOPE; | 650 : Scope::EVAL_SCOPE; |
| 650 Handle<String> no_name = isolate()->factory()->empty_symbol(); | 651 Handle<String> no_name = isolate()->factory()->empty_symbol(); |
| 651 | 652 |
| 652 FunctionLiteral* result = NULL; | 653 FunctionLiteral* result = NULL; |
| 653 { Scope* scope = NewScope(top_scope_, type); | 654 { Scope* scope = NewScope(top_scope_, type); |
| 654 LexicalScope lexical_scope(this, scope, isolate()); | 655 LexicalScope lexical_scope(this, scope, isolate()); |
| 655 if (strict_mode == kStrictMode) { | 656 ASSERT(top_scope_->strict_mode_flag() == kNonStrictMode); |
| 656 top_scope_->EnableStrictMode(); | 657 top_scope_->SetStrictModeFlag(strict_mode); |
| 657 } | |
| 658 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); | 658 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); |
| 659 bool ok = true; | 659 bool ok = true; |
| 660 int beg_loc = scanner().location().beg_pos; | 660 int beg_loc = scanner().location().beg_pos; |
| 661 ParseSourceElements(body, Token::EOS, &ok); | 661 ParseSourceElements(body, Token::EOS, &ok); |
| 662 if (ok && top_scope_->is_strict_mode()) { | 662 if (ok && top_scope_->is_strict_mode()) { |
| 663 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 663 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 664 } | 664 } |
| 665 | 665 |
| 666 if (ok && harmony_scoping_) { | 666 if (ok && harmony_scoping_) { |
| 667 CheckConflictingVarDeclarations(scope, &ok); | 667 CheckConflictingVarDeclarations(scope, &ok); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 return result; | 720 return result; |
| 721 } | 721 } |
| 722 } | 722 } |
| 723 | 723 |
| 724 | 724 |
| 725 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, | 725 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, |
| 726 UC16CharacterStream* source, | 726 UC16CharacterStream* source, |
| 727 ZoneScope* zone_scope) { | 727 ZoneScope* zone_scope) { |
| 728 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 728 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
| 729 scanner_.Initialize(source); | 729 scanner_.Initialize(source); |
| 730 ASSERT(top_scope_ == NULL); |
| 730 ASSERT(target_stack_ == NULL); | 731 ASSERT(target_stack_ == NULL); |
| 731 | 732 |
| 732 Handle<String> name(String::cast(shared_info->name())); | 733 Handle<String> name(String::cast(shared_info->name())); |
| 733 fni_ = new(zone()) FuncNameInferrer(isolate()); | 734 fni_ = new(zone()) FuncNameInferrer(isolate()); |
| 734 fni_->PushEnclosingName(name); | 735 fni_->PushEnclosingName(name); |
| 735 | 736 |
| 736 mode_ = PARSE_EAGERLY; | 737 mode_ = PARSE_EAGERLY; |
| 737 | 738 |
| 738 // Place holder for the result. | 739 // Place holder for the result. |
| 739 FunctionLiteral* result = NULL; | 740 FunctionLiteral* result = NULL; |
| 740 | 741 |
| 741 { | 742 { |
| 742 // Parse the function literal. | 743 // Parse the function literal. |
| 743 Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE); | 744 Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE); |
| 744 if (!info->closure().is_null()) { | 745 if (!info->closure().is_null()) { |
| 745 scope = Scope::DeserializeScopeChain(info, scope); | 746 scope = Scope::DeserializeScopeChain(info, scope); |
| 746 } | 747 } |
| 747 LexicalScope lexical_scope(this, scope, isolate()); | 748 LexicalScope lexical_scope(this, scope, isolate()); |
| 748 | 749 ASSERT(scope->strict_mode_flag() == kNonStrictMode || |
| 749 if (shared_info->strict_mode()) { | 750 scope->strict_mode_flag() == info->strict_mode_flag()); |
| 750 top_scope_->EnableStrictMode(); | 751 ASSERT(info->strict_mode_flag() == shared_info->strict_mode_flag()); |
| 751 } | 752 scope->SetStrictModeFlag(shared_info->strict_mode_flag()); |
| 752 | |
| 753 FunctionLiteral::Type type = shared_info->is_expression() | 753 FunctionLiteral::Type type = shared_info->is_expression() |
| 754 ? (shared_info->is_anonymous() | 754 ? (shared_info->is_anonymous() |
| 755 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 755 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 756 : FunctionLiteral::NAMED_EXPRESSION) | 756 : FunctionLiteral::NAMED_EXPRESSION) |
| 757 : FunctionLiteral::DECLARATION; | 757 : FunctionLiteral::DECLARATION; |
| 758 bool ok = true; | 758 bool ok = true; |
| 759 result = ParseFunctionLiteral(name, | 759 result = ParseFunctionLiteral(name, |
| 760 false, // Strict mode name already checked. | 760 false, // Strict mode name already checked. |
| 761 RelocInfo::kNoPosition, | 761 RelocInfo::kNoPosition, |
| 762 type, | 762 type, |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1189 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 1189 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 1190 (literal = e_stat->expression()->AsLiteral()) != NULL && | 1190 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 1191 literal->handle()->IsString()) { | 1191 literal->handle()->IsString()) { |
| 1192 Handle<String> directive = Handle<String>::cast(literal->handle()); | 1192 Handle<String> directive = Handle<String>::cast(literal->handle()); |
| 1193 | 1193 |
| 1194 // Check "use strict" directive (ES5 14.1). | 1194 // Check "use strict" directive (ES5 14.1). |
| 1195 if (!top_scope_->is_strict_mode() && | 1195 if (!top_scope_->is_strict_mode() && |
| 1196 directive->Equals(isolate()->heap()->use_strict()) && | 1196 directive->Equals(isolate()->heap()->use_strict()) && |
| 1197 token_loc.end_pos - token_loc.beg_pos == | 1197 token_loc.end_pos - token_loc.beg_pos == |
| 1198 isolate()->heap()->use_strict()->length() + 2) { | 1198 isolate()->heap()->use_strict()->length() + 2) { |
| 1199 top_scope_->EnableStrictMode(); | 1199 top_scope_->SetStrictModeFlag(kStrictMode); |
| 1200 // "use strict" is the only directive for now. | 1200 // "use strict" is the only directive for now. |
| 1201 directive_prologue = false; | 1201 directive_prologue = false; |
| 1202 } | 1202 } |
| 1203 } else { | 1203 } else { |
| 1204 // End of the directive prologue. | 1204 // End of the directive prologue. |
| 1205 directive_prologue = false; | 1205 directive_prologue = false; |
| 1206 } | 1206 } |
| 1207 } | 1207 } |
| 1208 | 1208 |
| 1209 block_finder.Update(stat); | 1209 block_finder.Update(stat); |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1589 | 1589 |
| 1590 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { | 1590 Block* Parser::ParseScopedBlock(ZoneStringList* labels, bool* ok) { |
| 1591 // The harmony mode uses source elements instead of statements. | 1591 // The harmony mode uses source elements instead of statements. |
| 1592 // | 1592 // |
| 1593 // Block :: | 1593 // Block :: |
| 1594 // '{' SourceElement* '}' | 1594 // '{' SourceElement* '}' |
| 1595 | 1595 |
| 1596 // Construct block expecting 16 statements. | 1596 // Construct block expecting 16 statements. |
| 1597 Block* body = new(zone()) Block(isolate(), labels, 16, false); | 1597 Block* body = new(zone()) Block(isolate(), labels, 16, false); |
| 1598 Scope* block_scope = NewScope(top_scope_, Scope::BLOCK_SCOPE); | 1598 Scope* block_scope = NewScope(top_scope_, Scope::BLOCK_SCOPE); |
| 1599 if (top_scope_->is_strict_mode()) { | |
| 1600 block_scope->EnableStrictMode(); | |
| 1601 } | |
| 1602 | 1599 |
| 1603 // Parse the statements and collect escaping labels. | 1600 // Parse the statements and collect escaping labels. |
| 1604 Expect(Token::LBRACE, CHECK_OK); | 1601 Expect(Token::LBRACE, CHECK_OK); |
| 1605 { SaveScope save_scope(this, block_scope); | 1602 { SaveScope save_scope(this, block_scope); |
| 1606 TargetCollector collector; | 1603 TargetCollector collector; |
| 1607 Target target(&this->target_stack_, &collector); | 1604 Target target(&this->target_stack_, &collector); |
| 1608 Target target_body(&this->target_stack_, body); | 1605 Target target_body(&this->target_stack_, body); |
| 1609 InitializationBlockFinder block_finder(top_scope_, target_stack_); | 1606 InitializationBlockFinder block_finder(top_scope_, target_stack_); |
| 1610 | 1607 |
| 1611 while (peek() != Token::RBRACE) { | 1608 while (peek() != Token::RBRACE) { |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1837 // the number of arguments (1 or 2). | 1834 // the number of arguments (1 or 2). |
| 1838 initialize = | 1835 initialize = |
| 1839 new(zone()) CallRuntime( | 1836 new(zone()) CallRuntime( |
| 1840 isolate(), | 1837 isolate(), |
| 1841 isolate()->factory()->InitializeConstGlobal_symbol(), | 1838 isolate()->factory()->InitializeConstGlobal_symbol(), |
| 1842 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), | 1839 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
| 1843 arguments); | 1840 arguments); |
| 1844 } else { | 1841 } else { |
| 1845 // Add strict mode. | 1842 // Add strict mode. |
| 1846 // We may want to pass singleton to avoid Literal allocations. | 1843 // We may want to pass singleton to avoid Literal allocations. |
| 1847 StrictModeFlag flag = initialization_scope->is_strict_mode() | 1844 StrictModeFlag flag = initialization_scope->strict_mode_flag(); |
| 1848 ? kStrictMode | |
| 1849 : kNonStrictMode; | |
| 1850 arguments->Add(NewNumberLiteral(flag)); | 1845 arguments->Add(NewNumberLiteral(flag)); |
| 1851 | 1846 |
| 1852 // Be careful not to assign a value to the global variable if | 1847 // Be careful not to assign a value to the global variable if |
| 1853 // we're in a with. The initialization value should not | 1848 // we're in a with. The initialization value should not |
| 1854 // necessarily be stored in the global object in that case, | 1849 // necessarily be stored in the global object in that case, |
| 1855 // which is why we need to generate a separate assignment node. | 1850 // which is why we need to generate a separate assignment node. |
| 1856 if (value != NULL && !inside_with()) { | 1851 if (value != NULL && !inside_with()) { |
| 1857 arguments->Add(value); | 1852 arguments->Add(value); |
| 1858 value = NULL; // zap the value to avoid the unnecessary assignment | 1853 value = NULL; // zap the value to avoid the unnecessary assignment |
| 1859 } | 1854 } |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2249 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); | 2244 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); |
| 2250 *ok = false; | 2245 *ok = false; |
| 2251 return NULL; | 2246 return NULL; |
| 2252 } | 2247 } |
| 2253 | 2248 |
| 2254 Expect(Token::RPAREN, CHECK_OK); | 2249 Expect(Token::RPAREN, CHECK_OK); |
| 2255 | 2250 |
| 2256 if (peek() == Token::LBRACE) { | 2251 if (peek() == Token::LBRACE) { |
| 2257 Target target(&this->target_stack_, &catch_collector); | 2252 Target target(&this->target_stack_, &catch_collector); |
| 2258 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE); | 2253 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE); |
| 2259 if (top_scope_->is_strict_mode()) { | |
| 2260 catch_scope->EnableStrictMode(); | |
| 2261 } | |
| 2262 VariableMode mode = harmony_scoping_ ? LET : VAR; | 2254 VariableMode mode = harmony_scoping_ ? LET : VAR; |
| 2263 catch_variable = catch_scope->DeclareLocal(name, mode); | 2255 catch_variable = catch_scope->DeclareLocal(name, mode); |
| 2264 | 2256 |
| 2265 SaveScope save_scope(this, catch_scope); | 2257 SaveScope save_scope(this, catch_scope); |
| 2266 catch_block = ParseBlock(NULL, CHECK_OK); | 2258 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2267 } else { | 2259 } else { |
| 2268 Expect(Token::LBRACE, CHECK_OK); | 2260 Expect(Token::LBRACE, CHECK_OK); |
| 2269 } | 2261 } |
| 2270 | 2262 |
| 2271 tok = peek(); | 2263 tok = peek(); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2369 | 2361 |
| 2370 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { | 2362 Statement* Parser::ParseForStatement(ZoneStringList* labels, bool* ok) { |
| 2371 // ForStatement :: | 2363 // ForStatement :: |
| 2372 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement | 2364 // 'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement |
| 2373 | 2365 |
| 2374 Statement* init = NULL; | 2366 Statement* init = NULL; |
| 2375 | 2367 |
| 2376 // Create an in-between scope for let-bound iteration variables. | 2368 // Create an in-between scope for let-bound iteration variables. |
| 2377 Scope* saved_scope = top_scope_; | 2369 Scope* saved_scope = top_scope_; |
| 2378 Scope* for_scope = NewScope(top_scope_, Scope::BLOCK_SCOPE); | 2370 Scope* for_scope = NewScope(top_scope_, Scope::BLOCK_SCOPE); |
| 2379 if (top_scope_->is_strict_mode()) { | |
| 2380 for_scope->EnableStrictMode(); | |
| 2381 } | |
| 2382 top_scope_ = for_scope; | 2371 top_scope_ = for_scope; |
| 2383 | 2372 |
| 2384 Expect(Token::FOR, CHECK_OK); | 2373 Expect(Token::FOR, CHECK_OK); |
| 2385 Expect(Token::LPAREN, CHECK_OK); | 2374 Expect(Token::LPAREN, CHECK_OK); |
| 2386 if (peek() != Token::SEMICOLON) { | 2375 if (peek() != Token::SEMICOLON) { |
| 2387 if (peek() == Token::VAR || peek() == Token::CONST) { | 2376 if (peek() == Token::VAR || peek() == Token::CONST) { |
| 2388 Handle<String> name; | 2377 Handle<String> name; |
| 2389 Block* variable_statement = | 2378 Block* variable_statement = |
| 2390 ParseVariableDeclarations(kForStatement, NULL, &name, CHECK_OK); | 2379 ParseVariableDeclarations(kForStatement, NULL, &name, CHECK_OK); |
| 2391 | 2380 |
| (...skipping 1576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3968 if (end_pos <= function_block_pos) { | 3957 if (end_pos <= function_block_pos) { |
| 3969 // End position greater than end of stream is safe, and hard to check. | 3958 // End position greater than end of stream is safe, and hard to check. |
| 3970 ReportInvalidPreparseData(function_name, CHECK_OK); | 3959 ReportInvalidPreparseData(function_name, CHECK_OK); |
| 3971 } | 3960 } |
| 3972 isolate()->counters()->total_preparse_skipped()->Increment( | 3961 isolate()->counters()->total_preparse_skipped()->Increment( |
| 3973 end_pos - function_block_pos); | 3962 end_pos - function_block_pos); |
| 3974 // Seek to position just before terminal '}'. | 3963 // Seek to position just before terminal '}'. |
| 3975 scanner().SeekForward(end_pos - 1); | 3964 scanner().SeekForward(end_pos - 1); |
| 3976 materialized_literal_count = entry.literal_count(); | 3965 materialized_literal_count = entry.literal_count(); |
| 3977 expected_property_count = entry.property_count(); | 3966 expected_property_count = entry.property_count(); |
| 3978 if (entry.strict_mode()) top_scope_->EnableStrictMode(); | 3967 if (entry.strict_mode()) top_scope_->SetStrictModeFlag(kStrictMode); |
| 3979 only_simple_this_property_assignments = false; | 3968 only_simple_this_property_assignments = false; |
| 3980 this_property_assignments = isolate()->factory()->empty_fixed_array(); | 3969 this_property_assignments = isolate()->factory()->empty_fixed_array(); |
| 3981 Expect(Token::RBRACE, CHECK_OK); | 3970 Expect(Token::RBRACE, CHECK_OK); |
| 3982 } | 3971 } |
| 3983 } | 3972 } |
| 3984 | 3973 |
| 3985 if (!is_lazily_compiled) { | 3974 if (!is_lazily_compiled) { |
| 3986 ParseSourceElements(body, Token::RBRACE, CHECK_OK); | 3975 ParseSourceElements(body, Token::RBRACE, CHECK_OK); |
| 3987 | 3976 |
| 3988 materialized_literal_count = lexical_scope.materialized_literal_count(); | 3977 materialized_literal_count = lexical_scope.materialized_literal_count(); |
| (...skipping 1389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5378 DeleteArray(message); | 5367 DeleteArray(message); |
| 5379 for (int i = 0; i < args.length(); i++) { | 5368 for (int i = 0; i < args.length(); i++) { |
| 5380 DeleteArray(args[i]); | 5369 DeleteArray(args[i]); |
| 5381 } | 5370 } |
| 5382 DeleteArray(args.start()); | 5371 DeleteArray(args.start()); |
| 5383 ASSERT(info->isolate()->has_pending_exception()); | 5372 ASSERT(info->isolate()->has_pending_exception()); |
| 5384 } else { | 5373 } else { |
| 5385 Handle<String> source = Handle<String>(String::cast(script->source())); | 5374 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 5386 result = parser.ParseProgram(source, | 5375 result = parser.ParseProgram(source, |
| 5387 info->is_global(), | 5376 info->is_global(), |
| 5388 info->StrictMode()); | 5377 info->strict_mode_flag()); |
| 5389 } | 5378 } |
| 5390 } | 5379 } |
| 5391 info->SetFunction(result); | 5380 info->SetFunction(result); |
| 5392 return (result != NULL); | 5381 return (result != NULL); |
| 5393 } | 5382 } |
| 5394 | 5383 |
| 5395 } } // namespace v8::internal | 5384 } } // namespace v8::internal |
| OLD | NEW |