| 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 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 top_scope_(NULL), | 580 top_scope_(NULL), |
| 581 with_nesting_level_(0), | 581 with_nesting_level_(0), |
| 582 lexical_scope_(NULL), | 582 lexical_scope_(NULL), |
| 583 target_stack_(NULL), | 583 target_stack_(NULL), |
| 584 allow_natives_syntax_(allow_natives_syntax), | 584 allow_natives_syntax_(allow_natives_syntax), |
| 585 extension_(extension), | 585 extension_(extension), |
| 586 pre_data_(pre_data), | 586 pre_data_(pre_data), |
| 587 fni_(NULL), | 587 fni_(NULL), |
| 588 stack_overflow_(false), | 588 stack_overflow_(false), |
| 589 parenthesized_function_(false), | 589 parenthesized_function_(false), |
| 590 harmony_block_scoping_(false) { | 590 harmony_scoping_(false) { |
| 591 AstNode::ResetIds(); | 591 AstNode::ResetIds(); |
| 592 } | 592 } |
| 593 | 593 |
| 594 | 594 |
| 595 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 595 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
| 596 bool in_global_context, | 596 bool in_global_context, |
| 597 StrictModeFlag strict_mode) { | 597 StrictModeFlag strict_mode) { |
| 598 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); | 598 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); |
| 599 | 599 |
| 600 HistogramTimerScope timer(isolate()->counters()->parse()); | 600 HistogramTimerScope timer(isolate()->counters()->parse()); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 top_scope_->EnableStrictMode(); | 643 top_scope_->EnableStrictMode(); |
| 644 } | 644 } |
| 645 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); | 645 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16); |
| 646 bool ok = true; | 646 bool ok = true; |
| 647 int beg_loc = scanner().location().beg_pos; | 647 int beg_loc = scanner().location().beg_pos; |
| 648 ParseSourceElements(body, Token::EOS, &ok); | 648 ParseSourceElements(body, Token::EOS, &ok); |
| 649 if (ok && top_scope_->is_strict_mode()) { | 649 if (ok && top_scope_->is_strict_mode()) { |
| 650 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 650 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 651 } | 651 } |
| 652 | 652 |
| 653 if (ok && harmony_block_scoping_) { | 653 if (ok && harmony_scoping_) { |
| 654 CheckConflictingVarDeclarations(scope, &ok); | 654 CheckConflictingVarDeclarations(scope, &ok); |
| 655 } | 655 } |
| 656 | 656 |
| 657 if (ok) { | 657 if (ok) { |
| 658 result = new(zone()) FunctionLiteral( | 658 result = new(zone()) FunctionLiteral( |
| 659 isolate(), | 659 isolate(), |
| 660 no_name, | 660 no_name, |
| 661 top_scope_, | 661 top_scope_, |
| 662 body, | 662 body, |
| 663 lexical_scope.materialized_literal_count(), | 663 lexical_scope.materialized_literal_count(), |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 Factory* factory = isolate()->factory(); | 810 Factory* factory = isolate()->factory(); |
| 811 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); | 811 Handle<FixedArray> elements = factory->NewFixedArray(args.length()); |
| 812 for (int i = 0; i < args.length(); i++) { | 812 for (int i = 0; i < args.length(); i++) { |
| 813 elements->set(i, *args[i]); | 813 elements->set(i, *args[i]); |
| 814 } | 814 } |
| 815 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 815 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
| 816 Handle<Object> result = factory->NewSyntaxError(type, array); | 816 Handle<Object> result = factory->NewSyntaxError(type, array); |
| 817 isolate()->Throw(*result, &location); | 817 isolate()->Throw(*result, &location); |
| 818 } | 818 } |
| 819 | 819 |
| 820 void Parser::SetHarmonyBlockScoping(bool block_scoping) { | 820 void Parser::SetHarmonyScoping(bool block_scoping) { |
| 821 scanner().SetHarmonyBlockScoping(block_scoping); | 821 scanner().SetHarmonyScoping(block_scoping); |
| 822 harmony_block_scoping_ = block_scoping; | 822 harmony_scoping_ = block_scoping; |
| 823 } | 823 } |
| 824 | 824 |
| 825 // Base class containing common code for the different finder classes used by | 825 // Base class containing common code for the different finder classes used by |
| 826 // the parser. | 826 // the parser. |
| 827 class ParserFinder { | 827 class ParserFinder { |
| 828 protected: | 828 protected: |
| 829 ParserFinder() {} | 829 ParserFinder() {} |
| 830 static Assignment* AsAssignment(Statement* stat) { | 830 static Assignment* AsAssignment(Statement* stat) { |
| 831 if (stat == NULL) return NULL; | 831 if (stat == NULL) return NULL; |
| 832 ExpressionStatement* exp_stat = stat->AsExpressionStatement(); | 832 ExpressionStatement* exp_stat = stat->AsExpressionStatement(); |
| (...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1383 // | 1383 // |
| 1384 // function () { let x; { var x; } } | 1384 // function () { let x; { var x; } } |
| 1385 // | 1385 // |
| 1386 // because the var declaration is hoisted to the function scope where 'x' | 1386 // because the var declaration is hoisted to the function scope where 'x' |
| 1387 // is already bound. | 1387 // is already bound. |
| 1388 if ((mode != VAR) || (var->mode() != VAR)) { | 1388 if ((mode != VAR) || (var->mode() != VAR)) { |
| 1389 // We only have vars, consts and lets in declarations. | 1389 // We only have vars, consts and lets in declarations. |
| 1390 ASSERT(var->mode() == VAR || | 1390 ASSERT(var->mode() == VAR || |
| 1391 var->mode() == CONST || | 1391 var->mode() == CONST || |
| 1392 var->mode() == LET); | 1392 var->mode() == LET); |
| 1393 if (harmony_block_scoping_) { | 1393 if (harmony_scoping_) { |
| 1394 // In harmony mode we treat re-declarations as early errors. See | 1394 // In harmony mode we treat re-declarations as early errors. See |
| 1395 // ES5 16 for a definition of early errors. | 1395 // ES5 16 for a definition of early errors. |
| 1396 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 1396 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 1397 const char* elms[2] = { "Variable", *c_string }; | 1397 const char* elms[2] = { "Variable", *c_string }; |
| 1398 Vector<const char*> args(elms, 2); | 1398 Vector<const char*> args(elms, 2); |
| 1399 ReportMessage("redeclaration", args); | 1399 ReportMessage("redeclaration", args); |
| 1400 *ok = false; | 1400 *ok = false; |
| 1401 return NULL; | 1401 return NULL; |
| 1402 } | 1402 } |
| 1403 const char* type = (var->mode() == VAR) ? "var" : | 1403 const char* type = (var->mode() == VAR) ? "var" : |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1535 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1535 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
| 1536 &is_strict_reserved, CHECK_OK); | 1536 &is_strict_reserved, CHECK_OK); |
| 1537 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1537 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1538 is_strict_reserved, | 1538 is_strict_reserved, |
| 1539 function_token_position, | 1539 function_token_position, |
| 1540 FunctionLiteral::DECLARATION, | 1540 FunctionLiteral::DECLARATION, |
| 1541 CHECK_OK); | 1541 CHECK_OK); |
| 1542 // Even if we're not at the top-level of the global or a function | 1542 // Even if we're not at the top-level of the global or a function |
| 1543 // scope, we treat is as such and introduce the function with it's | 1543 // scope, we treat is as such and introduce the function with it's |
| 1544 // initial value upon entering the corresponding scope. | 1544 // initial value upon entering the corresponding scope. |
| 1545 VariableMode mode = harmony_block_scoping_ ? LET : VAR; | 1545 VariableMode mode = harmony_scoping_ ? LET : VAR; |
| 1546 Declare(name, mode, fun, true, CHECK_OK); | 1546 Declare(name, mode, fun, true, CHECK_OK); |
| 1547 return EmptyStatement(); | 1547 return EmptyStatement(); |
| 1548 } | 1548 } |
| 1549 | 1549 |
| 1550 | 1550 |
| 1551 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { | 1551 Block* Parser::ParseBlock(ZoneStringList* labels, bool* ok) { |
| 1552 if (harmony_block_scoping_) return ParseScopedBlock(labels, ok); | 1552 if (harmony_scoping_) return ParseScopedBlock(labels, ok); |
| 1553 | 1553 |
| 1554 // Block :: | 1554 // Block :: |
| 1555 // '{' Statement* '}' | 1555 // '{' Statement* '}' |
| 1556 | 1556 |
| 1557 // Note that a Block does not introduce a new execution scope! | 1557 // Note that a Block does not introduce a new execution scope! |
| 1558 // (ECMA-262, 3rd, 12.2) | 1558 // (ECMA-262, 3rd, 12.2) |
| 1559 // | 1559 // |
| 1560 // Construct block expecting 16 statements. | 1560 // Construct block expecting 16 statements. |
| 1561 Block* result = new(zone()) Block(isolate(), labels, 16, false); | 1561 Block* result = new(zone()) Block(isolate(), labels, 16, false); |
| 1562 Target target(&this->target_stack_, result); | 1562 Target target(&this->target_stack_, result); |
| (...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2242 } | 2242 } |
| 2243 | 2243 |
| 2244 Expect(Token::RPAREN, CHECK_OK); | 2244 Expect(Token::RPAREN, CHECK_OK); |
| 2245 | 2245 |
| 2246 if (peek() == Token::LBRACE) { | 2246 if (peek() == Token::LBRACE) { |
| 2247 Target target(&this->target_stack_, &catch_collector); | 2247 Target target(&this->target_stack_, &catch_collector); |
| 2248 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); | 2248 catch_scope = NewScope(top_scope_, Scope::CATCH_SCOPE, inside_with()); |
| 2249 if (top_scope_->is_strict_mode()) { | 2249 if (top_scope_->is_strict_mode()) { |
| 2250 catch_scope->EnableStrictMode(); | 2250 catch_scope->EnableStrictMode(); |
| 2251 } | 2251 } |
| 2252 VariableMode mode = harmony_block_scoping_ ? LET : VAR; | 2252 VariableMode mode = harmony_scoping_ ? LET : VAR; |
| 2253 catch_variable = catch_scope->DeclareLocal(name, mode); | 2253 catch_variable = catch_scope->DeclareLocal(name, mode); |
| 2254 | 2254 |
| 2255 Scope* saved_scope = top_scope_; | 2255 Scope* saved_scope = top_scope_; |
| 2256 top_scope_ = catch_scope; | 2256 top_scope_ = catch_scope; |
| 2257 catch_block = ParseBlock(NULL, CHECK_OK); | 2257 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2258 top_scope_ = saved_scope; | 2258 top_scope_ = saved_scope; |
| 2259 } else { | 2259 } else { |
| 2260 Expect(Token::LBRACE, CHECK_OK); | 2260 Expect(Token::LBRACE, CHECK_OK); |
| 2261 } | 2261 } |
| 2262 | 2262 |
| (...skipping 1444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3707 | 3707 |
| 3708 // We want a non-null handle as the function name. | 3708 // We want a non-null handle as the function name. |
| 3709 if (should_infer_name) { | 3709 if (should_infer_name) { |
| 3710 function_name = isolate()->factory()->empty_symbol(); | 3710 function_name = isolate()->factory()->empty_symbol(); |
| 3711 } | 3711 } |
| 3712 | 3712 |
| 3713 int num_parameters = 0; | 3713 int num_parameters = 0; |
| 3714 // Function declarations are function scoped in normal mode, so they are | 3714 // Function declarations are function scoped in normal mode, so they are |
| 3715 // hoisted. In harmony block scoping mode they are block scoped, so they | 3715 // hoisted. In harmony block scoping mode they are block scoped, so they |
| 3716 // are not hoisted. | 3716 // are not hoisted. |
| 3717 Scope* scope = (type == FunctionLiteral::DECLARATION && | 3717 Scope* scope = (type == FunctionLiteral::DECLARATION && !harmony_scoping_) |
| 3718 !harmony_block_scoping_) | |
| 3719 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) | 3718 ? NewScope(top_scope_->DeclarationScope(), Scope::FUNCTION_SCOPE, false) |
| 3720 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); | 3719 : NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); |
| 3721 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); | 3720 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(8); |
| 3722 int materialized_literal_count; | 3721 int materialized_literal_count; |
| 3723 int expected_property_count; | 3722 int expected_property_count; |
| 3724 int start_pos; | 3723 int start_pos; |
| 3725 int end_pos; | 3724 int end_pos; |
| 3726 bool only_simple_this_property_assignments; | 3725 bool only_simple_this_property_assignments; |
| 3727 Handle<FixedArray> this_property_assignments; | 3726 Handle<FixedArray> this_property_assignments; |
| 3728 bool has_duplicate_parameters = false; | 3727 bool has_duplicate_parameters = false; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3750 name_loc = scanner().location(); | 3749 name_loc = scanner().location(); |
| 3751 } | 3750 } |
| 3752 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { | 3751 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { |
| 3753 has_duplicate_parameters = true; | 3752 has_duplicate_parameters = true; |
| 3754 dupe_loc = scanner().location(); | 3753 dupe_loc = scanner().location(); |
| 3755 } | 3754 } |
| 3756 if (!reserved_loc.IsValid() && is_strict_reserved) { | 3755 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 3757 reserved_loc = scanner().location(); | 3756 reserved_loc = scanner().location(); |
| 3758 } | 3757 } |
| 3759 | 3758 |
| 3760 top_scope_->DeclareParameter(param_name, | 3759 top_scope_->DeclareParameter(param_name, harmony_scoping_ ? LET : VAR); |
| 3761 harmony_block_scoping_ ? LET : VAR); | |
| 3762 num_parameters++; | 3760 num_parameters++; |
| 3763 if (num_parameters > kMaxNumFunctionParameters) { | 3761 if (num_parameters > kMaxNumFunctionParameters) { |
| 3764 ReportMessageAt(scanner().location(), "too_many_parameters", | 3762 ReportMessageAt(scanner().location(), "too_many_parameters", |
| 3765 Vector<const char*>::empty()); | 3763 Vector<const char*>::empty()); |
| 3766 *ok = false; | 3764 *ok = false; |
| 3767 return NULL; | 3765 return NULL; |
| 3768 } | 3766 } |
| 3769 done = (peek() == Token::RPAREN); | 3767 done = (peek() == Token::RPAREN); |
| 3770 if (!done) Expect(Token::COMMA, CHECK_OK); | 3768 if (!done) Expect(Token::COMMA, CHECK_OK); |
| 3771 } | 3769 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3878 if (reserved_loc.IsValid()) { | 3876 if (reserved_loc.IsValid()) { |
| 3879 ReportMessageAt(reserved_loc, "strict_reserved_word", | 3877 ReportMessageAt(reserved_loc, "strict_reserved_word", |
| 3880 Vector<const char*>::empty()); | 3878 Vector<const char*>::empty()); |
| 3881 *ok = false; | 3879 *ok = false; |
| 3882 return NULL; | 3880 return NULL; |
| 3883 } | 3881 } |
| 3884 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); | 3882 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); |
| 3885 } | 3883 } |
| 3886 } | 3884 } |
| 3887 | 3885 |
| 3888 if (harmony_block_scoping_) { | 3886 if (harmony_scoping_) { |
| 3889 CheckConflictingVarDeclarations(scope, CHECK_OK); | 3887 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 3890 } | 3888 } |
| 3891 | 3889 |
| 3892 FunctionLiteral* function_literal = | 3890 FunctionLiteral* function_literal = |
| 3893 new(zone()) FunctionLiteral(isolate(), | 3891 new(zone()) FunctionLiteral(isolate(), |
| 3894 function_name, | 3892 function_name, |
| 3895 scope, | 3893 scope, |
| 3896 body, | 3894 body, |
| 3897 materialized_literal_count, | 3895 materialized_literal_count, |
| 3898 expected_property_count, | 3896 expected_property_count, |
| (...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5116 } | 5114 } |
| 5117 *source = data; | 5115 *source = data; |
| 5118 return result; | 5116 return result; |
| 5119 } | 5117 } |
| 5120 | 5118 |
| 5121 | 5119 |
| 5122 // Create a Scanner for the preparser to use as input, and preparse the source. | 5120 // Create a Scanner for the preparser to use as input, and preparse the source. |
| 5123 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, | 5121 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, |
| 5124 bool allow_lazy, | 5122 bool allow_lazy, |
| 5125 ParserRecorder* recorder, | 5123 ParserRecorder* recorder, |
| 5126 bool harmony_block_scoping) { | 5124 bool harmony_scoping) { |
| 5127 Isolate* isolate = Isolate::Current(); | 5125 Isolate* isolate = Isolate::Current(); |
| 5128 JavaScriptScanner scanner(isolate->unicode_cache()); | 5126 JavaScriptScanner scanner(isolate->unicode_cache()); |
| 5129 scanner.SetHarmonyBlockScoping(harmony_block_scoping); | 5127 scanner.SetHarmonyScoping(harmony_scoping); |
| 5130 scanner.Initialize(source); | 5128 scanner.Initialize(source); |
| 5131 intptr_t stack_limit = isolate->stack_guard()->real_climit(); | 5129 intptr_t stack_limit = isolate->stack_guard()->real_climit(); |
| 5132 if (!preparser::PreParser::PreParseProgram(&scanner, | 5130 if (!preparser::PreParser::PreParseProgram(&scanner, |
| 5133 recorder, | 5131 recorder, |
| 5134 allow_lazy, | 5132 allow_lazy, |
| 5135 stack_limit)) { | 5133 stack_limit)) { |
| 5136 isolate->StackOverflow(); | 5134 isolate->StackOverflow(); |
| 5137 return NULL; | 5135 return NULL; |
| 5138 } | 5136 } |
| 5139 | 5137 |
| 5140 // Extract the accumulated data from the recorder as a single | 5138 // Extract the accumulated data from the recorder as a single |
| 5141 // contiguous vector that we are responsible for disposing. | 5139 // contiguous vector that we are responsible for disposing. |
| 5142 Vector<unsigned> store = recorder->ExtractData(); | 5140 Vector<unsigned> store = recorder->ExtractData(); |
| 5143 return new ScriptDataImpl(store); | 5141 return new ScriptDataImpl(store); |
| 5144 } | 5142 } |
| 5145 | 5143 |
| 5146 | 5144 |
| 5147 // Preparse, but only collect data that is immediately useful, | 5145 // Preparse, but only collect data that is immediately useful, |
| 5148 // even if the preparser data is only used once. | 5146 // even if the preparser data is only used once. |
| 5149 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, | 5147 ScriptDataImpl* ParserApi::PartialPreParse(UC16CharacterStream* source, |
| 5150 v8::Extension* extension, | 5148 v8::Extension* extension, |
| 5151 bool harmony_block_scoping) { | 5149 bool harmony_scoping) { |
| 5152 bool allow_lazy = FLAG_lazy && (extension == NULL); | 5150 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 5153 if (!allow_lazy) { | 5151 if (!allow_lazy) { |
| 5154 // Partial preparsing is only about lazily compiled functions. | 5152 // Partial preparsing is only about lazily compiled functions. |
| 5155 // If we don't allow lazy compilation, the log data will be empty. | 5153 // If we don't allow lazy compilation, the log data will be empty. |
| 5156 return NULL; | 5154 return NULL; |
| 5157 } | 5155 } |
| 5158 PartialParserRecorder recorder; | 5156 PartialParserRecorder recorder; |
| 5159 return DoPreParse(source, allow_lazy, &recorder, harmony_block_scoping); | 5157 return DoPreParse(source, allow_lazy, &recorder, harmony_scoping); |
| 5160 } | 5158 } |
| 5161 | 5159 |
| 5162 | 5160 |
| 5163 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, | 5161 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, |
| 5164 v8::Extension* extension, | 5162 v8::Extension* extension, |
| 5165 bool harmony_block_scoping) { | 5163 bool harmony_scoping) { |
| 5166 Handle<Script> no_script; | 5164 Handle<Script> no_script; |
| 5167 bool allow_lazy = FLAG_lazy && (extension == NULL); | 5165 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 5168 CompleteParserRecorder recorder; | 5166 CompleteParserRecorder recorder; |
| 5169 return DoPreParse(source, allow_lazy, &recorder, harmony_block_scoping); | 5167 return DoPreParse(source, allow_lazy, &recorder, harmony_scoping); |
| 5170 } | 5168 } |
| 5171 | 5169 |
| 5172 | 5170 |
| 5173 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 5171 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
| 5174 bool multiline, | 5172 bool multiline, |
| 5175 RegExpCompileData* result) { | 5173 RegExpCompileData* result) { |
| 5176 ASSERT(result != NULL); | 5174 ASSERT(result != NULL); |
| 5177 RegExpParser parser(input, &result->error, multiline); | 5175 RegExpParser parser(input, &result->error, multiline); |
| 5178 RegExpTree* tree = parser.ParsePattern(); | 5176 RegExpTree* tree = parser.ParsePattern(); |
| 5179 if (parser.failed()) { | 5177 if (parser.failed()) { |
| 5180 ASSERT(tree == NULL); | 5178 ASSERT(tree == NULL); |
| 5181 ASSERT(!result->error.is_null()); | 5179 ASSERT(!result->error.is_null()); |
| 5182 } else { | 5180 } else { |
| 5183 ASSERT(tree != NULL); | 5181 ASSERT(tree != NULL); |
| 5184 ASSERT(result->error.is_null()); | 5182 ASSERT(result->error.is_null()); |
| 5185 result->tree = tree; | 5183 result->tree = tree; |
| 5186 int capture_count = parser.captures_started(); | 5184 int capture_count = parser.captures_started(); |
| 5187 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; | 5185 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; |
| 5188 result->contains_anchor = parser.contains_anchor(); | 5186 result->contains_anchor = parser.contains_anchor(); |
| 5189 result->capture_count = capture_count; | 5187 result->capture_count = capture_count; |
| 5190 } | 5188 } |
| 5191 return !parser.failed(); | 5189 return !parser.failed(); |
| 5192 } | 5190 } |
| 5193 | 5191 |
| 5194 | 5192 |
| 5195 bool ParserApi::Parse(CompilationInfo* info) { | 5193 bool ParserApi::Parse(CompilationInfo* info) { |
| 5196 ASSERT(info->function() == NULL); | 5194 ASSERT(info->function() == NULL); |
| 5197 FunctionLiteral* result = NULL; | 5195 FunctionLiteral* result = NULL; |
| 5198 Handle<Script> script = info->script(); | 5196 Handle<Script> script = info->script(); |
| 5199 bool harmony_block_scoping = !info->is_native() && | 5197 bool harmony_scoping = !info->is_native() && FLAG_harmony_scoping; |
| 5200 FLAG_harmony_block_scoping; | |
| 5201 if (info->is_lazy()) { | 5198 if (info->is_lazy()) { |
| 5202 Parser parser(script, true, NULL, NULL); | 5199 Parser parser(script, true, NULL, NULL); |
| 5203 parser.SetHarmonyBlockScoping(harmony_block_scoping); | 5200 parser.SetHarmonyScoping(harmony_scoping); |
| 5204 result = parser.ParseLazy(info); | 5201 result = parser.ParseLazy(info); |
| 5205 } else { | 5202 } else { |
| 5206 // Whether we allow %identifier(..) syntax. | 5203 // Whether we allow %identifier(..) syntax. |
| 5207 bool allow_natives_syntax = | 5204 bool allow_natives_syntax = |
| 5208 info->allows_natives_syntax() || FLAG_allow_natives_syntax; | 5205 info->allows_natives_syntax() || FLAG_allow_natives_syntax; |
| 5209 ScriptDataImpl* pre_data = info->pre_parse_data(); | 5206 ScriptDataImpl* pre_data = info->pre_parse_data(); |
| 5210 Parser parser(script, | 5207 Parser parser(script, |
| 5211 allow_natives_syntax, | 5208 allow_natives_syntax, |
| 5212 info->extension(), | 5209 info->extension(), |
| 5213 pre_data); | 5210 pre_data); |
| 5214 parser.SetHarmonyBlockScoping(harmony_block_scoping); | 5211 parser.SetHarmonyScoping(harmony_scoping); |
| 5215 if (pre_data != NULL && pre_data->has_error()) { | 5212 if (pre_data != NULL && pre_data->has_error()) { |
| 5216 Scanner::Location loc = pre_data->MessageLocation(); | 5213 Scanner::Location loc = pre_data->MessageLocation(); |
| 5217 const char* message = pre_data->BuildMessage(); | 5214 const char* message = pre_data->BuildMessage(); |
| 5218 Vector<const char*> args = pre_data->BuildArgs(); | 5215 Vector<const char*> args = pre_data->BuildArgs(); |
| 5219 parser.ReportMessageAt(loc, message, args); | 5216 parser.ReportMessageAt(loc, message, args); |
| 5220 DeleteArray(message); | 5217 DeleteArray(message); |
| 5221 for (int i = 0; i < args.length(); i++) { | 5218 for (int i = 0; i < args.length(); i++) { |
| 5222 DeleteArray(args[i]); | 5219 DeleteArray(args[i]); |
| 5223 } | 5220 } |
| 5224 DeleteArray(args.start()); | 5221 DeleteArray(args.start()); |
| 5225 ASSERT(info->isolate()->has_pending_exception()); | 5222 ASSERT(info->isolate()->has_pending_exception()); |
| 5226 } else { | 5223 } else { |
| 5227 Handle<String> source = Handle<String>(String::cast(script->source())); | 5224 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 5228 result = parser.ParseProgram(source, | 5225 result = parser.ParseProgram(source, |
| 5229 info->is_global(), | 5226 info->is_global(), |
| 5230 info->StrictMode()); | 5227 info->StrictMode()); |
| 5231 } | 5228 } |
| 5232 } | 5229 } |
| 5233 info->SetFunction(result); | 5230 info->SetFunction(result); |
| 5234 return (result != NULL); | 5231 return (result != NULL); |
| 5235 } | 5232 } |
| 5236 | 5233 |
| 5237 } } // namespace v8::internal | 5234 } } // namespace v8::internal |
| OLD | NEW |