| 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 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 Handle<FixedArray> this_property_assignments() { | 276 Handle<FixedArray> this_property_assignments() { |
| 277 return this_property_assignments_; | 277 return this_property_assignments_; |
| 278 } | 278 } |
| 279 | 279 |
| 280 void AddProperty() { expected_property_count_++; } | 280 void AddProperty() { expected_property_count_++; } |
| 281 int expected_property_count() { return expected_property_count_; } | 281 int expected_property_count() { return expected_property_count_; } |
| 282 | 282 |
| 283 void AddLoop() { loop_count_++; } | 283 void AddLoop() { loop_count_++; } |
| 284 bool ContainsLoops() const { return loop_count_ > 0; } | 284 bool ContainsLoops() const { return loop_count_ > 0; } |
| 285 | 285 |
| 286 bool StrictMode() { return strict_mode_; } | |
| 287 void EnableStrictMode() { | |
| 288 strict_mode_ = FLAG_strict_mode; | |
| 289 } | |
| 290 | |
| 291 private: | 286 private: |
| 292 // Captures the number of literals that need materialization in the | 287 // Captures the number of literals that need materialization in the |
| 293 // function. Includes regexp literals, and boilerplate for object | 288 // function. Includes regexp literals, and boilerplate for object |
| 294 // and array literals. | 289 // and array literals. |
| 295 int materialized_literal_count_; | 290 int materialized_literal_count_; |
| 296 | 291 |
| 297 // Properties count estimation. | 292 // Properties count estimation. |
| 298 int expected_property_count_; | 293 int expected_property_count_; |
| 299 | 294 |
| 300 // Keeps track of assignments to properties of this. Used for | 295 // Keeps track of assignments to properties of this. Used for |
| 301 // optimizing constructors. | 296 // optimizing constructors. |
| 302 bool only_simple_this_property_assignments_; | 297 bool only_simple_this_property_assignments_; |
| 303 Handle<FixedArray> this_property_assignments_; | 298 Handle<FixedArray> this_property_assignments_; |
| 304 | 299 |
| 305 // Captures the number of loops inside the scope. | 300 // Captures the number of loops inside the scope. |
| 306 int loop_count_; | 301 int loop_count_; |
| 307 | 302 |
| 308 // Parsing strict mode code. | |
| 309 bool strict_mode_; | |
| 310 | |
| 311 // Bookkeeping | 303 // Bookkeeping |
| 312 TemporaryScope** variable_; | 304 TemporaryScope** variable_; |
| 313 TemporaryScope* parent_; | 305 TemporaryScope* parent_; |
| 314 }; | 306 }; |
| 315 | 307 |
| 316 | 308 |
| 317 TemporaryScope::TemporaryScope(TemporaryScope** variable) | 309 TemporaryScope::TemporaryScope(TemporaryScope** variable) |
| 318 : materialized_literal_count_(0), | 310 : materialized_literal_count_(0), |
| 319 expected_property_count_(0), | 311 expected_property_count_(0), |
| 320 only_simple_this_property_assignments_(false), | 312 only_simple_this_property_assignments_(false), |
| 321 this_property_assignments_(Factory::empty_fixed_array()), | 313 this_property_assignments_(Factory::empty_fixed_array()), |
| 322 loop_count_(0), | 314 loop_count_(0), |
| 323 variable_(variable), | 315 variable_(variable), |
| 324 parent_(*variable) { | 316 parent_(*variable) { |
| 325 // Inherit the strict mode from the parent scope. | |
| 326 strict_mode_ = (parent_ != NULL) && parent_->strict_mode_; | |
| 327 *variable = this; | 317 *variable = this; |
| 328 } | 318 } |
| 329 | 319 |
| 330 | 320 |
| 331 TemporaryScope::~TemporaryScope() { | 321 TemporaryScope::~TemporaryScope() { |
| 332 *variable_ = parent_; | 322 *variable_ = parent_; |
| 333 } | 323 } |
| 334 | 324 |
| 335 | 325 |
| 336 Handle<String> Parser::LookupSymbol(int symbol_id) { | 326 Handle<String> Parser::LookupSymbol(int symbol_id) { |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 ? Scope::GLOBAL_SCOPE | 648 ? Scope::GLOBAL_SCOPE |
| 659 : Scope::EVAL_SCOPE; | 649 : Scope::EVAL_SCOPE; |
| 660 Handle<String> no_name = Factory::empty_symbol(); | 650 Handle<String> no_name = Factory::empty_symbol(); |
| 661 | 651 |
| 662 FunctionLiteral* result = NULL; | 652 FunctionLiteral* result = NULL; |
| 663 { Scope* scope = NewScope(top_scope_, type, inside_with()); | 653 { Scope* scope = NewScope(top_scope_, type, inside_with()); |
| 664 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 654 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 665 scope); | 655 scope); |
| 666 TemporaryScope temp_scope(&this->temp_scope_); | 656 TemporaryScope temp_scope(&this->temp_scope_); |
| 667 if (strict_mode == kStrictMode) { | 657 if (strict_mode == kStrictMode) { |
| 668 temp_scope.EnableStrictMode(); | 658 top_scope_->EnableStrictMode(); |
| 669 } | 659 } |
| 670 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); | 660 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); |
| 671 bool ok = true; | 661 bool ok = true; |
| 672 int beg_loc = scanner().location().beg_pos; | 662 int beg_loc = scanner().location().beg_pos; |
| 673 ParseSourceElements(body, Token::EOS, &ok); | 663 ParseSourceElements(body, Token::EOS, &ok); |
| 674 if (ok && temp_scope_->StrictMode()) { | 664 if (ok && top_scope_->is_strict_mode()) { |
| 675 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 665 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 676 } | 666 } |
| 677 if (ok) { | 667 if (ok) { |
| 678 result = new FunctionLiteral( | 668 result = new FunctionLiteral( |
| 679 no_name, | 669 no_name, |
| 680 top_scope_, | 670 top_scope_, |
| 681 body, | 671 body, |
| 682 temp_scope.materialized_literal_count(), | 672 temp_scope.materialized_literal_count(), |
| 683 temp_scope.expected_property_count(), | 673 temp_scope.expected_property_count(), |
| 684 temp_scope.only_simple_this_property_assignments(), | 674 temp_scope.only_simple_this_property_assignments(), |
| 685 temp_scope.this_property_assignments(), | 675 temp_scope.this_property_assignments(), |
| 686 0, | 676 0, |
| 687 0, | 677 0, |
| 688 source->length(), | 678 source->length(), |
| 689 false, | 679 false, |
| 690 temp_scope.ContainsLoops(), | 680 temp_scope.ContainsLoops()); |
| 691 temp_scope.StrictMode()); | |
| 692 } else if (stack_overflow_) { | 681 } else if (stack_overflow_) { |
| 693 Top::StackOverflow(); | 682 Top::StackOverflow(); |
| 694 } | 683 } |
| 695 } | 684 } |
| 696 | 685 |
| 697 // Make sure the target stack is empty. | 686 // Make sure the target stack is empty. |
| 698 ASSERT(target_stack_ == NULL); | 687 ASSERT(target_stack_ == NULL); |
| 699 | 688 |
| 700 // If there was a syntax error we have to get rid of the AST | 689 // If there was a syntax error we have to get rid of the AST |
| 701 // and it is not safe to do so before the scope has been deleted. | 690 // and it is not safe to do so before the scope has been deleted. |
| 702 if (result == NULL) zone_scope->DeleteOnExit(); | 691 if (result == NULL) zone_scope->DeleteOnExit(); |
| 703 return result; | 692 return result; |
| 704 } | 693 } |
| 705 | 694 |
| 706 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info) { | 695 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) { |
| 707 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 696 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
| 708 HistogramTimerScope timer(&Counters::parse_lazy); | 697 HistogramTimerScope timer(&Counters::parse_lazy); |
| 709 Handle<String> source(String::cast(script_->source())); | 698 Handle<String> source(String::cast(script_->source())); |
| 710 Counters::total_parse_size.Increment(source->length()); | 699 Counters::total_parse_size.Increment(source->length()); |
| 711 | 700 |
| 701 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
| 712 // Initialize parser state. | 702 // Initialize parser state. |
| 713 source->TryFlatten(); | 703 source->TryFlatten(); |
| 714 if (source->IsExternalTwoByteString()) { | 704 if (source->IsExternalTwoByteString()) { |
| 715 ExternalTwoByteStringUC16CharacterStream stream( | 705 ExternalTwoByteStringUC16CharacterStream stream( |
| 716 Handle<ExternalTwoByteString>::cast(source), | 706 Handle<ExternalTwoByteString>::cast(source), |
| 717 info->start_position(), | 707 shared_info->start_position(), |
| 718 info->end_position()); | 708 shared_info->end_position()); |
| 719 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); | 709 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); |
| 720 return result; | 710 return result; |
| 721 } else { | 711 } else { |
| 722 GenericStringUC16CharacterStream stream(source, | 712 GenericStringUC16CharacterStream stream(source, |
| 723 info->start_position(), | 713 shared_info->start_position(), |
| 724 info->end_position()); | 714 shared_info->end_position()); |
| 725 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); | 715 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); |
| 726 return result; | 716 return result; |
| 727 } | 717 } |
| 728 } | 718 } |
| 729 | 719 |
| 730 | 720 |
| 731 FunctionLiteral* Parser::ParseLazy(Handle<SharedFunctionInfo> info, | 721 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, |
| 732 UC16CharacterStream* source, | 722 UC16CharacterStream* source, |
| 733 ZoneScope* zone_scope) { | 723 ZoneScope* zone_scope) { |
| 724 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
| 734 scanner_.Initialize(source); | 725 scanner_.Initialize(source); |
| 735 ASSERT(target_stack_ == NULL); | 726 ASSERT(target_stack_ == NULL); |
| 736 | 727 |
| 737 Handle<String> name(String::cast(info->name())); | 728 Handle<String> name(String::cast(shared_info->name())); |
| 738 fni_ = new FuncNameInferrer(); | 729 fni_ = new FuncNameInferrer(); |
| 739 fni_->PushEnclosingName(name); | 730 fni_->PushEnclosingName(name); |
| 740 | 731 |
| 741 mode_ = PARSE_EAGERLY; | 732 mode_ = PARSE_EAGERLY; |
| 742 | 733 |
| 743 // Place holder for the result. | 734 // Place holder for the result. |
| 744 FunctionLiteral* result = NULL; | 735 FunctionLiteral* result = NULL; |
| 745 | 736 |
| 746 { | 737 { |
| 747 // Parse the function literal. | 738 // Parse the function literal. |
| 748 Handle<String> no_name = Factory::empty_symbol(); | 739 Handle<String> no_name = Factory::empty_symbol(); |
| 749 Scope* scope = | 740 Scope* scope = NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); |
| 750 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); | 741 if (!info->closure().is_null()) { |
| 742 scope = Scope::DeserializeScopeChain(info, scope); |
| 743 } |
| 751 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 744 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 752 scope); | 745 scope); |
| 753 TemporaryScope temp_scope(&this->temp_scope_); | 746 TemporaryScope temp_scope(&this->temp_scope_); |
| 754 | 747 |
| 755 if (info->strict_mode()) { | 748 if (shared_info->strict_mode()) { |
| 756 temp_scope.EnableStrictMode(); | 749 top_scope_->EnableStrictMode(); |
| 757 } | 750 } |
| 758 | 751 |
| 759 FunctionLiteralType type = | 752 FunctionLiteralType type = |
| 760 info->is_expression() ? EXPRESSION : DECLARATION; | 753 shared_info->is_expression() ? EXPRESSION : DECLARATION; |
| 761 bool ok = true; | 754 bool ok = true; |
| 762 result = ParseFunctionLiteral(name, | 755 result = ParseFunctionLiteral(name, |
| 763 false, // Strict mode name already checked. | 756 false, // Strict mode name already checked. |
| 764 RelocInfo::kNoPosition, type, &ok); | 757 RelocInfo::kNoPosition, type, &ok); |
| 765 // Make sure the results agree. | 758 // Make sure the results agree. |
| 766 ASSERT(ok == (result != NULL)); | 759 ASSERT(ok == (result != NULL)); |
| 767 } | 760 } |
| 768 | 761 |
| 769 // Make sure the target stack is empty. | 762 // Make sure the target stack is empty. |
| 770 ASSERT(target_stack_ == NULL); | 763 ASSERT(target_stack_ == NULL); |
| 771 | 764 |
| 772 // If there was a stack overflow we have to get rid of AST and it is | 765 // If there was a stack overflow we have to get rid of AST and it is |
| 773 // not safe to do before scope has been deleted. | 766 // not safe to do before scope has been deleted. |
| 774 if (result == NULL) { | 767 if (result == NULL) { |
| 775 zone_scope->DeleteOnExit(); | 768 zone_scope->DeleteOnExit(); |
| 776 if (stack_overflow_) Top::StackOverflow(); | 769 if (stack_overflow_) Top::StackOverflow(); |
| 777 } else { | 770 } else { |
| 778 Handle<String> inferred_name(info->inferred_name()); | 771 Handle<String> inferred_name(shared_info->inferred_name()); |
| 779 result->set_inferred_name(inferred_name); | 772 result->set_inferred_name(inferred_name); |
| 780 } | 773 } |
| 781 return result; | 774 return result; |
| 782 } | 775 } |
| 783 | 776 |
| 784 | 777 |
| 785 Handle<String> Parser::GetSymbol(bool* ok) { | 778 Handle<String> Parser::GetSymbol(bool* ok) { |
| 786 int symbol_id = -1; | 779 int symbol_id = -1; |
| 787 if (pre_data() != NULL) { | 780 if (pre_data() != NULL) { |
| 788 symbol_id = pre_data()->GetSymbolIdentifier(); | 781 symbol_id = pre_data()->GetSymbolIdentifier(); |
| 789 } | 782 } |
| 790 return LookupSymbol(symbol_id); | 783 return LookupSymbol(symbol_id); |
| 791 } | 784 } |
| 792 | 785 |
| 793 | 786 |
| 794 void Parser::ReportMessage(const char* type, Vector<const char*> args) { | 787 void Parser::ReportMessage(const char* type, Vector<const char*> args) { |
| 795 Scanner::Location source_location = scanner().location(); | 788 Scanner::Location source_location = scanner().location(); |
| 796 ReportMessageAt(source_location, type, args); | 789 ReportMessageAt(source_location, type, args); |
| 797 } | 790 } |
| 798 | 791 |
| 799 | 792 |
| 800 void Parser::ReportMessageAt(Scanner::Location source_location, | 793 void Parser::ReportMessageAt(Scanner::Location source_location, |
| 801 const char* type, | 794 const char* type, |
| 802 Vector<const char*> args) { | 795 Vector<const char*> args) { |
| 803 MessageLocation location(script_, | 796 MessageLocation location(script_, |
| 804 source_location.beg_pos, | 797 source_location.beg_pos, |
| 805 source_location.end_pos); | 798 source_location.end_pos); |
| 806 Handle<JSArray> array = Factory::NewJSArray(args.length()); | 799 Handle<FixedArray> elements = Factory::NewFixedArray(args.length()); |
| 807 for (int i = 0; i < args.length(); i++) { | 800 for (int i = 0; i < args.length(); i++) { |
| 808 SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i]))); | 801 Handle<String> arg_string = Factory::NewStringFromUtf8(CStrVector(args[i])); |
| 802 elements->set(i, *arg_string); |
| 809 } | 803 } |
| 804 Handle<JSArray> array = Factory::NewJSArrayWithElements(elements); |
| 810 Handle<Object> result = Factory::NewSyntaxError(type, array); | 805 Handle<Object> result = Factory::NewSyntaxError(type, array); |
| 811 Top::Throw(*result, &location); | 806 Top::Throw(*result, &location); |
| 812 } | 807 } |
| 813 | 808 |
| 814 | 809 |
| 815 void Parser::ReportMessageAt(Scanner::Location source_location, | 810 void Parser::ReportMessageAt(Scanner::Location source_location, |
| 816 const char* type, | 811 const char* type, |
| 817 Vector<Handle<String> > args) { | 812 Vector<Handle<String> > args) { |
| 818 MessageLocation location(script_, | 813 MessageLocation location(script_, |
| 819 source_location.beg_pos, | 814 source_location.beg_pos, |
| 820 source_location.end_pos); | 815 source_location.end_pos); |
| 821 Handle<JSArray> array = Factory::NewJSArray(args.length()); | 816 Handle<FixedArray> elements = Factory::NewFixedArray(args.length()); |
| 822 for (int i = 0; i < args.length(); i++) { | 817 for (int i = 0; i < args.length(); i++) { |
| 823 SetElement(array, i, args[i]); | 818 elements->set(i, *args[i]); |
| 824 } | 819 } |
| 820 Handle<JSArray> array = Factory::NewJSArrayWithElements(elements); |
| 825 Handle<Object> result = Factory::NewSyntaxError(type, array); | 821 Handle<Object> result = Factory::NewSyntaxError(type, array); |
| 826 Top::Throw(*result, &location); | 822 Top::Throw(*result, &location); |
| 827 } | 823 } |
| 828 | 824 |
| 829 | 825 |
| 830 // Base class containing common code for the different finder classes used by | 826 // Base class containing common code for the different finder classes used by |
| 831 // the parser. | 827 // the parser. |
| 832 class ParserFinder { | 828 class ParserFinder { |
| 833 protected: | 829 protected: |
| 834 ParserFinder() {} | 830 ParserFinder() {} |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1099 InitializationBlockFinder block_finder; | 1095 InitializationBlockFinder block_finder; |
| 1100 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; | 1096 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; |
| 1101 bool directive_prologue = true; // Parsing directive prologue. | 1097 bool directive_prologue = true; // Parsing directive prologue. |
| 1102 | 1098 |
| 1103 while (peek() != end_token) { | 1099 while (peek() != end_token) { |
| 1104 if (directive_prologue && peek() != Token::STRING) { | 1100 if (directive_prologue && peek() != Token::STRING) { |
| 1105 directive_prologue = false; | 1101 directive_prologue = false; |
| 1106 } | 1102 } |
| 1107 | 1103 |
| 1108 Scanner::Location token_loc = scanner().peek_location(); | 1104 Scanner::Location token_loc = scanner().peek_location(); |
| 1109 Statement* stat = ParseStatement(NULL, CHECK_OK); | 1105 |
| 1106 Statement* stat; |
| 1107 if (peek() == Token::FUNCTION) { |
| 1108 // FunctionDeclaration is only allowed in the context of SourceElements |
| 1109 // (Ecma 262 5th Edition, clause 14): |
| 1110 // SourceElement: |
| 1111 // Statement |
| 1112 // FunctionDeclaration |
| 1113 // Common language extension is to allow function declaration in place |
| 1114 // of any statement. This language extension is disabled in strict mode. |
| 1115 stat = ParseFunctionDeclaration(CHECK_OK); |
| 1116 } else { |
| 1117 stat = ParseStatement(NULL, CHECK_OK); |
| 1118 } |
| 1110 | 1119 |
| 1111 if (stat == NULL || stat->IsEmpty()) { | 1120 if (stat == NULL || stat->IsEmpty()) { |
| 1112 directive_prologue = false; // End of directive prologue. | 1121 directive_prologue = false; // End of directive prologue. |
| 1113 continue; | 1122 continue; |
| 1114 } | 1123 } |
| 1115 | 1124 |
| 1116 if (directive_prologue) { | 1125 if (directive_prologue) { |
| 1117 // A shot at a directive. | 1126 // A shot at a directive. |
| 1118 ExpressionStatement *e_stat; | 1127 ExpressionStatement *e_stat; |
| 1119 Literal *literal; | 1128 Literal *literal; |
| 1120 // Still processing directive prologue? | 1129 // Still processing directive prologue? |
| 1121 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 1130 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 1122 (literal = e_stat->expression()->AsLiteral()) != NULL && | 1131 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 1123 literal->handle()->IsString()) { | 1132 literal->handle()->IsString()) { |
| 1124 Handle<String> directive = Handle<String>::cast(literal->handle()); | 1133 Handle<String> directive = Handle<String>::cast(literal->handle()); |
| 1125 | 1134 |
| 1126 // Check "use strict" directive (ES5 14.1). | 1135 // Check "use strict" directive (ES5 14.1). |
| 1127 if (!temp_scope_->StrictMode() && | 1136 if (!top_scope_->is_strict_mode() && |
| 1128 directive->Equals(Heap::use_strict()) && | 1137 directive->Equals(Heap::use_strict()) && |
| 1129 token_loc.end_pos - token_loc.beg_pos == | 1138 token_loc.end_pos - token_loc.beg_pos == |
| 1130 Heap::use_strict()->length() + 2) { | 1139 Heap::use_strict()->length() + 2) { |
| 1131 temp_scope_->EnableStrictMode(); | 1140 top_scope_->EnableStrictMode(); |
| 1132 // "use strict" is the only directive for now. | 1141 // "use strict" is the only directive for now. |
| 1133 directive_prologue = false; | 1142 directive_prologue = false; |
| 1134 } | 1143 } |
| 1135 } else { | 1144 } else { |
| 1136 // End of the directive prologue. | 1145 // End of the directive prologue. |
| 1137 directive_prologue = false; | 1146 directive_prologue = false; |
| 1138 } | 1147 } |
| 1139 } | 1148 } |
| 1140 | 1149 |
| 1141 // We find and mark the initialization blocks on top level code only. | 1150 // We find and mark the initialization blocks on top level code only. |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 Block* result = new Block(labels, 1, false); | 1265 Block* result = new Block(labels, 1, false); |
| 1257 Target target(&this->target_stack_, result); | 1266 Target target(&this->target_stack_, result); |
| 1258 TryStatement* statement = ParseTryStatement(CHECK_OK); | 1267 TryStatement* statement = ParseTryStatement(CHECK_OK); |
| 1259 if (statement) { | 1268 if (statement) { |
| 1260 statement->set_statement_pos(statement_pos); | 1269 statement->set_statement_pos(statement_pos); |
| 1261 } | 1270 } |
| 1262 if (result) result->AddStatement(statement); | 1271 if (result) result->AddStatement(statement); |
| 1263 return result; | 1272 return result; |
| 1264 } | 1273 } |
| 1265 | 1274 |
| 1266 case Token::FUNCTION: | 1275 case Token::FUNCTION: { |
| 1276 // In strict mode, FunctionDeclaration is only allowed in the context |
| 1277 // of SourceElements. |
| 1278 if (top_scope_->is_strict_mode()) { |
| 1279 ReportMessageAt(scanner().peek_location(), "strict_function", |
| 1280 Vector<const char*>::empty()); |
| 1281 *ok = false; |
| 1282 return NULL; |
| 1283 } |
| 1267 return ParseFunctionDeclaration(ok); | 1284 return ParseFunctionDeclaration(ok); |
| 1285 } |
| 1268 | 1286 |
| 1269 case Token::NATIVE: | 1287 case Token::NATIVE: |
| 1270 return ParseNativeDeclaration(ok); | 1288 return ParseNativeDeclaration(ok); |
| 1271 | 1289 |
| 1272 case Token::DEBUGGER: | 1290 case Token::DEBUGGER: |
| 1273 stmt = ParseDebuggerStatement(ok); | 1291 stmt = ParseDebuggerStatement(ok); |
| 1274 break; | 1292 break; |
| 1275 | 1293 |
| 1276 default: | 1294 default: |
| 1277 stmt = ParseExpressionOrLabelledStatement(labels, ok); | 1295 stmt = ParseExpressionOrLabelledStatement(labels, ok); |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1508 bool* ok) { | 1526 bool* ok) { |
| 1509 // VariableDeclarations :: | 1527 // VariableDeclarations :: |
| 1510 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] | 1528 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] |
| 1511 | 1529 |
| 1512 Variable::Mode mode = Variable::VAR; | 1530 Variable::Mode mode = Variable::VAR; |
| 1513 bool is_const = false; | 1531 bool is_const = false; |
| 1514 if (peek() == Token::VAR) { | 1532 if (peek() == Token::VAR) { |
| 1515 Consume(Token::VAR); | 1533 Consume(Token::VAR); |
| 1516 } else if (peek() == Token::CONST) { | 1534 } else if (peek() == Token::CONST) { |
| 1517 Consume(Token::CONST); | 1535 Consume(Token::CONST); |
| 1536 if (top_scope_->is_strict_mode()) { |
| 1537 ReportMessage("strict_const", Vector<const char*>::empty()); |
| 1538 *ok = false; |
| 1539 return NULL; |
| 1540 } |
| 1518 mode = Variable::CONST; | 1541 mode = Variable::CONST; |
| 1519 is_const = true; | 1542 is_const = true; |
| 1520 } else { | 1543 } else { |
| 1521 UNREACHABLE(); // by current callers | 1544 UNREACHABLE(); // by current callers |
| 1522 } | 1545 } |
| 1523 | 1546 |
| 1524 // The scope of a variable/const declared anywhere inside a function | 1547 // The scope of a variable/const declared anywhere inside a function |
| 1525 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can | 1548 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can |
| 1526 // transform a source-level variable/const declaration into a (Function) | 1549 // transform a source-level variable/const declaration into a (Function) |
| 1527 // Scope declaration, and rewrite the source-level initialization into an | 1550 // Scope declaration, and rewrite the source-level initialization into an |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1539 int nvars = 0; // the number of variables declared | 1562 int nvars = 0; // the number of variables declared |
| 1540 do { | 1563 do { |
| 1541 if (fni_ != NULL) fni_->Enter(); | 1564 if (fni_ != NULL) fni_->Enter(); |
| 1542 | 1565 |
| 1543 // Parse variable name. | 1566 // Parse variable name. |
| 1544 if (nvars > 0) Consume(Token::COMMA); | 1567 if (nvars > 0) Consume(Token::COMMA); |
| 1545 Handle<String> name = ParseIdentifier(CHECK_OK); | 1568 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1546 if (fni_ != NULL) fni_->PushVariableName(name); | 1569 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1547 | 1570 |
| 1548 // Strict mode variables may not be named eval or arguments | 1571 // Strict mode variables may not be named eval or arguments |
| 1549 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) { | 1572 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { |
| 1550 ReportMessage("strict_var_name", Vector<const char*>::empty()); | 1573 ReportMessage("strict_var_name", Vector<const char*>::empty()); |
| 1551 *ok = false; | 1574 *ok = false; |
| 1552 return NULL; | 1575 return NULL; |
| 1553 } | 1576 } |
| 1554 | 1577 |
| 1555 // Declare variable. | 1578 // Declare variable. |
| 1556 // Note that we *always* must treat the initial value via a separate init | 1579 // Note that we *always* must treat the initial value via a separate init |
| 1557 // assignment for variables and constants because the value must be assigned | 1580 // assignment for variables and constants because the value must be assigned |
| 1558 // when the variable is encountered in the source. But the variable/constant | 1581 // when the variable is encountered in the source. But the variable/constant |
| 1559 // is declared (and set to 'undefined') upon entering the function within | 1582 // is declared (and set to 'undefined') upon entering the function within |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1627 // guarantee to give the global object a "local" variable; a | 1650 // guarantee to give the global object a "local" variable; a |
| 1628 // variable defined in the global object and not in any | 1651 // variable defined in the global object and not in any |
| 1629 // prototype. This way, global variable declarations can shadow | 1652 // prototype. This way, global variable declarations can shadow |
| 1630 // properties in the prototype chain, but only after the variable | 1653 // properties in the prototype chain, but only after the variable |
| 1631 // declaration statement has been executed. This is important in | 1654 // declaration statement has been executed. This is important in |
| 1632 // browsers where the global object (window) has lots of | 1655 // browsers where the global object (window) has lots of |
| 1633 // properties defined in prototype objects. | 1656 // properties defined in prototype objects. |
| 1634 | 1657 |
| 1635 if (top_scope_->is_global_scope()) { | 1658 if (top_scope_->is_global_scope()) { |
| 1636 // Compute the arguments for the runtime call. | 1659 // Compute the arguments for the runtime call. |
| 1637 ZoneList<Expression*>* arguments = new ZoneList<Expression*>(2); | 1660 ZoneList<Expression*>* arguments = new ZoneList<Expression*>(3); |
| 1638 // Be careful not to assign a value to the global variable if | |
| 1639 // we're in a with. The initialization value should not | |
| 1640 // necessarily be stored in the global object in that case, | |
| 1641 // which is why we need to generate a separate assignment node. | |
| 1642 arguments->Add(new Literal(name)); // we have at least 1 parameter | 1661 arguments->Add(new Literal(name)); // we have at least 1 parameter |
| 1643 if (is_const || (value != NULL && !inside_with())) { | 1662 CallRuntime* initialize; |
| 1663 |
| 1664 if (is_const) { |
| 1644 arguments->Add(value); | 1665 arguments->Add(value); |
| 1645 value = NULL; // zap the value to avoid the unnecessary assignment | 1666 value = NULL; // zap the value to avoid the unnecessary assignment |
| 1667 |
| 1668 // Construct the call to Runtime_InitializeConstGlobal |
| 1669 // and add it to the initialization statement block. |
| 1670 // Note that the function does different things depending on |
| 1671 // the number of arguments (1 or 2). |
| 1672 initialize = |
| 1673 new CallRuntime( |
| 1674 Factory::InitializeConstGlobal_symbol(), |
| 1675 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
| 1676 arguments); |
| 1677 } else { |
| 1678 // Add strict mode. |
| 1679 // We may want to pass singleton to avoid Literal allocations. |
| 1680 arguments->Add(NewNumberLiteral( |
| 1681 top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode)); |
| 1682 |
| 1683 // Be careful not to assign a value to the global variable if |
| 1684 // we're in a with. The initialization value should not |
| 1685 // necessarily be stored in the global object in that case, |
| 1686 // which is why we need to generate a separate assignment node. |
| 1687 if (value != NULL && !inside_with()) { |
| 1688 arguments->Add(value); |
| 1689 value = NULL; // zap the value to avoid the unnecessary assignment |
| 1690 } |
| 1691 |
| 1692 // Construct the call to Runtime_InitializeVarGlobal |
| 1693 // and add it to the initialization statement block. |
| 1694 // Note that the function does different things depending on |
| 1695 // the number of arguments (2 or 3). |
| 1696 initialize = |
| 1697 new CallRuntime( |
| 1698 Factory::InitializeVarGlobal_symbol(), |
| 1699 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), |
| 1700 arguments); |
| 1646 } | 1701 } |
| 1647 // Construct the call to Runtime::DeclareGlobal{Variable,Const}Locally | 1702 |
| 1648 // and add it to the initialization statement block. Note that | |
| 1649 // this function does different things depending on if we have | |
| 1650 // 1 or 2 parameters. | |
| 1651 CallRuntime* initialize; | |
| 1652 if (is_const) { | |
| 1653 initialize = | |
| 1654 new CallRuntime( | |
| 1655 Factory::InitializeConstGlobal_symbol(), | |
| 1656 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), | |
| 1657 arguments); | |
| 1658 } else { | |
| 1659 initialize = | |
| 1660 new CallRuntime( | |
| 1661 Factory::InitializeVarGlobal_symbol(), | |
| 1662 Runtime::FunctionForId(Runtime::kInitializeVarGlobal), | |
| 1663 arguments); | |
| 1664 } | |
| 1665 block->AddStatement(new ExpressionStatement(initialize)); | 1703 block->AddStatement(new ExpressionStatement(initialize)); |
| 1666 } | 1704 } |
| 1667 | 1705 |
| 1668 // Add an assignment node to the initialization statement block if | 1706 // Add an assignment node to the initialization statement block if |
| 1669 // we still have a pending initialization value. We must distinguish | 1707 // we still have a pending initialization value. We must distinguish |
| 1670 // between variables and constants: Variable initializations are simply | 1708 // between variables and constants: Variable initializations are simply |
| 1671 // assignments (with all the consequences if they are inside a 'with' | 1709 // assignments (with all the consequences if they are inside a 'with' |
| 1672 // statement - they may change a 'with' object property). Constant | 1710 // statement - they may change a 'with' object property). Constant |
| 1673 // initializations always assign to the declared constant which is | 1711 // initializations always assign to the declared constant which is |
| 1674 // always at the function scope level. This is only relevant for | 1712 // always at the function scope level. This is only relevant for |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1906 return result; | 1944 return result; |
| 1907 } | 1945 } |
| 1908 | 1946 |
| 1909 | 1947 |
| 1910 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 1948 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 1911 // WithStatement :: | 1949 // WithStatement :: |
| 1912 // 'with' '(' Expression ')' Statement | 1950 // 'with' '(' Expression ')' Statement |
| 1913 | 1951 |
| 1914 Expect(Token::WITH, CHECK_OK); | 1952 Expect(Token::WITH, CHECK_OK); |
| 1915 | 1953 |
| 1916 if (temp_scope_->StrictMode()) { | 1954 if (top_scope_->is_strict_mode()) { |
| 1917 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | 1955 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
| 1918 *ok = false; | 1956 *ok = false; |
| 1919 return NULL; | 1957 return NULL; |
| 1920 } | 1958 } |
| 1921 | 1959 |
| 1922 Expect(Token::LPAREN, CHECK_OK); | 1960 Expect(Token::LPAREN, CHECK_OK); |
| 1923 Expression* expr = ParseExpression(true, CHECK_OK); | 1961 Expression* expr = ParseExpression(true, CHECK_OK); |
| 1924 Expect(Token::RPAREN, CHECK_OK); | 1962 Expect(Token::RPAREN, CHECK_OK); |
| 1925 | 1963 |
| 1926 return WithHelper(expr, labels, false, CHECK_OK); | 1964 return WithHelper(expr, labels, false, CHECK_OK); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2045 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); | 2083 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); |
| 2046 TargetCollector catch_collector(catch_target_list); | 2084 TargetCollector catch_collector(catch_target_list); |
| 2047 bool has_catch = false; | 2085 bool has_catch = false; |
| 2048 if (tok == Token::CATCH) { | 2086 if (tok == Token::CATCH) { |
| 2049 has_catch = true; | 2087 has_catch = true; |
| 2050 Consume(Token::CATCH); | 2088 Consume(Token::CATCH); |
| 2051 | 2089 |
| 2052 Expect(Token::LPAREN, CHECK_OK); | 2090 Expect(Token::LPAREN, CHECK_OK); |
| 2053 Handle<String> name = ParseIdentifier(CHECK_OK); | 2091 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2054 | 2092 |
| 2055 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) { | 2093 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { |
| 2056 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); | 2094 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); |
| 2057 *ok = false; | 2095 *ok = false; |
| 2058 return NULL; | 2096 return NULL; |
| 2059 } | 2097 } |
| 2060 | 2098 |
| 2061 Expect(Token::RPAREN, CHECK_OK); | 2099 Expect(Token::RPAREN, CHECK_OK); |
| 2062 | 2100 |
| 2063 if (peek() == Token::LBRACE) { | 2101 if (peek() == Token::LBRACE) { |
| 2064 // Allocate a temporary for holding the finally state while | 2102 // Allocate a temporary for holding the finally state while |
| 2065 // executing the finally block. | 2103 // executing the finally block. |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2296 | 2334 |
| 2297 // Signal a reference error if the expression is an invalid left-hand | 2335 // Signal a reference error if the expression is an invalid left-hand |
| 2298 // side expression. We could report this as a syntax error here but | 2336 // side expression. We could report this as a syntax error here but |
| 2299 // for compatibility with JSC we choose to report the error at | 2337 // for compatibility with JSC we choose to report the error at |
| 2300 // runtime. | 2338 // runtime. |
| 2301 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2339 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2302 Handle<String> type = Factory::invalid_lhs_in_assignment_symbol(); | 2340 Handle<String> type = Factory::invalid_lhs_in_assignment_symbol(); |
| 2303 expression = NewThrowReferenceError(type); | 2341 expression = NewThrowReferenceError(type); |
| 2304 } | 2342 } |
| 2305 | 2343 |
| 2306 if (temp_scope_->StrictMode()) { | 2344 if (top_scope_->is_strict_mode()) { |
| 2307 // Assignment to eval or arguments is disallowed in strict mode. | 2345 // Assignment to eval or arguments is disallowed in strict mode. |
| 2308 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); | 2346 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); |
| 2309 } | 2347 } |
| 2310 | 2348 |
| 2311 Token::Value op = Next(); // Get assignment operator. | 2349 Token::Value op = Next(); // Get assignment operator. |
| 2312 int pos = scanner().location().beg_pos; | 2350 int pos = scanner().location().beg_pos; |
| 2313 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2351 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2314 | 2352 |
| 2315 // TODO(1231235): We try to estimate the set of properties set by | 2353 // TODO(1231235): We try to estimate the set of properties set by |
| 2316 // constructors. We define a new property whenever there is an | 2354 // constructors. We define a new property whenever there is an |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2515 return expression; | 2553 return expression; |
| 2516 case Token::SUB: | 2554 case Token::SUB: |
| 2517 return NewNumberLiteral(-value); | 2555 return NewNumberLiteral(-value); |
| 2518 case Token::BIT_NOT: | 2556 case Token::BIT_NOT: |
| 2519 return NewNumberLiteral(~DoubleToInt32(value)); | 2557 return NewNumberLiteral(~DoubleToInt32(value)); |
| 2520 default: break; | 2558 default: break; |
| 2521 } | 2559 } |
| 2522 } | 2560 } |
| 2523 | 2561 |
| 2524 // "delete identifier" is a syntax error in strict mode. | 2562 // "delete identifier" is a syntax error in strict mode. |
| 2525 if (op == Token::DELETE && temp_scope_->StrictMode()) { | 2563 if (op == Token::DELETE && top_scope_->is_strict_mode()) { |
| 2526 VariableProxy* operand = expression->AsVariableProxy(); | 2564 VariableProxy* operand = expression->AsVariableProxy(); |
| 2527 if (operand != NULL && !operand->is_this()) { | 2565 if (operand != NULL && !operand->is_this()) { |
| 2528 ReportMessage("strict_delete", Vector<const char*>::empty()); | 2566 ReportMessage("strict_delete", Vector<const char*>::empty()); |
| 2529 *ok = false; | 2567 *ok = false; |
| 2530 return NULL; | 2568 return NULL; |
| 2531 } | 2569 } |
| 2532 } | 2570 } |
| 2533 | 2571 |
| 2534 return new UnaryOperation(op, expression); | 2572 return new UnaryOperation(op, expression); |
| 2535 | 2573 |
| 2536 } else if (Token::IsCountOp(op)) { | 2574 } else if (Token::IsCountOp(op)) { |
| 2537 op = Next(); | 2575 op = Next(); |
| 2538 Expression* expression = ParseUnaryExpression(CHECK_OK); | 2576 Expression* expression = ParseUnaryExpression(CHECK_OK); |
| 2539 // Signal a reference error if the expression is an invalid | 2577 // Signal a reference error if the expression is an invalid |
| 2540 // left-hand side expression. We could report this as a syntax | 2578 // left-hand side expression. We could report this as a syntax |
| 2541 // error here but for compatibility with JSC we choose to report the | 2579 // error here but for compatibility with JSC we choose to report the |
| 2542 // error at runtime. | 2580 // error at runtime. |
| 2543 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2581 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2544 Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol(); | 2582 Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol(); |
| 2545 expression = NewThrowReferenceError(type); | 2583 expression = NewThrowReferenceError(type); |
| 2546 } | 2584 } |
| 2547 | 2585 |
| 2548 if (temp_scope_->StrictMode()) { | 2586 if (top_scope_->is_strict_mode()) { |
| 2549 // Prefix expression operand in strict mode may not be eval or arguments. | 2587 // Prefix expression operand in strict mode may not be eval or arguments. |
| 2550 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 2588 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 2551 } | 2589 } |
| 2552 | 2590 |
| 2553 int position = scanner().location().beg_pos; | 2591 int position = scanner().location().beg_pos; |
| 2554 IncrementOperation* increment = new IncrementOperation(op, expression); | 2592 IncrementOperation* increment = new IncrementOperation(op, expression); |
| 2555 return new CountOperation(true /* prefix */, increment, position); | 2593 return new CountOperation(true /* prefix */, increment, position); |
| 2556 | 2594 |
| 2557 } else { | 2595 } else { |
| 2558 return ParsePostfixExpression(ok); | 2596 return ParsePostfixExpression(ok); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2569 Token::IsCountOp(peek())) { | 2607 Token::IsCountOp(peek())) { |
| 2570 // Signal a reference error if the expression is an invalid | 2608 // Signal a reference error if the expression is an invalid |
| 2571 // left-hand side expression. We could report this as a syntax | 2609 // left-hand side expression. We could report this as a syntax |
| 2572 // error here but for compatibility with JSC we choose to report the | 2610 // error here but for compatibility with JSC we choose to report the |
| 2573 // error at runtime. | 2611 // error at runtime. |
| 2574 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2612 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2575 Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol(); | 2613 Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol(); |
| 2576 expression = NewThrowReferenceError(type); | 2614 expression = NewThrowReferenceError(type); |
| 2577 } | 2615 } |
| 2578 | 2616 |
| 2579 if (temp_scope_->StrictMode()) { | 2617 if (top_scope_->is_strict_mode()) { |
| 2580 // Postfix expression operand in strict mode may not be eval or arguments. | 2618 // Postfix expression operand in strict mode may not be eval or arguments. |
| 2581 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 2619 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 2582 } | 2620 } |
| 2583 | 2621 |
| 2584 Token::Value next = Next(); | 2622 Token::Value next = Next(); |
| 2585 int position = scanner().location().beg_pos; | 2623 int position = scanner().location().beg_pos; |
| 2586 IncrementOperation* increment = new IncrementOperation(next, expression); | 2624 IncrementOperation* increment = new IncrementOperation(next, expression); |
| 2587 expression = new CountOperation(false /* postfix */, increment, position); | 2625 expression = new CountOperation(false /* postfix */, increment, position); |
| 2588 } | 2626 } |
| 2589 return expression; | 2627 return expression; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2777 case Token::NUMBER: | 2815 case Token::NUMBER: |
| 2778 return ReportMessage("unexpected_token_number", | 2816 return ReportMessage("unexpected_token_number", |
| 2779 Vector<const char*>::empty()); | 2817 Vector<const char*>::empty()); |
| 2780 case Token::STRING: | 2818 case Token::STRING: |
| 2781 return ReportMessage("unexpected_token_string", | 2819 return ReportMessage("unexpected_token_string", |
| 2782 Vector<const char*>::empty()); | 2820 Vector<const char*>::empty()); |
| 2783 case Token::IDENTIFIER: | 2821 case Token::IDENTIFIER: |
| 2784 return ReportMessage("unexpected_token_identifier", | 2822 return ReportMessage("unexpected_token_identifier", |
| 2785 Vector<const char*>::empty()); | 2823 Vector<const char*>::empty()); |
| 2786 case Token::FUTURE_RESERVED_WORD: | 2824 case Token::FUTURE_RESERVED_WORD: |
| 2787 return ReportMessage(temp_scope_->StrictMode() ? | 2825 return ReportMessage(top_scope_->is_strict_mode() ? |
| 2788 "unexpected_strict_reserved" : | 2826 "unexpected_strict_reserved" : |
| 2789 "unexpected_token_identifier", | 2827 "unexpected_token_identifier", |
| 2790 Vector<const char*>::empty()); | 2828 Vector<const char*>::empty()); |
| 2791 default: | 2829 default: |
| 2792 const char* name = Token::String(token); | 2830 const char* name = Token::String(token); |
| 2793 ASSERT(name != NULL); | 2831 ASSERT(name != NULL); |
| 2794 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); | 2832 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); |
| 2795 } | 2833 } |
| 2796 } | 2834 } |
| 2797 | 2835 |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3282 // ObjectLiteral :: | 3320 // ObjectLiteral :: |
| 3283 // '{' ( | 3321 // '{' ( |
| 3284 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 3322 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 3285 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 3323 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 3286 // )*[','] '}' | 3324 // )*[','] '}' |
| 3287 | 3325 |
| 3288 ZoneList<ObjectLiteral::Property*>* properties = | 3326 ZoneList<ObjectLiteral::Property*>* properties = |
| 3289 new ZoneList<ObjectLiteral::Property*>(4); | 3327 new ZoneList<ObjectLiteral::Property*>(4); |
| 3290 int number_of_boilerplate_properties = 0; | 3328 int number_of_boilerplate_properties = 0; |
| 3291 | 3329 |
| 3292 ObjectLiteralPropertyChecker checker(this, temp_scope_->StrictMode()); | 3330 ObjectLiteralPropertyChecker checker(this, top_scope_->is_strict_mode()); |
| 3293 | 3331 |
| 3294 Expect(Token::LBRACE, CHECK_OK); | 3332 Expect(Token::LBRACE, CHECK_OK); |
| 3295 Scanner::Location loc = scanner().location(); | 3333 Scanner::Location loc = scanner().location(); |
| 3296 | 3334 |
| 3297 while (peek() != Token::RBRACE) { | 3335 while (peek() != Token::RBRACE) { |
| 3298 if (fni_ != NULL) fni_->Enter(); | 3336 if (fni_ != NULL) fni_->Enter(); |
| 3299 | 3337 |
| 3300 Literal* key = NULL; | 3338 Literal* key = NULL; |
| 3301 Token::Value next = peek(); | 3339 Token::Value next = peek(); |
| 3302 | 3340 |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3579 expected_property_count = temp_scope.expected_property_count(); | 3617 expected_property_count = temp_scope.expected_property_count(); |
| 3580 only_simple_this_property_assignments = | 3618 only_simple_this_property_assignments = |
| 3581 temp_scope.only_simple_this_property_assignments(); | 3619 temp_scope.only_simple_this_property_assignments(); |
| 3582 this_property_assignments = temp_scope.this_property_assignments(); | 3620 this_property_assignments = temp_scope.this_property_assignments(); |
| 3583 | 3621 |
| 3584 Expect(Token::RBRACE, CHECK_OK); | 3622 Expect(Token::RBRACE, CHECK_OK); |
| 3585 end_pos = scanner().location().end_pos; | 3623 end_pos = scanner().location().end_pos; |
| 3586 } | 3624 } |
| 3587 | 3625 |
| 3588 // Validate strict mode. | 3626 // Validate strict mode. |
| 3589 if (temp_scope_->StrictMode()) { | 3627 if (top_scope_->is_strict_mode()) { |
| 3590 if (IsEvalOrArguments(name)) { | 3628 if (IsEvalOrArguments(name)) { |
| 3591 int position = function_token_position != RelocInfo::kNoPosition | 3629 int position = function_token_position != RelocInfo::kNoPosition |
| 3592 ? function_token_position | 3630 ? function_token_position |
| 3593 : (start_pos > 0 ? start_pos - 1 : start_pos); | 3631 : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 3594 Scanner::Location location = Scanner::Location(position, start_pos); | 3632 Scanner::Location location = Scanner::Location(position, start_pos); |
| 3595 ReportMessageAt(location, | 3633 ReportMessageAt(location, |
| 3596 "strict_function_name", Vector<const char*>::empty()); | 3634 "strict_function_name", Vector<const char*>::empty()); |
| 3597 *ok = false; | 3635 *ok = false; |
| 3598 return NULL; | 3636 return NULL; |
| 3599 } | 3637 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3633 top_scope_, | 3671 top_scope_, |
| 3634 body, | 3672 body, |
| 3635 materialized_literal_count, | 3673 materialized_literal_count, |
| 3636 expected_property_count, | 3674 expected_property_count, |
| 3637 only_simple_this_property_assignments, | 3675 only_simple_this_property_assignments, |
| 3638 this_property_assignments, | 3676 this_property_assignments, |
| 3639 num_parameters, | 3677 num_parameters, |
| 3640 start_pos, | 3678 start_pos, |
| 3641 end_pos, | 3679 end_pos, |
| 3642 function_name->length() > 0, | 3680 function_name->length() > 0, |
| 3643 temp_scope.ContainsLoops(), | 3681 temp_scope.ContainsLoops()); |
| 3644 temp_scope.StrictMode()); | |
| 3645 function_literal->set_function_token_position(function_token_position); | 3682 function_literal->set_function_token_position(function_token_position); |
| 3646 | 3683 |
| 3647 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); | 3684 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); |
| 3648 return function_literal; | 3685 return function_literal; |
| 3649 } | 3686 } |
| 3650 } | 3687 } |
| 3651 | 3688 |
| 3652 | 3689 |
| 3653 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3690 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3654 // CallRuntime :: | 3691 // CallRuntime :: |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3763 | 3800 |
| 3764 Handle<String> Parser::ParseIdentifier(bool* ok) { | 3801 Handle<String> Parser::ParseIdentifier(bool* ok) { |
| 3765 bool is_reserved; | 3802 bool is_reserved; |
| 3766 return ParseIdentifierOrReservedWord(&is_reserved, ok); | 3803 return ParseIdentifierOrReservedWord(&is_reserved, ok); |
| 3767 } | 3804 } |
| 3768 | 3805 |
| 3769 | 3806 |
| 3770 Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved, | 3807 Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved, |
| 3771 bool* ok) { | 3808 bool* ok) { |
| 3772 *is_reserved = false; | 3809 *is_reserved = false; |
| 3773 if (temp_scope_->StrictMode()) { | 3810 if (top_scope_->is_strict_mode()) { |
| 3774 Expect(Token::IDENTIFIER, ok); | 3811 Expect(Token::IDENTIFIER, ok); |
| 3775 } else { | 3812 } else { |
| 3776 if (!Check(Token::IDENTIFIER)) { | 3813 if (!Check(Token::IDENTIFIER)) { |
| 3777 Expect(Token::FUTURE_RESERVED_WORD, ok); | 3814 Expect(Token::FUTURE_RESERVED_WORD, ok); |
| 3778 *is_reserved = true; | 3815 *is_reserved = true; |
| 3779 } | 3816 } |
| 3780 } | 3817 } |
| 3781 if (!*ok) return Handle<String>(); | 3818 if (!*ok) return Handle<String>(); |
| 3782 return GetSymbol(ok); | 3819 return GetSymbol(ok); |
| 3783 } | 3820 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3794 } | 3831 } |
| 3795 return GetSymbol(ok); | 3832 return GetSymbol(ok); |
| 3796 } | 3833 } |
| 3797 | 3834 |
| 3798 | 3835 |
| 3799 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 3836 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
| 3800 // in strict mode. | 3837 // in strict mode. |
| 3801 void Parser::CheckStrictModeLValue(Expression* expression, | 3838 void Parser::CheckStrictModeLValue(Expression* expression, |
| 3802 const char* error, | 3839 const char* error, |
| 3803 bool* ok) { | 3840 bool* ok) { |
| 3804 ASSERT(temp_scope_->StrictMode()); | 3841 ASSERT(top_scope_->is_strict_mode()); |
| 3805 VariableProxy* lhs = expression != NULL | 3842 VariableProxy* lhs = expression != NULL |
| 3806 ? expression->AsVariableProxy() | 3843 ? expression->AsVariableProxy() |
| 3807 : NULL; | 3844 : NULL; |
| 3808 | 3845 |
| 3809 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 3846 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 3810 ReportMessage(error, Vector<const char*>::empty()); | 3847 ReportMessage(error, Vector<const char*>::empty()); |
| 3811 *ok = false; | 3848 *ok = false; |
| 3812 } | 3849 } |
| 3813 } | 3850 } |
| 3814 | 3851 |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3986 message = "unexpected_token"; | 4023 message = "unexpected_token"; |
| 3987 name_opt = Token::String(token); | 4024 name_opt = Token::String(token); |
| 3988 ASSERT(name_opt != NULL); | 4025 ASSERT(name_opt != NULL); |
| 3989 break; | 4026 break; |
| 3990 } | 4027 } |
| 3991 | 4028 |
| 3992 Scanner::Location source_location = scanner_.location(); | 4029 Scanner::Location source_location = scanner_.location(); |
| 3993 MessageLocation location(Factory::NewScript(script), | 4030 MessageLocation location(Factory::NewScript(script), |
| 3994 source_location.beg_pos, | 4031 source_location.beg_pos, |
| 3995 source_location.end_pos); | 4032 source_location.end_pos); |
| 3996 int argc = (name_opt == NULL) ? 0 : 1; | 4033 Handle<JSArray> array; |
| 3997 Handle<JSArray> array = Factory::NewJSArray(argc); | 4034 if (name_opt == NULL) { |
| 3998 if (name_opt != NULL) { | 4035 array = Factory::NewJSArray(0); |
| 3999 SetElement(array, | 4036 } else { |
| 4000 0, | 4037 Handle<String> name = Factory::NewStringFromUtf8(CStrVector(name_opt)); |
| 4001 Factory::NewStringFromUtf8(CStrVector(name_opt))); | 4038 Handle<FixedArray> element = Factory::NewFixedArray(1); |
| 4039 element->set(0, *name); |
| 4040 array = Factory::NewJSArrayWithElements(element); |
| 4002 } | 4041 } |
| 4003 Handle<Object> result = Factory::NewSyntaxError(message, array); | 4042 Handle<Object> result = Factory::NewSyntaxError(message, array); |
| 4004 Top::Throw(*result, &location); | 4043 Top::Throw(*result, &location); |
| 4005 return Handle<Object>::null(); | 4044 return Handle<Object>::null(); |
| 4006 } | 4045 } |
| 4007 } | 4046 } |
| 4008 return result; | 4047 return result; |
| 4009 } | 4048 } |
| 4010 | 4049 |
| 4011 | 4050 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4063 return ReportUnexpectedToken(); | 4102 return ReportUnexpectedToken(); |
| 4064 } | 4103 } |
| 4065 Handle<String> key = GetString(); | 4104 Handle<String> key = GetString(); |
| 4066 if (scanner_.Next() != Token::COLON) { | 4105 if (scanner_.Next() != Token::COLON) { |
| 4067 return ReportUnexpectedToken(); | 4106 return ReportUnexpectedToken(); |
| 4068 } | 4107 } |
| 4069 Handle<Object> value = ParseJsonValue(); | 4108 Handle<Object> value = ParseJsonValue(); |
| 4070 if (value.is_null()) return Handle<Object>::null(); | 4109 if (value.is_null()) return Handle<Object>::null(); |
| 4071 uint32_t index; | 4110 uint32_t index; |
| 4072 if (key->AsArrayIndex(&index)) { | 4111 if (key->AsArrayIndex(&index)) { |
| 4073 SetOwnElement(json_object, index, value); | 4112 SetOwnElement(json_object, index, value, kNonStrictMode); |
| 4074 } else if (key->Equals(Heap::Proto_symbol())) { | 4113 } else if (key->Equals(Heap::Proto_symbol())) { |
| 4075 // We can't remove the __proto__ accessor since it's hardcoded | 4114 // We can't remove the __proto__ accessor since it's hardcoded |
| 4076 // in several places. Instead go along and add the value as | 4115 // in several places. Instead go along and add the value as |
| 4077 // the prototype of the created object if possible. | 4116 // the prototype of the created object if possible. |
| 4078 SetPrototype(json_object, value); | 4117 SetPrototype(json_object, value); |
| 4079 } else { | 4118 } else { |
| 4080 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE); | 4119 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE); |
| 4081 } | 4120 } |
| 4082 } while (scanner_.Next() == Token::COMMA); | 4121 } while (scanner_.Next() == Token::COMMA); |
| 4083 if (scanner_.current_token() != Token::RBRACE) { | 4122 if (scanner_.current_token() != Token::RBRACE) { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4266 body = capture; | 4305 body = capture; |
| 4267 } else if (type != GROUPING) { | 4306 } else if (type != GROUPING) { |
| 4268 ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD); | 4307 ASSERT(type == POSITIVE_LOOKAHEAD || type == NEGATIVE_LOOKAHEAD); |
| 4269 bool is_positive = (type == POSITIVE_LOOKAHEAD); | 4308 bool is_positive = (type == POSITIVE_LOOKAHEAD); |
| 4270 body = new RegExpLookahead(body, | 4309 body = new RegExpLookahead(body, |
| 4271 is_positive, | 4310 is_positive, |
| 4272 end_capture_index - capture_index, | 4311 end_capture_index - capture_index, |
| 4273 capture_index); | 4312 capture_index); |
| 4274 } | 4313 } |
| 4275 builder->AddAtom(body); | 4314 builder->AddAtom(body); |
| 4315 // For compatability with JSC and ES3, we allow quantifiers after |
| 4316 // lookaheads, and break in all cases. |
| 4276 break; | 4317 break; |
| 4277 } | 4318 } |
| 4278 case '|': { | 4319 case '|': { |
| 4279 Advance(); | 4320 Advance(); |
| 4280 builder->NewAlternative(); | 4321 builder->NewAlternative(); |
| 4281 continue; | 4322 continue; |
| 4282 } | 4323 } |
| 4283 case '*': | 4324 case '*': |
| 4284 case '+': | 4325 case '+': |
| 4285 case '?': | 4326 case '?': |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4339 if (captures_started() >= kMaxCaptures) { | 4380 if (captures_started() >= kMaxCaptures) { |
| 4340 ReportError(CStrVector("Too many captures") CHECK_FAILED); | 4381 ReportError(CStrVector("Too many captures") CHECK_FAILED); |
| 4341 } | 4382 } |
| 4342 captures_->Add(NULL); | 4383 captures_->Add(NULL); |
| 4343 } | 4384 } |
| 4344 // Store current state and begin new disjunction parsing. | 4385 // Store current state and begin new disjunction parsing. |
| 4345 stored_state = new RegExpParserState(stored_state, | 4386 stored_state = new RegExpParserState(stored_state, |
| 4346 type, | 4387 type, |
| 4347 captures_started()); | 4388 captures_started()); |
| 4348 builder = stored_state->builder(); | 4389 builder = stored_state->builder(); |
| 4349 break; | 4390 continue; |
| 4350 } | 4391 } |
| 4351 case '[': { | 4392 case '[': { |
| 4352 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED); | 4393 RegExpTree* atom = ParseCharacterClass(CHECK_FAILED); |
| 4353 builder->AddAtom(atom); | 4394 builder->AddAtom(atom); |
| 4354 break; | 4395 break; |
| 4355 } | 4396 } |
| 4356 // Atom :: | 4397 // Atom :: |
| 4357 // \ AtomEscape | 4398 // \ AtomEscape |
| 4358 case '\\': | 4399 case '\\': |
| 4359 switch (Next()) { | 4400 switch (Next()) { |
| 4360 case kEndMarker: | 4401 case kEndMarker: |
| 4361 return ReportError(CStrVector("\\ at end of pattern")); | 4402 return ReportError(CStrVector("\\ at end of pattern")); |
| 4362 case 'b': | 4403 case 'b': |
| 4363 Advance(2); | 4404 Advance(2); |
| 4364 builder->AddAssertion( | 4405 builder->AddAssertion( |
| 4365 new RegExpAssertion(RegExpAssertion::BOUNDARY)); | 4406 new RegExpAssertion(RegExpAssertion::BOUNDARY)); |
| 4366 continue; | 4407 continue; |
| 4367 case 'B': | 4408 case 'B': |
| 4368 Advance(2); | 4409 Advance(2); |
| 4369 builder->AddAssertion( | 4410 builder->AddAssertion( |
| 4370 new RegExpAssertion(RegExpAssertion::NON_BOUNDARY)); | 4411 new RegExpAssertion(RegExpAssertion::NON_BOUNDARY)); |
| 4371 continue; | 4412 continue; |
| 4372 // AtomEscape :: | 4413 // AtomEscape :: |
| 4373 // CharacterClassEscape | 4414 // CharacterClassEscape |
| 4374 // | 4415 // |
| 4375 // CharacterClassEscape :: one of | 4416 // CharacterClassEscape :: one of |
| 4376 // d D s S w W | 4417 // d D s S w W |
| 4377 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': { | 4418 case 'd': case 'D': case 's': case 'S': case 'w': case 'W': { |
| 4378 uc32 c = Next(); | 4419 uc32 c = Next(); |
| 4379 Advance(2); | 4420 Advance(2); |
| 4380 ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2); | 4421 ZoneList<CharacterRange>* ranges = new ZoneList<CharacterRange>(2); |
| 4381 CharacterRange::AddClassEscape(c, ranges); | 4422 CharacterRange::AddClassEscape(c, ranges); |
| 4382 RegExpTree* atom = new RegExpCharacterClass(ranges, false); | 4423 RegExpTree* atom = new RegExpCharacterClass(ranges, false); |
| 4383 builder->AddAtom(atom); | 4424 builder->AddAtom(atom); |
| 4384 break; | 4425 break; |
| 4385 } | 4426 } |
| 4386 case '1': case '2': case '3': case '4': case '5': case '6': | 4427 case '1': case '2': case '3': case '4': case '5': case '6': |
| (...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5082 return !parser.failed(); | 5123 return !parser.failed(); |
| 5083 } | 5124 } |
| 5084 | 5125 |
| 5085 | 5126 |
| 5086 bool ParserApi::Parse(CompilationInfo* info) { | 5127 bool ParserApi::Parse(CompilationInfo* info) { |
| 5087 ASSERT(info->function() == NULL); | 5128 ASSERT(info->function() == NULL); |
| 5088 FunctionLiteral* result = NULL; | 5129 FunctionLiteral* result = NULL; |
| 5089 Handle<Script> script = info->script(); | 5130 Handle<Script> script = info->script(); |
| 5090 if (info->is_lazy()) { | 5131 if (info->is_lazy()) { |
| 5091 Parser parser(script, true, NULL, NULL); | 5132 Parser parser(script, true, NULL, NULL); |
| 5092 result = parser.ParseLazy(info->shared_info()); | 5133 result = parser.ParseLazy(info); |
| 5093 } else { | 5134 } else { |
| 5094 bool allow_natives_syntax = | 5135 bool allow_natives_syntax = |
| 5095 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); | 5136 info->allows_natives_syntax() || FLAG_allow_natives_syntax; |
| 5096 ScriptDataImpl* pre_data = info->pre_parse_data(); | 5137 ScriptDataImpl* pre_data = info->pre_parse_data(); |
| 5097 Parser parser(script, allow_natives_syntax, info->extension(), pre_data); | 5138 Parser parser(script, allow_natives_syntax, info->extension(), pre_data); |
| 5098 if (pre_data != NULL && pre_data->has_error()) { | 5139 if (pre_data != NULL && pre_data->has_error()) { |
| 5099 Scanner::Location loc = pre_data->MessageLocation(); | 5140 Scanner::Location loc = pre_data->MessageLocation(); |
| 5100 const char* message = pre_data->BuildMessage(); | 5141 const char* message = pre_data->BuildMessage(); |
| 5101 Vector<const char*> args = pre_data->BuildArgs(); | 5142 Vector<const char*> args = pre_data->BuildArgs(); |
| 5102 parser.ReportMessageAt(loc, message, args); | 5143 parser.ReportMessageAt(loc, message, args); |
| 5103 DeleteArray(message); | 5144 DeleteArray(message); |
| 5104 for (int i = 0; i < args.length(); i++) { | 5145 for (int i = 0; i < args.length(); i++) { |
| 5105 DeleteArray(args[i]); | 5146 DeleteArray(args[i]); |
| 5106 } | 5147 } |
| 5107 DeleteArray(args.start()); | 5148 DeleteArray(args.start()); |
| 5108 ASSERT(Top::has_pending_exception()); | 5149 ASSERT(Top::has_pending_exception()); |
| 5109 } else { | 5150 } else { |
| 5110 Handle<String> source = Handle<String>(String::cast(script->source())); | 5151 Handle<String> source = Handle<String>(String::cast(script->source())); |
| 5111 result = parser.ParseProgram(source, | 5152 result = parser.ParseProgram(source, |
| 5112 info->is_global(), | 5153 info->is_global(), |
| 5113 info->StrictMode()); | 5154 info->StrictMode()); |
| 5114 } | 5155 } |
| 5115 } | 5156 } |
| 5116 | 5157 |
| 5117 info->SetFunction(result); | 5158 info->SetFunction(result); |
| 5118 return (result != NULL); | 5159 return (result != NULL); |
| 5119 } | 5160 } |
| 5120 | 5161 |
| 5121 } } // namespace v8::internal | 5162 } } // namespace v8::internal |
| OLD | NEW |