OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 : symbol_cache_(pre_data ? pre_data->symbol_count() : 0), | 586 : symbol_cache_(pre_data ? pre_data->symbol_count() : 0), |
587 script_(script), | 587 script_(script), |
588 scanner_(), | 588 scanner_(), |
589 top_scope_(NULL), | 589 top_scope_(NULL), |
590 with_nesting_level_(0), | 590 with_nesting_level_(0), |
591 temp_scope_(NULL), | 591 temp_scope_(NULL), |
592 target_stack_(NULL), | 592 target_stack_(NULL), |
593 allow_natives_syntax_(allow_natives_syntax), | 593 allow_natives_syntax_(allow_natives_syntax), |
594 extension_(extension), | 594 extension_(extension), |
595 pre_data_(pre_data), | 595 pre_data_(pre_data), |
596 fni_(NULL) { | 596 fni_(NULL), |
| 597 stack_overflow_(false) { |
597 } | 598 } |
598 | 599 |
599 | 600 |
600 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 601 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
601 bool in_global_context) { | 602 bool in_global_context) { |
602 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 603 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
603 | 604 |
604 HistogramTimerScope timer(&Counters::parse); | 605 HistogramTimerScope timer(&Counters::parse); |
605 Counters::total_parse_size.Increment(source->length()); | 606 Counters::total_parse_size.Increment(source->length()); |
606 fni_ = new FuncNameInferrer(); | 607 fni_ = new FuncNameInferrer(); |
(...skipping 29 matching lines...) Expand all Loading... |
636 body, | 637 body, |
637 temp_scope.materialized_literal_count(), | 638 temp_scope.materialized_literal_count(), |
638 temp_scope.expected_property_count(), | 639 temp_scope.expected_property_count(), |
639 temp_scope.only_simple_this_property_assignments(), | 640 temp_scope.only_simple_this_property_assignments(), |
640 temp_scope.this_property_assignments(), | 641 temp_scope.this_property_assignments(), |
641 0, | 642 0, |
642 0, | 643 0, |
643 source->length(), | 644 source->length(), |
644 false, | 645 false, |
645 temp_scope.ContainsLoops()); | 646 temp_scope.ContainsLoops()); |
646 } else if (scanner().stack_overflow()) { | 647 } else if (stack_overflow_) { |
647 Top::StackOverflow(); | 648 Top::StackOverflow(); |
648 } | 649 } |
649 } | 650 } |
650 | 651 |
651 // Make sure the target stack is empty. | 652 // Make sure the target stack is empty. |
652 ASSERT(target_stack_ == NULL); | 653 ASSERT(target_stack_ == NULL); |
653 | 654 |
654 // If there was a syntax error we have to get rid of the AST | 655 // If there was a syntax error we have to get rid of the AST |
655 // and it is not safe to do so before the scope has been deleted. | 656 // and it is not safe to do so before the scope has been deleted. |
656 if (result == NULL) zone_scope.DeleteOnExit(); | 657 if (result == NULL) zone_scope.DeleteOnExit(); |
(...skipping 29 matching lines...) Expand all Loading... |
686 scope); | 687 scope); |
687 TemporaryScope temp_scope(&this->temp_scope_); | 688 TemporaryScope temp_scope(&this->temp_scope_); |
688 | 689 |
689 FunctionLiteralType type = | 690 FunctionLiteralType type = |
690 info->is_expression() ? EXPRESSION : DECLARATION; | 691 info->is_expression() ? EXPRESSION : DECLARATION; |
691 bool ok = true; | 692 bool ok = true; |
692 result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok); | 693 result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok); |
693 // Make sure the results agree. | 694 // Make sure the results agree. |
694 ASSERT(ok == (result != NULL)); | 695 ASSERT(ok == (result != NULL)); |
695 // The only errors should be stack overflows. | 696 // The only errors should be stack overflows. |
696 ASSERT(ok || scanner_.stack_overflow()); | 697 ASSERT(ok || stack_overflow_); |
697 } | 698 } |
698 | 699 |
699 // Make sure the target stack is empty. | 700 // Make sure the target stack is empty. |
700 ASSERT(target_stack_ == NULL); | 701 ASSERT(target_stack_ == NULL); |
701 | 702 |
702 // If there was a stack overflow we have to get rid of AST and it is | 703 // If there was a stack overflow we have to get rid of AST and it is |
703 // not safe to do before scope has been deleted. | 704 // not safe to do before scope has been deleted. |
704 if (result == NULL) { | 705 if (result == NULL) { |
705 Top::StackOverflow(); | 706 Top::StackOverflow(); |
706 zone_scope.DeleteOnExit(); | 707 zone_scope.DeleteOnExit(); |
(...skipping 1876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2583 Expect(Token::DEBUGGER, CHECK_OK); | 2584 Expect(Token::DEBUGGER, CHECK_OK); |
2584 ExpectSemicolon(CHECK_OK); | 2585 ExpectSemicolon(CHECK_OK); |
2585 return new DebuggerStatement(); | 2586 return new DebuggerStatement(); |
2586 } | 2587 } |
2587 | 2588 |
2588 | 2589 |
2589 void Parser::ReportUnexpectedToken(Token::Value token) { | 2590 void Parser::ReportUnexpectedToken(Token::Value token) { |
2590 // We don't report stack overflows here, to avoid increasing the | 2591 // We don't report stack overflows here, to avoid increasing the |
2591 // stack depth even further. Instead we report it after parsing is | 2592 // stack depth even further. Instead we report it after parsing is |
2592 // over, in ParseProgram/ParseJson. | 2593 // over, in ParseProgram/ParseJson. |
2593 if (token == Token::ILLEGAL && scanner().stack_overflow()) | 2594 if (token == Token::ILLEGAL && stack_overflow_) return; |
2594 return; | |
2595 // Four of the tokens are treated specially | 2595 // Four of the tokens are treated specially |
2596 switch (token) { | 2596 switch (token) { |
2597 case Token::EOS: | 2597 case Token::EOS: |
2598 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); | 2598 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); |
2599 case Token::NUMBER: | 2599 case Token::NUMBER: |
2600 return ReportMessage("unexpected_token_number", | 2600 return ReportMessage("unexpected_token_number", |
2601 Vector<const char*>::empty()); | 2601 Vector<const char*>::empty()); |
2602 case Token::STRING: | 2602 case Token::STRING: |
2603 return ReportMessage("unexpected_token_string", | 2603 return ReportMessage("unexpected_token_string", |
2604 Vector<const char*>::empty()); | 2604 Vector<const char*>::empty()); |
2605 case Token::IDENTIFIER: | 2605 case Token::IDENTIFIER: |
2606 return ReportMessage("unexpected_token_identifier", | 2606 return ReportMessage("unexpected_token_identifier", |
2607 Vector<const char*>::empty()); | 2607 Vector<const char*>::empty()); |
2608 default: | 2608 default: |
2609 const char* name = Token::String(token); | 2609 const char* name = Token::String(token); |
2610 ASSERT(name != NULL); | 2610 ASSERT(name != NULL); |
2611 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); | 2611 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); |
2612 } | 2612 } |
2613 } | 2613 } |
2614 | 2614 |
2615 | 2615 |
2616 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { | 2616 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { |
2617 SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS); | 2617 SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS); |
2618 const char* element[1] = { *name_string }; | 2618 const char* element[1] = { *name_string }; |
2619 ReportMessage("invalid_preparser_data", | 2619 ReportMessage("invalid_preparser_data", |
2620 Vector<const char*>(element, 1)); | 2620 Vector<const char*>(element, 1)); |
2621 *ok = false; | 2621 *ok = false; |
(...skipping 869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3491 return new Throw(new CallRuntime(constructor, NULL, args), | 3491 return new Throw(new CallRuntime(constructor, NULL, args), |
3492 scanner().location().beg_pos); | 3492 scanner().location().beg_pos); |
3493 } | 3493 } |
3494 | 3494 |
3495 // ---------------------------------------------------------------------------- | 3495 // ---------------------------------------------------------------------------- |
3496 // JSON | 3496 // JSON |
3497 | 3497 |
3498 Handle<Object> JsonParser::ParseJson(Handle<String> source) { | 3498 Handle<Object> JsonParser::ParseJson(Handle<String> source) { |
3499 source->TryFlatten(); | 3499 source->TryFlatten(); |
3500 scanner_.Initialize(source); | 3500 scanner_.Initialize(source); |
| 3501 stack_overflow_ = false; |
3501 Handle<Object> result = ParseJsonValue(); | 3502 Handle<Object> result = ParseJsonValue(); |
3502 if (result.is_null() || scanner_.Next() != Token::EOS) { | 3503 if (result.is_null() || scanner_.Next() != Token::EOS) { |
3503 if (scanner_.stack_overflow()) { | 3504 if (stack_overflow_) { |
3504 // Scanner failed. | 3505 // Scanner failed. |
3505 Top::StackOverflow(); | 3506 Top::StackOverflow(); |
3506 } else { | 3507 } else { |
3507 // Parse failed. Scanner's current token is the unexpected token. | 3508 // Parse failed. Scanner's current token is the unexpected token. |
3508 Token::Value token = scanner_.current_token(); | 3509 Token::Value token = scanner_.current_token(); |
3509 | 3510 |
3510 const char* message; | 3511 const char* message; |
3511 const char* name_opt = NULL; | 3512 const char* name_opt = NULL; |
3512 | 3513 |
3513 switch (token) { | 3514 switch (token) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3591 | 3592 |
3592 | 3593 |
3593 // Parse a JSON object. Scanner must be right after '{' token. | 3594 // Parse a JSON object. Scanner must be right after '{' token. |
3594 Handle<Object> JsonParser::ParseJsonObject() { | 3595 Handle<Object> JsonParser::ParseJsonObject() { |
3595 Handle<JSFunction> object_constructor( | 3596 Handle<JSFunction> object_constructor( |
3596 Top::global_context()->object_function()); | 3597 Top::global_context()->object_function()); |
3597 Handle<JSObject> json_object = Factory::NewJSObject(object_constructor); | 3598 Handle<JSObject> json_object = Factory::NewJSObject(object_constructor); |
3598 if (scanner_.peek() == Token::RBRACE) { | 3599 if (scanner_.peek() == Token::RBRACE) { |
3599 scanner_.Next(); | 3600 scanner_.Next(); |
3600 } else { | 3601 } else { |
| 3602 if (StackLimitCheck().HasOverflowed()) { |
| 3603 stack_overflow_ = true; |
| 3604 return Handle<Object>::null(); |
| 3605 } |
3601 do { | 3606 do { |
3602 if (scanner_.Next() != Token::STRING) { | 3607 if (scanner_.Next() != Token::STRING) { |
3603 return ReportUnexpectedToken(); | 3608 return ReportUnexpectedToken(); |
3604 } | 3609 } |
3605 Handle<String> key = GetString(); | 3610 Handle<String> key = GetString(); |
3606 if (scanner_.Next() != Token::COLON) { | 3611 if (scanner_.Next() != Token::COLON) { |
3607 return ReportUnexpectedToken(); | 3612 return ReportUnexpectedToken(); |
3608 } | 3613 } |
3609 Handle<Object> value = ParseJsonValue(); | 3614 Handle<Object> value = ParseJsonValue(); |
3610 if (value.is_null()) return Handle<Object>::null(); | 3615 if (value.is_null()) return Handle<Object>::null(); |
(...skipping 14 matching lines...) Expand all Loading... |
3625 | 3630 |
3626 // Parse a JSON array. Scanner must be right after '[' token. | 3631 // Parse a JSON array. Scanner must be right after '[' token. |
3627 Handle<Object> JsonParser::ParseJsonArray() { | 3632 Handle<Object> JsonParser::ParseJsonArray() { |
3628 ZoneScope zone_scope(DELETE_ON_EXIT); | 3633 ZoneScope zone_scope(DELETE_ON_EXIT); |
3629 ZoneList<Handle<Object> > elements(4); | 3634 ZoneList<Handle<Object> > elements(4); |
3630 | 3635 |
3631 Token::Value token = scanner_.peek(); | 3636 Token::Value token = scanner_.peek(); |
3632 if (token == Token::RBRACK) { | 3637 if (token == Token::RBRACK) { |
3633 scanner_.Next(); | 3638 scanner_.Next(); |
3634 } else { | 3639 } else { |
| 3640 if (StackLimitCheck().HasOverflowed()) { |
| 3641 stack_overflow_ = true; |
| 3642 return Handle<Object>::null(); |
| 3643 } |
3635 do { | 3644 do { |
3636 Handle<Object> element = ParseJsonValue(); | 3645 Handle<Object> element = ParseJsonValue(); |
3637 if (element.is_null()) return Handle<Object>::null(); | 3646 if (element.is_null()) return Handle<Object>::null(); |
3638 elements.Add(element); | 3647 elements.Add(element); |
3639 token = scanner_.Next(); | 3648 token = scanner_.Next(); |
3640 } while (token == Token::COMMA); | 3649 } while (token == Token::COMMA); |
3641 if (token != Token::RBRACK) { | 3650 if (token != Token::RBRACK) { |
3642 return ReportUnexpectedToken(); | 3651 return ReportUnexpectedToken(); |
3643 } | 3652 } |
3644 } | 3653 } |
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4524 | 4533 |
4525 | 4534 |
4526 // Create a Scanner for the preparser to use as input, and preparse the source. | 4535 // Create a Scanner for the preparser to use as input, and preparse the source. |
4527 static ScriptDataImpl* DoPreParse(Handle<String> source, | 4536 static ScriptDataImpl* DoPreParse(Handle<String> source, |
4528 unibrow::CharacterStream* stream, | 4537 unibrow::CharacterStream* stream, |
4529 bool allow_lazy, | 4538 bool allow_lazy, |
4530 ParserRecorder* recorder, | 4539 ParserRecorder* recorder, |
4531 int literal_flags) { | 4540 int literal_flags) { |
4532 V8JavaScriptScanner scanner; | 4541 V8JavaScriptScanner scanner; |
4533 scanner.Initialize(source, stream, literal_flags); | 4542 scanner.Initialize(source, stream, literal_flags); |
4534 preparser::PreParser preparser; | 4543 intptr_t stack_limit = StackGuard::real_climit(); |
4535 if (!preparser.PreParseProgram(&scanner, recorder, allow_lazy)) { | 4544 if (!preparser::PreParser::PreParseProgram(&scanner, |
| 4545 recorder, |
| 4546 allow_lazy, |
| 4547 stack_limit)) { |
4536 Top::StackOverflow(); | 4548 Top::StackOverflow(); |
4537 return NULL; | 4549 return NULL; |
4538 } | 4550 } |
4539 | 4551 |
4540 // Extract the accumulated data from the recorder as a single | 4552 // Extract the accumulated data from the recorder as a single |
4541 // contiguous vector that we are responsible for disposing. | 4553 // contiguous vector that we are responsible for disposing. |
4542 Vector<unsigned> store = recorder->ExtractData(); | 4554 Vector<unsigned> store = recorder->ExtractData(); |
4543 return new ScriptDataImpl(store); | 4555 return new ScriptDataImpl(store); |
4544 } | 4556 } |
4545 | 4557 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4624 Handle<String> source = Handle<String>(String::cast(script->source())); | 4636 Handle<String> source = Handle<String>(String::cast(script->source())); |
4625 result = parser.ParseProgram(source, info->is_global()); | 4637 result = parser.ParseProgram(source, info->is_global()); |
4626 } | 4638 } |
4627 } | 4639 } |
4628 | 4640 |
4629 info->SetFunction(result); | 4641 info->SetFunction(result); |
4630 return (result != NULL); | 4642 return (result != NULL); |
4631 } | 4643 } |
4632 | 4644 |
4633 } } // namespace v8::internal | 4645 } } // namespace v8::internal |
OLD | NEW |