Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(503)

Side by Side Diff: src/parser.cc

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/platform.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/platform.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698