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

Side by Side Diff: src/parser.cc

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 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
286 private: 291 private:
287 // Captures the number of literals that need materialization in the 292 // Captures the number of literals that need materialization in the
288 // function. Includes regexp literals, and boilerplate for object 293 // function. Includes regexp literals, and boilerplate for object
289 // and array literals. 294 // and array literals.
290 int materialized_literal_count_; 295 int materialized_literal_count_;
291 296
292 // Properties count estimation. 297 // Properties count estimation.
293 int expected_property_count_; 298 int expected_property_count_;
294 299
295 // Keeps track of assignments to properties of this. Used for 300 // Keeps track of assignments to properties of this. Used for
296 // optimizing constructors. 301 // optimizing constructors.
297 bool only_simple_this_property_assignments_; 302 bool only_simple_this_property_assignments_;
298 Handle<FixedArray> this_property_assignments_; 303 Handle<FixedArray> this_property_assignments_;
299 304
300 // Captures the number of loops inside the scope. 305 // Captures the number of loops inside the scope.
301 int loop_count_; 306 int loop_count_;
302 307
308 // Parsing strict mode code.
309 bool strict_mode_;
310
303 // Bookkeeping 311 // Bookkeeping
304 TemporaryScope** variable_; 312 TemporaryScope** variable_;
305 TemporaryScope* parent_; 313 TemporaryScope* parent_;
306 }; 314 };
307 315
308 316
309 TemporaryScope::TemporaryScope(TemporaryScope** variable) 317 TemporaryScope::TemporaryScope(TemporaryScope** variable)
310 : materialized_literal_count_(0), 318 : materialized_literal_count_(0),
311 expected_property_count_(0), 319 expected_property_count_(0),
312 only_simple_this_property_assignments_(false), 320 only_simple_this_property_assignments_(false),
313 this_property_assignments_(Factory::empty_fixed_array()), 321 this_property_assignments_(Factory::empty_fixed_array()),
314 loop_count_(0), 322 loop_count_(0),
315 variable_(variable), 323 variable_(variable),
316 parent_(*variable) { 324 parent_(*variable) {
325 // Inherit the strict mode from the parent scope.
326 strict_mode_ = (parent_ != NULL) && parent_->strict_mode_;
317 *variable = this; 327 *variable = this;
318 } 328 }
319 329
320 330
321 TemporaryScope::~TemporaryScope() { 331 TemporaryScope::~TemporaryScope() {
322 *variable_ = parent_; 332 *variable_ = parent_;
323 } 333 }
324 334
325 335
326 Handle<String> Parser::LookupSymbol(int symbol_id) { 336 Handle<String> Parser::LookupSymbol(int symbol_id) {
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 *with_nesting_level_variable_ = prev_level_; 564 *with_nesting_level_variable_ = prev_level_;
555 } 565 }
556 566
557 private: 567 private:
558 Scope** scope_variable_; 568 Scope** scope_variable_;
559 int* with_nesting_level_variable_; 569 int* with_nesting_level_variable_;
560 Scope* prev_scope_; 570 Scope* prev_scope_;
561 int prev_level_; 571 int prev_level_;
562 }; 572 };
563 573
564
565 // ---------------------------------------------------------------------------- 574 // ----------------------------------------------------------------------------
566 // The CHECK_OK macro is a convenient macro to enforce error 575 // The CHECK_OK macro is a convenient macro to enforce error
567 // handling for functions that may fail (by returning !*ok). 576 // handling for functions that may fail (by returning !*ok).
568 // 577 //
569 // CAUTION: This macro appends extra statements after a call, 578 // CAUTION: This macro appends extra statements after a call,
570 // thus it must never be used where only a single statement 579 // thus it must never be used where only a single statement
571 // is correct (e.g. an if statement branch w/o braces)! 580 // is correct (e.g. an if statement branch w/o braces)!
572 581
573 #define CHECK_OK ok); \ 582 #define CHECK_OK ok); \
574 if (!*ok) return NULL; \ 583 if (!*ok) return NULL; \
(...skipping 18 matching lines...) Expand all
593 script_(script), 602 script_(script),
594 scanner_(), 603 scanner_(),
595 top_scope_(NULL), 604 top_scope_(NULL),
596 with_nesting_level_(0), 605 with_nesting_level_(0),
597 temp_scope_(NULL), 606 temp_scope_(NULL),
598 target_stack_(NULL), 607 target_stack_(NULL),
599 allow_natives_syntax_(allow_natives_syntax), 608 allow_natives_syntax_(allow_natives_syntax),
600 extension_(extension), 609 extension_(extension),
601 pre_data_(pre_data), 610 pre_data_(pre_data),
602 fni_(NULL), 611 fni_(NULL),
603 stack_overflow_(false) { 612 stack_overflow_(false),
613 parenthesized_function_(false) {
604 AstNode::ResetIds(); 614 AstNode::ResetIds();
605 } 615 }
606 616
607 617
608 FunctionLiteral* Parser::ParseProgram(Handle<String> source, 618 FunctionLiteral* Parser::ParseProgram(Handle<String> source,
609 bool in_global_context) { 619 bool in_global_context,
620 StrictModeFlag strict_mode) {
610 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); 621 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
611 622
612 HistogramTimerScope timer(&Counters::parse); 623 HistogramTimerScope timer(&Counters::parse);
613 Counters::total_parse_size.Increment(source->length()); 624 Counters::total_parse_size.Increment(source->length());
614 fni_ = new FuncNameInferrer(); 625 fni_ = new FuncNameInferrer();
615 626
616 // Initialize parser state. 627 // Initialize parser state.
617 source->TryFlatten(); 628 source->TryFlatten();
618 if (source->IsExternalTwoByteString()) { 629 if (source->IsExternalTwoByteString()) {
619 // Notice that the stream is destroyed at the end of the branch block. 630 // Notice that the stream is destroyed at the end of the branch block.
620 // The last line of the blocks can't be moved outside, even though they're 631 // The last line of the blocks can't be moved outside, even though they're
621 // identical calls. 632 // identical calls.
622 ExternalTwoByteStringUC16CharacterStream stream( 633 ExternalTwoByteStringUC16CharacterStream stream(
623 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 634 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
624 scanner_.Initialize(&stream); 635 scanner_.Initialize(&stream);
625 return DoParseProgram(source, in_global_context, &zone_scope); 636 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope);
626 } else { 637 } else {
627 GenericStringUC16CharacterStream stream(source, 0, source->length()); 638 GenericStringUC16CharacterStream stream(source, 0, source->length());
628 scanner_.Initialize(&stream); 639 scanner_.Initialize(&stream);
629 return DoParseProgram(source, in_global_context, &zone_scope); 640 return DoParseProgram(source, in_global_context, strict_mode, &zone_scope);
630 } 641 }
631 } 642 }
632 643
633 644
634 FunctionLiteral* Parser::DoParseProgram(Handle<String> source, 645 FunctionLiteral* Parser::DoParseProgram(Handle<String> source,
635 bool in_global_context, 646 bool in_global_context,
647 StrictModeFlag strict_mode,
636 ZoneScope* zone_scope) { 648 ZoneScope* zone_scope) {
637 ASSERT(target_stack_ == NULL); 649 ASSERT(target_stack_ == NULL);
638 if (pre_data_ != NULL) pre_data_->Initialize(); 650 if (pre_data_ != NULL) pre_data_->Initialize();
639 651
640 // Compute the parsing mode. 652 // Compute the parsing mode.
641 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; 653 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY;
642 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; 654 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
643 655
644 Scope::Type type = 656 Scope::Type type =
645 in_global_context 657 in_global_context
646 ? Scope::GLOBAL_SCOPE 658 ? Scope::GLOBAL_SCOPE
647 : Scope::EVAL_SCOPE; 659 : Scope::EVAL_SCOPE;
648 Handle<String> no_name = Factory::empty_symbol(); 660 Handle<String> no_name = Factory::empty_symbol();
649 661
650 FunctionLiteral* result = NULL; 662 FunctionLiteral* result = NULL;
651 { Scope* scope = NewScope(top_scope_, type, inside_with()); 663 { Scope* scope = NewScope(top_scope_, type, inside_with());
652 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, 664 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
653 scope); 665 scope);
654 TemporaryScope temp_scope(&this->temp_scope_); 666 TemporaryScope temp_scope(&this->temp_scope_);
667 if (strict_mode == kStrictMode) {
668 temp_scope.EnableStrictMode();
669 }
655 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); 670 ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
656 bool ok = true; 671 bool ok = true;
672 int beg_loc = scanner().location().beg_pos;
657 ParseSourceElements(body, Token::EOS, &ok); 673 ParseSourceElements(body, Token::EOS, &ok);
674 if (ok && temp_scope_->StrictMode()) {
675 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
676 }
658 if (ok) { 677 if (ok) {
659 result = new FunctionLiteral( 678 result = new FunctionLiteral(
660 no_name, 679 no_name,
661 top_scope_, 680 top_scope_,
662 body, 681 body,
663 temp_scope.materialized_literal_count(), 682 temp_scope.materialized_literal_count(),
664 temp_scope.expected_property_count(), 683 temp_scope.expected_property_count(),
665 temp_scope.only_simple_this_property_assignments(), 684 temp_scope.only_simple_this_property_assignments(),
666 temp_scope.this_property_assignments(), 685 temp_scope.this_property_assignments(),
667 0, 686 0,
668 0, 687 0,
669 source->length(), 688 source->length(),
670 false, 689 false,
671 temp_scope.ContainsLoops()); 690 temp_scope.ContainsLoops(),
691 temp_scope.StrictMode());
672 } else if (stack_overflow_) { 692 } else if (stack_overflow_) {
673 Top::StackOverflow(); 693 Top::StackOverflow();
674 } 694 }
675 } 695 }
676 696
677 // Make sure the target stack is empty. 697 // Make sure the target stack is empty.
678 ASSERT(target_stack_ == NULL); 698 ASSERT(target_stack_ == NULL);
679 699
680 // If there was a syntax error we have to get rid of the AST 700 // If there was a syntax error we have to get rid of the AST
681 // and it is not safe to do so before the scope has been deleted. 701 // and it is not safe to do so before the scope has been deleted.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 745
726 { 746 {
727 // Parse the function literal. 747 // Parse the function literal.
728 Handle<String> no_name = Factory::empty_symbol(); 748 Handle<String> no_name = Factory::empty_symbol();
729 Scope* scope = 749 Scope* scope =
730 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); 750 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with());
731 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, 751 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
732 scope); 752 scope);
733 TemporaryScope temp_scope(&this->temp_scope_); 753 TemporaryScope temp_scope(&this->temp_scope_);
734 754
755 if (info->strict_mode()) {
756 temp_scope.EnableStrictMode();
757 }
758
735 FunctionLiteralType type = 759 FunctionLiteralType type =
736 info->is_expression() ? EXPRESSION : DECLARATION; 760 info->is_expression() ? EXPRESSION : DECLARATION;
737 bool ok = true; 761 bool ok = true;
738 result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok); 762 result = ParseFunctionLiteral(name,
763 false, // Strict mode name already checked.
764 RelocInfo::kNoPosition, type, &ok);
739 // Make sure the results agree. 765 // Make sure the results agree.
740 ASSERT(ok == (result != NULL)); 766 ASSERT(ok == (result != NULL));
741 // The only errors should be stack overflows.
742 ASSERT(ok || stack_overflow_);
743 } 767 }
744 768
745 // Make sure the target stack is empty. 769 // Make sure the target stack is empty.
746 ASSERT(target_stack_ == NULL); 770 ASSERT(target_stack_ == NULL);
747 771
748 // If there was a stack overflow we have to get rid of AST and it is 772 // If there was a stack overflow we have to get rid of AST and it is
749 // not safe to do before scope has been deleted. 773 // not safe to do before scope has been deleted.
750 if (result == NULL) { 774 if (result == NULL) {
751 Top::StackOverflow();
752 zone_scope->DeleteOnExit(); 775 zone_scope->DeleteOnExit();
776 if (stack_overflow_) Top::StackOverflow();
753 } else { 777 } else {
754 Handle<String> inferred_name(info->inferred_name()); 778 Handle<String> inferred_name(info->inferred_name());
755 result->set_inferred_name(inferred_name); 779 result->set_inferred_name(inferred_name);
756 } 780 }
757 return result; 781 return result;
758 } 782 }
759 783
760 784
761 Handle<String> Parser::GetSymbol(bool* ok) { 785 Handle<String> Parser::GetSymbol(bool* ok) {
762 int symbol_id = -1; 786 int symbol_id = -1;
763 if (pre_data() != NULL) { 787 if (pre_data() != NULL) {
764 symbol_id = pre_data()->GetSymbolIdentifier(); 788 symbol_id = pre_data()->GetSymbolIdentifier();
765 } 789 }
766 return LookupSymbol(symbol_id); 790 return LookupSymbol(symbol_id);
767 } 791 }
768 792
769 793
770 void Parser::ReportMessage(const char* type, Vector<const char*> args) { 794 void Parser::ReportMessage(const char* type, Vector<const char*> args) {
771 Scanner::Location source_location = scanner().location(); 795 Scanner::Location source_location = scanner().location();
772 ReportMessageAt(source_location, type, args); 796 ReportMessageAt(source_location, type, args);
773 } 797 }
774 798
775 799
776 void Parser::ReportMessageAt(Scanner::Location source_location, 800 void Parser::ReportMessageAt(Scanner::Location source_location,
777 const char* type, 801 const char* type,
778 Vector<const char*> args) { 802 Vector<const char*> args) {
779 MessageLocation location(script_, 803 MessageLocation location(script_,
780 source_location.beg_pos, source_location.end_pos); 804 source_location.beg_pos,
805 source_location.end_pos);
781 Handle<JSArray> array = Factory::NewJSArray(args.length()); 806 Handle<JSArray> array = Factory::NewJSArray(args.length());
782 for (int i = 0; i < args.length(); i++) { 807 for (int i = 0; i < args.length(); i++) {
783 SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i]))); 808 SetElement(array, i, Factory::NewStringFromUtf8(CStrVector(args[i])));
784 } 809 }
785 Handle<Object> result = Factory::NewSyntaxError(type, array); 810 Handle<Object> result = Factory::NewSyntaxError(type, array);
786 Top::Throw(*result, &location); 811 Top::Throw(*result, &location);
787 } 812 }
788 813
789 814
815 void Parser::ReportMessageAt(Scanner::Location source_location,
816 const char* type,
817 Vector<Handle<String> > args) {
818 MessageLocation location(script_,
819 source_location.beg_pos,
820 source_location.end_pos);
821 Handle<JSArray> array = Factory::NewJSArray(args.length());
822 for (int i = 0; i < args.length(); i++) {
823 SetElement(array, i, args[i]);
824 }
825 Handle<Object> result = Factory::NewSyntaxError(type, array);
826 Top::Throw(*result, &location);
827 }
828
829
790 // Base class containing common code for the different finder classes used by 830 // Base class containing common code for the different finder classes used by
791 // the parser. 831 // the parser.
792 class ParserFinder { 832 class ParserFinder {
793 protected: 833 protected:
794 ParserFinder() {} 834 ParserFinder() {}
795 static Assignment* AsAssignment(Statement* stat) { 835 static Assignment* AsAssignment(Statement* stat) {
796 if (stat == NULL) return NULL; 836 if (stat == NULL) return NULL;
797 ExpressionStatement* exp_stat = stat->AsExpressionStatement(); 837 ExpressionStatement* exp_stat = stat->AsExpressionStatement();
798 if (exp_stat == NULL) return NULL; 838 if (exp_stat == NULL) return NULL;
799 return exp_stat->expression()->AsAssignment(); 839 return exp_stat->expression()->AsAssignment();
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 1091
1052 // Allocate a target stack to use for this set of source 1092 // Allocate a target stack to use for this set of source
1053 // elements. This way, all scripts and functions get their own 1093 // elements. This way, all scripts and functions get their own
1054 // target stack thus avoiding illegal breaks and continues across 1094 // target stack thus avoiding illegal breaks and continues across
1055 // functions. 1095 // functions.
1056 TargetScope scope(&this->target_stack_); 1096 TargetScope scope(&this->target_stack_);
1057 1097
1058 ASSERT(processor != NULL); 1098 ASSERT(processor != NULL);
1059 InitializationBlockFinder block_finder; 1099 InitializationBlockFinder block_finder;
1060 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; 1100 ThisNamedPropertyAssigmentFinder this_property_assignment_finder;
1101 bool directive_prologue = true; // Parsing directive prologue.
1102
1061 while (peek() != end_token) { 1103 while (peek() != end_token) {
1104 if (directive_prologue && peek() != Token::STRING) {
1105 directive_prologue = false;
1106 }
1107
1108 Scanner::Location token_loc = scanner().peek_location();
1062 Statement* stat = ParseStatement(NULL, CHECK_OK); 1109 Statement* stat = ParseStatement(NULL, CHECK_OK);
1063 if (stat == NULL || stat->IsEmpty()) continue; 1110
1111 if (stat == NULL || stat->IsEmpty()) {
1112 directive_prologue = false; // End of directive prologue.
1113 continue;
1114 }
1115
1116 if (directive_prologue) {
1117 // A shot at a directive.
1118 ExpressionStatement *e_stat;
1119 Literal *literal;
1120 // Still processing directive prologue?
1121 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1122 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1123 literal->handle()->IsString()) {
1124 Handle<String> directive = Handle<String>::cast(literal->handle());
1125
1126 // Check "use strict" directive (ES5 14.1).
1127 if (!temp_scope_->StrictMode() &&
1128 directive->Equals(Heap::use_strict()) &&
1129 token_loc.end_pos - token_loc.beg_pos ==
1130 Heap::use_strict()->length() + 2) {
1131 temp_scope_->EnableStrictMode();
1132 // "use strict" is the only directive for now.
1133 directive_prologue = false;
1134 }
1135 } else {
1136 // End of the directive prologue.
1137 directive_prologue = false;
1138 }
1139 }
1140
1064 // We find and mark the initialization blocks on top level code only. 1141 // We find and mark the initialization blocks on top level code only.
1065 // This is because the optimization prevents reuse of the map transitions, 1142 // This is because the optimization prevents reuse of the map transitions,
1066 // so it should be used only for code that will only be run once. 1143 // so it should be used only for code that will only be run once.
1067 if (top_scope_->is_global_scope()) { 1144 if (top_scope_->is_global_scope()) {
1068 block_finder.Update(stat); 1145 block_finder.Update(stat);
1069 } 1146 }
1070 // Find and mark all assignments to named properties in this (this.x =) 1147 // Find and mark all assignments to named properties in this (this.x =)
1071 if (top_scope_->is_function_scope()) { 1148 if (top_scope_->is_function_scope()) {
1072 this_property_assignment_finder.Update(top_scope_, stat); 1149 this_property_assignment_finder.Update(top_scope_, stat);
1073 } 1150 }
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 return new ExpressionStatement( 1441 return new ExpressionStatement(
1365 new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); 1442 new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
1366 } 1443 }
1367 1444
1368 1445
1369 Statement* Parser::ParseFunctionDeclaration(bool* ok) { 1446 Statement* Parser::ParseFunctionDeclaration(bool* ok) {
1370 // FunctionDeclaration :: 1447 // FunctionDeclaration ::
1371 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 1448 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1372 Expect(Token::FUNCTION, CHECK_OK); 1449 Expect(Token::FUNCTION, CHECK_OK);
1373 int function_token_position = scanner().location().beg_pos; 1450 int function_token_position = scanner().location().beg_pos;
1374 Handle<String> name = ParseIdentifier(CHECK_OK); 1451 bool is_reserved = false;
1452 Handle<String> name = ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
1375 FunctionLiteral* fun = ParseFunctionLiteral(name, 1453 FunctionLiteral* fun = ParseFunctionLiteral(name,
1454 is_reserved,
1376 function_token_position, 1455 function_token_position,
1377 DECLARATION, 1456 DECLARATION,
1378 CHECK_OK); 1457 CHECK_OK);
1379 // Even if we're not at the top-level of the global or a function 1458 // Even if we're not at the top-level of the global or a function
1380 // scope, we treat is as such and introduce the function with it's 1459 // scope, we treat is as such and introduce the function with it's
1381 // initial value upon entering the corresponding scope. 1460 // initial value upon entering the corresponding scope.
1382 Declare(name, Variable::VAR, fun, true, CHECK_OK); 1461 Declare(name, Variable::VAR, fun, true, CHECK_OK);
1383 return EmptyStatement(); 1462 return EmptyStatement();
1384 } 1463 }
1385 1464
(...skipping 21 matching lines...) Expand all
1407 Block* Parser::ParseVariableStatement(bool* ok) { 1486 Block* Parser::ParseVariableStatement(bool* ok) {
1408 // VariableStatement :: 1487 // VariableStatement ::
1409 // VariableDeclarations ';' 1488 // VariableDeclarations ';'
1410 1489
1411 Expression* dummy; // to satisfy the ParseVariableDeclarations() signature 1490 Expression* dummy; // to satisfy the ParseVariableDeclarations() signature
1412 Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK); 1491 Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK);
1413 ExpectSemicolon(CHECK_OK); 1492 ExpectSemicolon(CHECK_OK);
1414 return result; 1493 return result;
1415 } 1494 }
1416 1495
1496 static bool IsEvalOrArguments(Handle<String> string) {
1497 return string.is_identical_to(Factory::eval_symbol()) ||
1498 string.is_identical_to(Factory::arguments_symbol());
1499 }
1417 1500
1418 // If the variable declaration declares exactly one non-const 1501 // If the variable declaration declares exactly one non-const
1419 // variable, then *var is set to that variable. In all other cases, 1502 // variable, then *var is set to that variable. In all other cases,
1420 // *var is untouched; in particular, it is the caller's responsibility 1503 // *var is untouched; in particular, it is the caller's responsibility
1421 // to initialize it properly. This mechanism is used for the parsing 1504 // to initialize it properly. This mechanism is used for the parsing
1422 // of 'for-in' loops. 1505 // of 'for-in' loops.
1423 Block* Parser::ParseVariableDeclarations(bool accept_IN, 1506 Block* Parser::ParseVariableDeclarations(bool accept_IN,
1424 Expression** var, 1507 Expression** var,
1425 bool* ok) { 1508 bool* ok) {
1426 // VariableDeclarations :: 1509 // VariableDeclarations ::
(...skipping 28 matching lines...) Expand all
1455 VariableProxy* last_var = NULL; // the last variable declared 1538 VariableProxy* last_var = NULL; // the last variable declared
1456 int nvars = 0; // the number of variables declared 1539 int nvars = 0; // the number of variables declared
1457 do { 1540 do {
1458 if (fni_ != NULL) fni_->Enter(); 1541 if (fni_ != NULL) fni_->Enter();
1459 1542
1460 // Parse variable name. 1543 // Parse variable name.
1461 if (nvars > 0) Consume(Token::COMMA); 1544 if (nvars > 0) Consume(Token::COMMA);
1462 Handle<String> name = ParseIdentifier(CHECK_OK); 1545 Handle<String> name = ParseIdentifier(CHECK_OK);
1463 if (fni_ != NULL) fni_->PushVariableName(name); 1546 if (fni_ != NULL) fni_->PushVariableName(name);
1464 1547
1548 // Strict mode variables may not be named eval or arguments
1549 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
1550 ReportMessage("strict_var_name", Vector<const char*>::empty());
1551 *ok = false;
1552 return NULL;
1553 }
1554
1465 // Declare variable. 1555 // Declare variable.
1466 // Note that we *always* must treat the initial value via a separate init 1556 // Note that we *always* must treat the initial value via a separate init
1467 // assignment for variables and constants because the value must be assigned 1557 // assignment for variables and constants because the value must be assigned
1468 // when the variable is encountered in the source. But the variable/constant 1558 // when the variable is encountered in the source. But the variable/constant
1469 // is declared (and set to 'undefined') upon entering the function within 1559 // is declared (and set to 'undefined') upon entering the function within
1470 // which the variable or constant is declared. Only function variables have 1560 // which the variable or constant is declared. Only function variables have
1471 // an initial value in the declaration (because they are initialized upon 1561 // an initial value in the declaration (because they are initialized upon
1472 // entering the function). 1562 // entering the function).
1473 // 1563 //
1474 // If we have a const declaration, in an inner scope, the proxy is always 1564 // If we have a const declaration, in an inner scope, the proxy is always
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1613 1703
1614 return false; 1704 return false;
1615 } 1705 }
1616 1706
1617 1707
1618 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, 1708 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
1619 bool* ok) { 1709 bool* ok) {
1620 // ExpressionStatement | LabelledStatement :: 1710 // ExpressionStatement | LabelledStatement ::
1621 // Expression ';' 1711 // Expression ';'
1622 // Identifier ':' Statement 1712 // Identifier ':' Statement
1623 bool starts_with_idenfifier = (peek() == Token::IDENTIFIER); 1713 bool starts_with_idenfifier = peek_any_identifier();
1624 Expression* expr = ParseExpression(true, CHECK_OK); 1714 Expression* expr = ParseExpression(true, CHECK_OK);
1625 if (peek() == Token::COLON && starts_with_idenfifier && expr && 1715 if (peek() == Token::COLON && starts_with_idenfifier && expr &&
1626 expr->AsVariableProxy() != NULL && 1716 expr->AsVariableProxy() != NULL &&
1627 !expr->AsVariableProxy()->is_this()) { 1717 !expr->AsVariableProxy()->is_this()) {
1628 // Expression is a single identifier, and not, e.g., a parenthesized 1718 // Expression is a single identifier, and not, e.g., a parenthesized
1629 // identifier. 1719 // identifier.
1630 VariableProxy* var = expr->AsVariableProxy(); 1720 VariableProxy* var = expr->AsVariableProxy();
1631 Handle<String> label = var->name(); 1721 Handle<String> label = var->name();
1632 // TODO(1240780): We don't check for redeclaration of labels 1722 // TODO(1240780): We don't check for redeclaration of labels
1633 // during preparsing since keeping track of the set of active 1723 // during preparsing since keeping track of the set of active
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1685 Expect(Token::CONTINUE, CHECK_OK); 1775 Expect(Token::CONTINUE, CHECK_OK);
1686 Handle<String> label = Handle<String>::null(); 1776 Handle<String> label = Handle<String>::null();
1687 Token::Value tok = peek(); 1777 Token::Value tok = peek();
1688 if (!scanner().has_line_terminator_before_next() && 1778 if (!scanner().has_line_terminator_before_next() &&
1689 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 1779 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
1690 label = ParseIdentifier(CHECK_OK); 1780 label = ParseIdentifier(CHECK_OK);
1691 } 1781 }
1692 IterationStatement* target = NULL; 1782 IterationStatement* target = NULL;
1693 target = LookupContinueTarget(label, CHECK_OK); 1783 target = LookupContinueTarget(label, CHECK_OK);
1694 if (target == NULL) { 1784 if (target == NULL) {
1695 // Illegal continue statement. To be consistent with KJS we delay 1785 // Illegal continue statement.
1696 // reporting of the syntax error until runtime. 1786 const char* message = "illegal_continue";
1697 Handle<String> error_type = Factory::illegal_continue_symbol(); 1787 Vector<Handle<String> > args;
1698 if (!label.is_null()) error_type = Factory::unknown_label_symbol(); 1788 if (!label.is_null()) {
1699 Expression* throw_error = NewThrowSyntaxError(error_type, label); 1789 message = "unknown_label";
1700 return new ExpressionStatement(throw_error); 1790 args = Vector<Handle<String> >(&label, 1);
1791 }
1792 ReportMessageAt(scanner().location(), message, args);
1793 *ok = false;
1794 return NULL;
1701 } 1795 }
1702 ExpectSemicolon(CHECK_OK); 1796 ExpectSemicolon(CHECK_OK);
1703 return new ContinueStatement(target); 1797 return new ContinueStatement(target);
1704 } 1798 }
1705 1799
1706 1800
1707 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { 1801 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
1708 // BreakStatement :: 1802 // BreakStatement ::
1709 // 'break' Identifier? ';' 1803 // 'break' Identifier? ';'
1710 1804
1711 Expect(Token::BREAK, CHECK_OK); 1805 Expect(Token::BREAK, CHECK_OK);
1712 Handle<String> label; 1806 Handle<String> label;
1713 Token::Value tok = peek(); 1807 Token::Value tok = peek();
1714 if (!scanner().has_line_terminator_before_next() && 1808 if (!scanner().has_line_terminator_before_next() &&
1715 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 1809 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
1716 label = ParseIdentifier(CHECK_OK); 1810 label = ParseIdentifier(CHECK_OK);
1717 } 1811 }
1718 // Parse labeled break statements that target themselves into 1812 // Parse labeled break statements that target themselves into
1719 // empty statements, e.g. 'l1: l2: l3: break l2;' 1813 // empty statements, e.g. 'l1: l2: l3: break l2;'
1720 if (!label.is_null() && ContainsLabel(labels, label)) { 1814 if (!label.is_null() && ContainsLabel(labels, label)) {
1721 return EmptyStatement(); 1815 return EmptyStatement();
1722 } 1816 }
1723 BreakableStatement* target = NULL; 1817 BreakableStatement* target = NULL;
1724 target = LookupBreakTarget(label, CHECK_OK); 1818 target = LookupBreakTarget(label, CHECK_OK);
1725 if (target == NULL) { 1819 if (target == NULL) {
1726 // Illegal break statement. To be consistent with KJS we delay 1820 // Illegal break statement.
1727 // reporting of the syntax error until runtime. 1821 const char* message = "illegal_break";
1728 Handle<String> error_type = Factory::illegal_break_symbol(); 1822 Vector<Handle<String> > args;
1729 if (!label.is_null()) error_type = Factory::unknown_label_symbol(); 1823 if (!label.is_null()) {
1730 Expression* throw_error = NewThrowSyntaxError(error_type, label); 1824 message = "unknown_label";
1731 return new ExpressionStatement(throw_error); 1825 args = Vector<Handle<String> >(&label, 1);
1826 }
1827 ReportMessageAt(scanner().location(), message, args);
1828 *ok = false;
1829 return NULL;
1732 } 1830 }
1733 ExpectSemicolon(CHECK_OK); 1831 ExpectSemicolon(CHECK_OK);
1734 return new BreakStatement(target); 1832 return new BreakStatement(target);
1735 } 1833 }
1736 1834
1737 1835
1738 Statement* Parser::ParseReturnStatement(bool* ok) { 1836 Statement* Parser::ParseReturnStatement(bool* ok) {
1739 // ReturnStatement :: 1837 // ReturnStatement ::
1740 // 'return' Expression? ';' 1838 // 'return' Expression? ';'
1741 1839
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1807 } 1905 }
1808 return result; 1906 return result;
1809 } 1907 }
1810 1908
1811 1909
1812 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { 1910 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
1813 // WithStatement :: 1911 // WithStatement ::
1814 // 'with' '(' Expression ')' Statement 1912 // 'with' '(' Expression ')' Statement
1815 1913
1816 Expect(Token::WITH, CHECK_OK); 1914 Expect(Token::WITH, CHECK_OK);
1915
1916 if (temp_scope_->StrictMode()) {
1917 ReportMessage("strict_mode_with", Vector<const char*>::empty());
1918 *ok = false;
1919 return NULL;
1920 }
1921
1817 Expect(Token::LPAREN, CHECK_OK); 1922 Expect(Token::LPAREN, CHECK_OK);
1818 Expression* expr = ParseExpression(true, CHECK_OK); 1923 Expression* expr = ParseExpression(true, CHECK_OK);
1819 Expect(Token::RPAREN, CHECK_OK); 1924 Expect(Token::RPAREN, CHECK_OK);
1820 1925
1821 return WithHelper(expr, labels, false, CHECK_OK); 1926 return WithHelper(expr, labels, false, CHECK_OK);
1822 } 1927 }
1823 1928
1824 1929
1825 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { 1930 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
1826 // CaseClause :: 1931 // CaseClause ::
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1939 // the jump targets. 2044 // the jump targets.
1940 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); 2045 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0);
1941 TargetCollector catch_collector(catch_target_list); 2046 TargetCollector catch_collector(catch_target_list);
1942 bool has_catch = false; 2047 bool has_catch = false;
1943 if (tok == Token::CATCH) { 2048 if (tok == Token::CATCH) {
1944 has_catch = true; 2049 has_catch = true;
1945 Consume(Token::CATCH); 2050 Consume(Token::CATCH);
1946 2051
1947 Expect(Token::LPAREN, CHECK_OK); 2052 Expect(Token::LPAREN, CHECK_OK);
1948 Handle<String> name = ParseIdentifier(CHECK_OK); 2053 Handle<String> name = ParseIdentifier(CHECK_OK);
2054
2055 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
2056 ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2057 *ok = false;
2058 return NULL;
2059 }
2060
1949 Expect(Token::RPAREN, CHECK_OK); 2061 Expect(Token::RPAREN, CHECK_OK);
1950 2062
1951 if (peek() == Token::LBRACE) { 2063 if (peek() == Token::LBRACE) {
1952 // Allocate a temporary for holding the finally state while 2064 // Allocate a temporary for holding the finally state while
1953 // executing the finally block. 2065 // executing the finally block.
1954 catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol()); 2066 catch_var = top_scope_->NewTemporary(Factory::catch_var_symbol());
1955 Literal* name_literal = new Literal(name); 2067 Literal* name_literal = new Literal(name);
1956 VariableProxy* catch_var_use = new VariableProxy(catch_var); 2068 VariableProxy* catch_var_use = new VariableProxy(catch_var);
1957 Expression* obj = new CatchExtensionObject(name_literal, catch_var_use); 2069 Expression* obj = new CatchExtensionObject(name_literal, catch_var_use);
1958 { Target target(&this->target_stack_, &catch_collector); 2070 { Target target(&this->target_stack_, &catch_collector);
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
2184 2296
2185 // Signal a reference error if the expression is an invalid left-hand 2297 // Signal a reference error if the expression is an invalid left-hand
2186 // side expression. We could report this as a syntax error here but 2298 // side expression. We could report this as a syntax error here but
2187 // for compatibility with JSC we choose to report the error at 2299 // for compatibility with JSC we choose to report the error at
2188 // runtime. 2300 // runtime.
2189 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2301 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2190 Handle<String> type = Factory::invalid_lhs_in_assignment_symbol(); 2302 Handle<String> type = Factory::invalid_lhs_in_assignment_symbol();
2191 expression = NewThrowReferenceError(type); 2303 expression = NewThrowReferenceError(type);
2192 } 2304 }
2193 2305
2306 if (temp_scope_->StrictMode()) {
2307 // Assignment to eval or arguments is disallowed in strict mode.
2308 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK);
2309 }
2310
2194 Token::Value op = Next(); // Get assignment operator. 2311 Token::Value op = Next(); // Get assignment operator.
2195 int pos = scanner().location().beg_pos; 2312 int pos = scanner().location().beg_pos;
2196 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); 2313 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK);
2197 2314
2198 // TODO(1231235): We try to estimate the set of properties set by 2315 // TODO(1231235): We try to estimate the set of properties set by
2199 // constructors. We define a new property whenever there is an 2316 // constructors. We define a new property whenever there is an
2200 // assignment to a property of 'this'. We should probably only add 2317 // assignment to a property of 'this'. We should probably only add
2201 // properties if we haven't seen them before. Otherwise we'll 2318 // properties if we haven't seen them before. Otherwise we'll
2202 // probably overestimate the number of properties. 2319 // probably overestimate the number of properties.
2203 Property* property = expression ? expression->AsProperty() : NULL; 2320 Property* property = expression ? expression->AsProperty() : NULL;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2316 uint32_t shift = DoubleToInt32(y_val) & 0x1f; 2433 uint32_t shift = DoubleToInt32(y_val) & 0x1f;
2317 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); 2434 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift);
2318 x = NewNumberLiteral(value); 2435 x = NewNumberLiteral(value);
2319 continue; 2436 continue;
2320 } 2437 }
2321 default: 2438 default:
2322 break; 2439 break;
2323 } 2440 }
2324 } 2441 }
2325 2442
2326 // Convert constant divisions to multiplications for speed.
2327 if (op == Token::DIV &&
2328 y && y->AsLiteral() && y->AsLiteral()->handle()->IsNumber()) {
2329 double y_val = y->AsLiteral()->handle()->Number();
2330 int64_t y_int = static_cast<int64_t>(y_val);
2331 // There are rounding issues with this optimization, but they don't
2332 // apply if the number to be divided with has a reciprocal that can be
2333 // precisely represented as a floating point number. This is the case
2334 // if the number is an integer power of 2. Negative integer powers of
2335 // 2 work too, but for -2, -1, 1 and 2 we don't do the strength
2336 // reduction because the inlined optimistic idiv has a reasonable
2337 // chance of succeeding by producing a Smi answer with no remainder.
2338 if (static_cast<double>(y_int) == y_val &&
2339 (IsPowerOf2(y_int) || IsPowerOf2(-y_int)) &&
2340 (y_int > 2 || y_int < -2)) {
2341 y = NewNumberLiteral(1 / y_val);
2342 op = Token::MUL;
2343 }
2344 }
2345
2346 // For now we distinguish between comparisons and other binary 2443 // For now we distinguish between comparisons and other binary
2347 // operations. (We could combine the two and get rid of this 2444 // operations. (We could combine the two and get rid of this
2348 // code and AST node eventually.) 2445 // code and AST node eventually.)
2349 if (Token::IsCompareOp(op)) { 2446 if (Token::IsCompareOp(op)) {
2350 // We have a comparison. 2447 // We have a comparison.
2351 Token::Value cmp = op; 2448 Token::Value cmp = op;
2352 switch (op) { 2449 switch (op) {
2353 case Token::NE: cmp = Token::EQ; break; 2450 case Token::NE: cmp = Token::EQ; break;
2354 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; 2451 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break;
2355 default: break; 2452 default: break;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2417 case Token::ADD: 2514 case Token::ADD:
2418 return expression; 2515 return expression;
2419 case Token::SUB: 2516 case Token::SUB:
2420 return NewNumberLiteral(-value); 2517 return NewNumberLiteral(-value);
2421 case Token::BIT_NOT: 2518 case Token::BIT_NOT:
2422 return NewNumberLiteral(~DoubleToInt32(value)); 2519 return NewNumberLiteral(~DoubleToInt32(value));
2423 default: break; 2520 default: break;
2424 } 2521 }
2425 } 2522 }
2426 2523
2524 // "delete identifier" is a syntax error in strict mode.
2525 if (op == Token::DELETE && temp_scope_->StrictMode()) {
2526 VariableProxy* operand = expression->AsVariableProxy();
2527 if (operand != NULL && !operand->is_this()) {
2528 ReportMessage("strict_delete", Vector<const char*>::empty());
2529 *ok = false;
2530 return NULL;
2531 }
2532 }
2533
2427 return new UnaryOperation(op, expression); 2534 return new UnaryOperation(op, expression);
2428 2535
2429 } else if (Token::IsCountOp(op)) { 2536 } else if (Token::IsCountOp(op)) {
2430 op = Next(); 2537 op = Next();
2431 Expression* expression = ParseUnaryExpression(CHECK_OK); 2538 Expression* expression = ParseUnaryExpression(CHECK_OK);
2432 // Signal a reference error if the expression is an invalid 2539 // Signal a reference error if the expression is an invalid
2433 // left-hand side expression. We could report this as a syntax 2540 // left-hand side expression. We could report this as a syntax
2434 // error here but for compatibility with JSC we choose to report the 2541 // error here but for compatibility with JSC we choose to report the
2435 // error at runtime. 2542 // error at runtime.
2436 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2543 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2437 Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol(); 2544 Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol();
2438 expression = NewThrowReferenceError(type); 2545 expression = NewThrowReferenceError(type);
2439 } 2546 }
2547
2548 if (temp_scope_->StrictMode()) {
2549 // Prefix expression operand in strict mode may not be eval or arguments.
2550 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
2551 }
2552
2440 int position = scanner().location().beg_pos; 2553 int position = scanner().location().beg_pos;
2441 IncrementOperation* increment = new IncrementOperation(op, expression); 2554 IncrementOperation* increment = new IncrementOperation(op, expression);
2442 return new CountOperation(true /* prefix */, increment, position); 2555 return new CountOperation(true /* prefix */, increment, position);
2443 2556
2444 } else { 2557 } else {
2445 return ParsePostfixExpression(ok); 2558 return ParsePostfixExpression(ok);
2446 } 2559 }
2447 } 2560 }
2448 2561
2449 2562
2450 Expression* Parser::ParsePostfixExpression(bool* ok) { 2563 Expression* Parser::ParsePostfixExpression(bool* ok) {
2451 // PostfixExpression :: 2564 // PostfixExpression ::
2452 // LeftHandSideExpression ('++' | '--')? 2565 // LeftHandSideExpression ('++' | '--')?
2453 2566
2454 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); 2567 Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
2455 if (!scanner().has_line_terminator_before_next() && 2568 if (!scanner().has_line_terminator_before_next() &&
2456 Token::IsCountOp(peek())) { 2569 Token::IsCountOp(peek())) {
2457 // Signal a reference error if the expression is an invalid 2570 // Signal a reference error if the expression is an invalid
2458 // left-hand side expression. We could report this as a syntax 2571 // left-hand side expression. We could report this as a syntax
2459 // error here but for compatibility with JSC we choose to report the 2572 // error here but for compatibility with JSC we choose to report the
2460 // error at runtime. 2573 // error at runtime.
2461 if (expression == NULL || !expression->IsValidLeftHandSide()) { 2574 if (expression == NULL || !expression->IsValidLeftHandSide()) {
2462 Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol(); 2575 Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol();
2463 expression = NewThrowReferenceError(type); 2576 expression = NewThrowReferenceError(type);
2464 } 2577 }
2578
2579 if (temp_scope_->StrictMode()) {
2580 // Postfix expression operand in strict mode may not be eval or arguments.
2581 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK);
2582 }
2583
2465 Token::Value next = Next(); 2584 Token::Value next = Next();
2466 int position = scanner().location().beg_pos; 2585 int position = scanner().location().beg_pos;
2467 IncrementOperation* increment = new IncrementOperation(next, expression); 2586 IncrementOperation* increment = new IncrementOperation(next, expression);
2468 expression = new CountOperation(false /* postfix */, increment, position); 2587 expression = new CountOperation(false /* postfix */, increment, position);
2469 } 2588 }
2470 return expression; 2589 return expression;
2471 } 2590 }
2472 2591
2473 2592
2474 Expression* Parser::ParseLeftHandSideExpression(bool* ok) { 2593 Expression* Parser::ParseLeftHandSideExpression(bool* ok) {
(...skipping 20 matching lines...) Expand all
2495 2614
2496 case Token::LPAREN: { 2615 case Token::LPAREN: {
2497 int pos = scanner().location().beg_pos; 2616 int pos = scanner().location().beg_pos;
2498 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 2617 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
2499 2618
2500 // Keep track of eval() calls since they disable all local variable 2619 // Keep track of eval() calls since they disable all local variable
2501 // optimizations. 2620 // optimizations.
2502 // The calls that need special treatment are the 2621 // The calls that need special treatment are the
2503 // direct (i.e. not aliased) eval calls. These calls are all of the 2622 // direct (i.e. not aliased) eval calls. These calls are all of the
2504 // form eval(...) with no explicit receiver object where eval is not 2623 // form eval(...) with no explicit receiver object where eval is not
2505 // declared in the current scope chain. These calls are marked as 2624 // declared in the current scope chain.
2506 // potentially direct eval calls. Whether they are actually direct calls 2625 // These calls are marked as potentially direct eval calls. Whether
2507 // to eval is determined at run time. 2626 // they are actually direct calls to eval is determined at run time.
2627 // TODO(994): In ES5, it doesn't matter if the "eval" var is declared
2628 // in the local scope chain. It only matters that it's called "eval",
2629 // is called without a receiver and it refers to the original eval
2630 // function.
2508 VariableProxy* callee = result->AsVariableProxy(); 2631 VariableProxy* callee = result->AsVariableProxy();
2509 if (callee != NULL && callee->IsVariable(Factory::eval_symbol())) { 2632 if (callee != NULL && callee->IsVariable(Factory::eval_symbol())) {
2510 Handle<String> name = callee->name(); 2633 Handle<String> name = callee->name();
2511 Variable* var = top_scope_->Lookup(name); 2634 Variable* var = top_scope_->Lookup(name);
2512 if (var == NULL) { 2635 if (var == NULL) {
2513 top_scope_->RecordEvalCall(); 2636 top_scope_->RecordEvalCall();
2514 } 2637 }
2515 } 2638 }
2516 result = NewCall(result, args, pos); 2639 result = NewCall(result, args, pos);
2517 break; 2640 break;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2579 // MemberExpression :: 2702 // MemberExpression ::
2580 // (PrimaryExpression | FunctionLiteral) 2703 // (PrimaryExpression | FunctionLiteral)
2581 // ('[' Expression ']' | '.' Identifier | Arguments)* 2704 // ('[' Expression ']' | '.' Identifier | Arguments)*
2582 2705
2583 // Parse the initial primary or function expression. 2706 // Parse the initial primary or function expression.
2584 Expression* result = NULL; 2707 Expression* result = NULL;
2585 if (peek() == Token::FUNCTION) { 2708 if (peek() == Token::FUNCTION) {
2586 Expect(Token::FUNCTION, CHECK_OK); 2709 Expect(Token::FUNCTION, CHECK_OK);
2587 int function_token_position = scanner().location().beg_pos; 2710 int function_token_position = scanner().location().beg_pos;
2588 Handle<String> name; 2711 Handle<String> name;
2589 if (peek() == Token::IDENTIFIER) name = ParseIdentifier(CHECK_OK); 2712 bool is_reserved_name = false;
2590 result = ParseFunctionLiteral(name, function_token_position, 2713 if (peek_any_identifier()) {
2591 NESTED, CHECK_OK); 2714 name = ParseIdentifierOrReservedWord(&is_reserved_name, CHECK_OK);
2715 }
2716 result = ParseFunctionLiteral(name, is_reserved_name,
2717 function_token_position, NESTED, CHECK_OK);
2592 } else { 2718 } else {
2593 result = ParsePrimaryExpression(CHECK_OK); 2719 result = ParsePrimaryExpression(CHECK_OK);
2594 } 2720 }
2595 2721
2596 while (true) { 2722 while (true) {
2597 switch (peek()) { 2723 switch (peek()) {
2598 case Token::LBRACK: { 2724 case Token::LBRACK: {
2599 Consume(Token::LBRACK); 2725 Consume(Token::LBRACK);
2600 int pos = scanner().location().beg_pos; 2726 int pos = scanner().location().beg_pos;
2601 Expression* index = ParseExpression(true, CHECK_OK); 2727 Expression* index = ParseExpression(true, CHECK_OK);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2650 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); 2776 return ReportMessage("unexpected_eos", Vector<const char*>::empty());
2651 case Token::NUMBER: 2777 case Token::NUMBER:
2652 return ReportMessage("unexpected_token_number", 2778 return ReportMessage("unexpected_token_number",
2653 Vector<const char*>::empty()); 2779 Vector<const char*>::empty());
2654 case Token::STRING: 2780 case Token::STRING:
2655 return ReportMessage("unexpected_token_string", 2781 return ReportMessage("unexpected_token_string",
2656 Vector<const char*>::empty()); 2782 Vector<const char*>::empty());
2657 case Token::IDENTIFIER: 2783 case Token::IDENTIFIER:
2658 return ReportMessage("unexpected_token_identifier", 2784 return ReportMessage("unexpected_token_identifier",
2659 Vector<const char*>::empty()); 2785 Vector<const char*>::empty());
2786 case Token::FUTURE_RESERVED_WORD:
2787 return ReportMessage(temp_scope_->StrictMode() ?
2788 "unexpected_strict_reserved" :
2789 "unexpected_token_identifier",
2790 Vector<const char*>::empty());
2660 default: 2791 default:
2661 const char* name = Token::String(token); 2792 const char* name = Token::String(token);
2662 ASSERT(name != NULL); 2793 ASSERT(name != NULL);
2663 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); 2794 ReportMessage("unexpected_token", Vector<const char*>(&name, 1));
2664 } 2795 }
2665 } 2796 }
2666 2797
2667 2798
2668 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { 2799 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
2669 SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS); 2800 SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2705 case Token::TRUE_LITERAL: 2836 case Token::TRUE_LITERAL:
2706 Consume(Token::TRUE_LITERAL); 2837 Consume(Token::TRUE_LITERAL);
2707 result = new Literal(Factory::true_value()); 2838 result = new Literal(Factory::true_value());
2708 break; 2839 break;
2709 2840
2710 case Token::FALSE_LITERAL: 2841 case Token::FALSE_LITERAL:
2711 Consume(Token::FALSE_LITERAL); 2842 Consume(Token::FALSE_LITERAL);
2712 result = new Literal(Factory::false_value()); 2843 result = new Literal(Factory::false_value());
2713 break; 2844 break;
2714 2845
2715 case Token::IDENTIFIER: { 2846 case Token::IDENTIFIER:
2847 case Token::FUTURE_RESERVED_WORD: {
2716 Handle<String> name = ParseIdentifier(CHECK_OK); 2848 Handle<String> name = ParseIdentifier(CHECK_OK);
2717 if (fni_ != NULL) fni_->PushVariableName(name); 2849 if (fni_ != NULL) fni_->PushVariableName(name);
2718 result = top_scope_->NewUnresolved(name, inside_with()); 2850 result = top_scope_->NewUnresolved(name, inside_with());
2719 break; 2851 break;
2720 } 2852 }
2721 2853
2722 case Token::NUMBER: { 2854 case Token::NUMBER: {
2723 Consume(Token::NUMBER); 2855 Consume(Token::NUMBER);
2724 ASSERT(scanner().is_literal_ascii()); 2856 ASSERT(scanner().is_literal_ascii());
2725 double value = StringToDouble(scanner().literal_ascii_string(), 2857 double value = StringToDouble(scanner().literal_ascii_string(),
(...skipping 21 matching lines...) Expand all
2747 case Token::LBRACK: 2879 case Token::LBRACK:
2748 result = ParseArrayLiteral(CHECK_OK); 2880 result = ParseArrayLiteral(CHECK_OK);
2749 break; 2881 break;
2750 2882
2751 case Token::LBRACE: 2883 case Token::LBRACE:
2752 result = ParseObjectLiteral(CHECK_OK); 2884 result = ParseObjectLiteral(CHECK_OK);
2753 break; 2885 break;
2754 2886
2755 case Token::LPAREN: 2887 case Token::LPAREN:
2756 Consume(Token::LPAREN); 2888 Consume(Token::LPAREN);
2889 // Heuristically try to detect immediately called functions before
2890 // seeing the call parentheses.
2891 parenthesized_function_ = (peek() == Token::FUNCTION);
2757 result = ParseExpression(true, CHECK_OK); 2892 result = ParseExpression(true, CHECK_OK);
2758 Expect(Token::RPAREN, CHECK_OK); 2893 Expect(Token::RPAREN, CHECK_OK);
2759 break; 2894 break;
2760 2895
2761 case Token::MOD: 2896 case Token::MOD:
2762 if (allow_natives_syntax_ || extension_ != NULL) { 2897 if (allow_natives_syntax_ || extension_ != NULL) {
2763 result = ParseV8Intrinsic(CHECK_OK); 2898 result = ParseV8Intrinsic(CHECK_OK);
2764 break; 2899 break;
2765 } 2900 }
2766 // If we're not allowing special syntax we fall-through to the 2901 // If we're not allowing special syntax we fall-through to the
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
2921 Handle<Object> Parser::GetBoilerplateValue(Expression* expression) { 3056 Handle<Object> Parser::GetBoilerplateValue(Expression* expression) {
2922 if (expression->AsLiteral() != NULL) { 3057 if (expression->AsLiteral() != NULL) {
2923 return expression->AsLiteral()->handle(); 3058 return expression->AsLiteral()->handle();
2924 } 3059 }
2925 if (CompileTimeValue::IsCompileTimeValue(expression)) { 3060 if (CompileTimeValue::IsCompileTimeValue(expression)) {
2926 return CompileTimeValue::GetValue(expression); 3061 return CompileTimeValue::GetValue(expression);
2927 } 3062 }
2928 return Factory::undefined_value(); 3063 return Factory::undefined_value();
2929 } 3064 }
2930 3065
3066 // Defined in ast.cc
3067 bool IsEqualString(void* first, void* second);
3068 bool IsEqualNumber(void* first, void* second);
3069
3070
3071 // Validation per 11.1.5 Object Initialiser
3072 class ObjectLiteralPropertyChecker {
3073 public:
3074 ObjectLiteralPropertyChecker(Parser* parser, bool strict) :
3075 props(&IsEqualString),
3076 elems(&IsEqualNumber),
3077 parser_(parser),
3078 strict_(strict) {
3079 }
3080
3081 void CheckProperty(
3082 ObjectLiteral::Property* property,
3083 Scanner::Location loc,
3084 bool* ok);
3085
3086 private:
3087 enum PropertyKind {
3088 kGetAccessor = 0x01,
3089 kSetAccessor = 0x02,
3090 kAccessor = kGetAccessor | kSetAccessor,
3091 kData = 0x04
3092 };
3093
3094 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) {
3095 switch (property->kind()) {
3096 case ObjectLiteral::Property::GETTER:
3097 return kGetAccessor;
3098 case ObjectLiteral::Property::SETTER:
3099 return kSetAccessor;
3100 default:
3101 return kData;
3102 }
3103 }
3104
3105 HashMap props;
3106 HashMap elems;
3107 Parser* parser_;
3108 bool strict_;
3109 };
3110
3111
3112 void ObjectLiteralPropertyChecker::CheckProperty(
3113 ObjectLiteral::Property* property,
3114 Scanner::Location loc,
3115 bool* ok) {
3116
3117 ASSERT(property != NULL);
3118
3119 Literal *lit = property->key();
3120 Handle<Object> handle = lit->handle();
3121
3122 uint32_t hash;
3123 HashMap* map;
3124 void* key;
3125
3126 if (handle->IsSymbol()) {
3127 Handle<String> name(String::cast(*handle));
3128 if (name->AsArrayIndex(&hash)) {
3129 Handle<Object> key_handle = Factory::NewNumberFromUint(hash);
3130 key = key_handle.location();
3131 map = &elems;
3132 } else {
3133 key = handle.location();
3134 hash = name->Hash();
3135 map = &props;
3136 }
3137 } else if (handle->ToArrayIndex(&hash)) {
3138 key = handle.location();
3139 map = &elems;
3140 } else {
3141 ASSERT(handle->IsNumber());
3142 double num = handle->Number();
3143 char arr[100];
3144 Vector<char> buffer(arr, ARRAY_SIZE(arr));
3145 const char* str = DoubleToCString(num, buffer);
3146 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str));
3147 key = name.location();
3148 hash = name->Hash();
3149 map = &props;
3150 }
3151
3152 // Lookup property previously defined, if any.
3153 HashMap::Entry* entry = map->Lookup(key, hash, true);
3154 intptr_t prev = reinterpret_cast<intptr_t> (entry->value);
3155 intptr_t curr = GetPropertyKind(property);
3156
3157 // Duplicate data properties are illegal in strict mode.
3158 if (strict_ && (curr & prev & kData) != 0) {
3159 parser_->ReportMessageAt(loc, "strict_duplicate_property",
3160 Vector<const char*>::empty());
3161 *ok = false;
3162 return;
3163 }
3164 // Data property conflicting with an accessor.
3165 if (((curr & kData) && (prev & kAccessor)) ||
3166 ((prev & kData) && (curr & kAccessor))) {
3167 parser_->ReportMessageAt(loc, "accessor_data_property",
3168 Vector<const char*>::empty());
3169 *ok = false;
3170 return;
3171 }
3172 // Two accessors of the same type conflicting
3173 if ((curr & prev & kAccessor) != 0) {
3174 parser_->ReportMessageAt(loc, "accessor_get_set",
3175 Vector<const char*>::empty());
3176 *ok = false;
3177 return;
3178 }
3179
3180 // Update map
3181 entry->value = reinterpret_cast<void*> (prev | curr);
3182 *ok = true;
3183 }
3184
2931 3185
2932 void Parser::BuildObjectLiteralConstantProperties( 3186 void Parser::BuildObjectLiteralConstantProperties(
2933 ZoneList<ObjectLiteral::Property*>* properties, 3187 ZoneList<ObjectLiteral::Property*>* properties,
2934 Handle<FixedArray> constant_properties, 3188 Handle<FixedArray> constant_properties,
2935 bool* is_simple, 3189 bool* is_simple,
2936 bool* fast_elements, 3190 bool* fast_elements,
2937 int* depth) { 3191 int* depth) {
2938 int position = 0; 3192 int position = 0;
2939 // Accumulate the value in local variables and store it at the end. 3193 // Accumulate the value in local variables and store it at the end.
2940 bool is_simple_acc = true; 3194 bool is_simple_acc = true;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2990 3244
2991 3245
2992 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, 3246 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
2993 bool* ok) { 3247 bool* ok) {
2994 // Special handling of getter and setter syntax: 3248 // Special handling of getter and setter syntax:
2995 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 3249 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
2996 // We have already read the "get" or "set" keyword. 3250 // We have already read the "get" or "set" keyword.
2997 Token::Value next = Next(); 3251 Token::Value next = Next();
2998 bool is_keyword = Token::IsKeyword(next); 3252 bool is_keyword = Token::IsKeyword(next);
2999 if (next == Token::IDENTIFIER || next == Token::NUMBER || 3253 if (next == Token::IDENTIFIER || next == Token::NUMBER ||
3254 next == Token::FUTURE_RESERVED_WORD ||
3000 next == Token::STRING || is_keyword) { 3255 next == Token::STRING || is_keyword) {
3001 Handle<String> name; 3256 Handle<String> name;
3002 if (is_keyword) { 3257 if (is_keyword) {
3003 name = Factory::LookupAsciiSymbol(Token::String(next)); 3258 name = Factory::LookupAsciiSymbol(Token::String(next));
3004 } else { 3259 } else {
3005 name = GetSymbol(CHECK_OK); 3260 name = GetSymbol(CHECK_OK);
3006 } 3261 }
3007 FunctionLiteral* value = 3262 FunctionLiteral* value =
3008 ParseFunctionLiteral(name, 3263 ParseFunctionLiteral(name,
3264 false, // reserved words are allowed here
3009 RelocInfo::kNoPosition, 3265 RelocInfo::kNoPosition,
3010 DECLARATION, 3266 DECLARATION,
3011 CHECK_OK); 3267 CHECK_OK);
3012 // Allow any number of parameters for compatiabilty with JSC. 3268 // Allow any number of parameters for compatiabilty with JSC.
3013 // Specification only allows zero parameters for get and one for set. 3269 // Specification only allows zero parameters for get and one for set.
3014 ObjectLiteral::Property* property = 3270 ObjectLiteral::Property* property =
3015 new ObjectLiteral::Property(is_getter, value); 3271 new ObjectLiteral::Property(is_getter, value);
3016 return property; 3272 return property;
3017 } else { 3273 } else {
3018 ReportUnexpectedToken(next); 3274 ReportUnexpectedToken(next);
3019 *ok = false; 3275 *ok = false;
3020 return NULL; 3276 return NULL;
3021 } 3277 }
3022 } 3278 }
3023 3279
3024 3280
3025 Expression* Parser::ParseObjectLiteral(bool* ok) { 3281 Expression* Parser::ParseObjectLiteral(bool* ok) {
3026 // ObjectLiteral :: 3282 // ObjectLiteral ::
3027 // '{' ( 3283 // '{' (
3028 // ((IdentifierName | String | Number) ':' AssignmentExpression) 3284 // ((IdentifierName | String | Number) ':' AssignmentExpression)
3029 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 3285 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
3030 // )*[','] '}' 3286 // )*[','] '}'
3031 3287
3032 ZoneList<ObjectLiteral::Property*>* properties = 3288 ZoneList<ObjectLiteral::Property*>* properties =
3033 new ZoneList<ObjectLiteral::Property*>(4); 3289 new ZoneList<ObjectLiteral::Property*>(4);
3034 int number_of_boilerplate_properties = 0; 3290 int number_of_boilerplate_properties = 0;
3035 3291
3292 ObjectLiteralPropertyChecker checker(this, temp_scope_->StrictMode());
3293
3036 Expect(Token::LBRACE, CHECK_OK); 3294 Expect(Token::LBRACE, CHECK_OK);
3295 Scanner::Location loc = scanner().location();
3296
3037 while (peek() != Token::RBRACE) { 3297 while (peek() != Token::RBRACE) {
3038 if (fni_ != NULL) fni_->Enter(); 3298 if (fni_ != NULL) fni_->Enter();
3039 3299
3040 Literal* key = NULL; 3300 Literal* key = NULL;
3041 Token::Value next = peek(); 3301 Token::Value next = peek();
3302
3303 // Location of the property name token
3304 Scanner::Location loc = scanner().peek_location();
3305
3042 switch (next) { 3306 switch (next) {
3307 case Token::FUTURE_RESERVED_WORD:
3043 case Token::IDENTIFIER: { 3308 case Token::IDENTIFIER: {
3044 bool is_getter = false; 3309 bool is_getter = false;
3045 bool is_setter = false; 3310 bool is_setter = false;
3046 Handle<String> id = 3311 Handle<String> id =
3047 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 3312 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
3048 if (fni_ != NULL) fni_->PushLiteralName(id); 3313 if (fni_ != NULL) fni_->PushLiteralName(id);
3049 3314
3050 if ((is_getter || is_setter) && peek() != Token::COLON) { 3315 if ((is_getter || is_setter) && peek() != Token::COLON) {
3316 // Update loc to point to the identifier
3317 loc = scanner().peek_location();
3051 ObjectLiteral::Property* property = 3318 ObjectLiteral::Property* property =
3052 ParseObjectLiteralGetSet(is_getter, CHECK_OK); 3319 ParseObjectLiteralGetSet(is_getter, CHECK_OK);
3053 if (IsBoilerplateProperty(property)) { 3320 if (IsBoilerplateProperty(property)) {
3054 number_of_boilerplate_properties++; 3321 number_of_boilerplate_properties++;
3055 } 3322 }
3323 // Validate the property.
3324 checker.CheckProperty(property, loc, CHECK_OK);
3056 properties->Add(property); 3325 properties->Add(property);
3057 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 3326 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
3058 3327
3059 if (fni_ != NULL) { 3328 if (fni_ != NULL) {
3060 fni_->Infer(); 3329 fni_->Infer();
3061 fni_->Leave(); 3330 fni_->Leave();
3062 } 3331 }
3063 continue; // restart the while 3332 continue; // restart the while
3064 } 3333 }
3065 // Failed to parse as get/set property, so it's just a property 3334 // Failed to parse as get/set property, so it's just a property
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3102 } 3371 }
3103 3372
3104 Expect(Token::COLON, CHECK_OK); 3373 Expect(Token::COLON, CHECK_OK);
3105 Expression* value = ParseAssignmentExpression(true, CHECK_OK); 3374 Expression* value = ParseAssignmentExpression(true, CHECK_OK);
3106 3375
3107 ObjectLiteral::Property* property = 3376 ObjectLiteral::Property* property =
3108 new ObjectLiteral::Property(key, value); 3377 new ObjectLiteral::Property(key, value);
3109 3378
3110 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 3379 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
3111 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; 3380 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
3381 // Validate the property
3382 checker.CheckProperty(property, loc, CHECK_OK);
3112 properties->Add(property); 3383 properties->Add(property);
3113 3384
3114 // TODO(1240767): Consider allowing trailing comma. 3385 // TODO(1240767): Consider allowing trailing comma.
3115 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 3386 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
3116 3387
3117 if (fni_ != NULL) { 3388 if (fni_ != NULL) {
3118 fni_->Infer(); 3389 fni_->Infer();
3119 fni_->Leave(); 3390 fni_->Leave();
3120 } 3391 }
3121 } 3392 }
3122 Expect(Token::RBRACE, CHECK_OK); 3393 Expect(Token::RBRACE, CHECK_OK);
3394
3123 // Computation of literal_index must happen before pre parse bailout. 3395 // Computation of literal_index must happen before pre parse bailout.
3124 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); 3396 int literal_index = temp_scope_->NextMaterializedLiteralIndex();
3125 3397
3126 Handle<FixedArray> constant_properties = 3398 Handle<FixedArray> constant_properties =
3127 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED); 3399 Factory::NewFixedArray(number_of_boilerplate_properties * 2, TENURED);
3128 3400
3129 bool is_simple = true; 3401 bool is_simple = true;
3130 bool fast_elements = true; 3402 bool fast_elements = true;
3131 int depth = 1; 3403 int depth = 1;
3132 BuildObjectLiteralConstantProperties(properties, 3404 BuildObjectLiteralConstantProperties(properties,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
3174 result->Add(argument); 3446 result->Add(argument);
3175 done = (peek() == Token::RPAREN); 3447 done = (peek() == Token::RPAREN);
3176 if (!done) Expect(Token::COMMA, CHECK_OK); 3448 if (!done) Expect(Token::COMMA, CHECK_OK);
3177 } 3449 }
3178 Expect(Token::RPAREN, CHECK_OK); 3450 Expect(Token::RPAREN, CHECK_OK);
3179 return result; 3451 return result;
3180 } 3452 }
3181 3453
3182 3454
3183 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, 3455 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
3456 bool name_is_reserved,
3184 int function_token_position, 3457 int function_token_position,
3185 FunctionLiteralType type, 3458 FunctionLiteralType type,
3186 bool* ok) { 3459 bool* ok) {
3187 // Function :: 3460 // Function ::
3188 // '(' FormalParameterList? ')' '{' FunctionBody '}' 3461 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3189 bool is_named = !var_name.is_null(); 3462 bool is_named = !var_name.is_null();
3190 3463
3191 // The name associated with this function. If it's a function expression, 3464 // The name associated with this function. If it's a function expression,
3192 // this is the actual function name, otherwise this is the name of the 3465 // this is the actual function name, otherwise this is the name of the
3193 // variable declared and initialized with the function (expression). In 3466 // variable declared and initialized with the function (expression). In
(...skipping 11 matching lines...) Expand all
3205 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); 3478 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
3206 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, 3479 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
3207 scope); 3480 scope);
3208 TemporaryScope temp_scope(&this->temp_scope_); 3481 TemporaryScope temp_scope(&this->temp_scope_);
3209 top_scope_->SetScopeName(name); 3482 top_scope_->SetScopeName(name);
3210 3483
3211 // FormalParameterList :: 3484 // FormalParameterList ::
3212 // '(' (Identifier)*[','] ')' 3485 // '(' (Identifier)*[','] ')'
3213 Expect(Token::LPAREN, CHECK_OK); 3486 Expect(Token::LPAREN, CHECK_OK);
3214 int start_pos = scanner().location().beg_pos; 3487 int start_pos = scanner().location().beg_pos;
3488 Scanner::Location name_loc = Scanner::NoLocation();
3489 Scanner::Location dupe_loc = Scanner::NoLocation();
3490 Scanner::Location reserved_loc = Scanner::NoLocation();
3491
3215 bool done = (peek() == Token::RPAREN); 3492 bool done = (peek() == Token::RPAREN);
3216 while (!done) { 3493 while (!done) {
3217 Handle<String> param_name = ParseIdentifier(CHECK_OK); 3494 bool is_reserved = false;
3218 top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, 3495 Handle<String> param_name =
3219 Variable::VAR)); 3496 ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
3497
3498 // Store locations for possible future error reports.
3499 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
3500 name_loc = scanner().location();
3501 }
3502 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
3503 dupe_loc = scanner().location();
3504 }
3505 if (!reserved_loc.IsValid() && is_reserved) {
3506 reserved_loc = scanner().location();
3507 }
3508
3509 Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR);
3510 top_scope_->AddParameter(parameter);
3220 num_parameters++; 3511 num_parameters++;
3512 if (num_parameters > kMaxNumFunctionParameters) {
3513 ReportMessageAt(scanner().location(), "too_many_parameters",
3514 Vector<const char*>::empty());
3515 *ok = false;
3516 return NULL;
3517 }
3221 done = (peek() == Token::RPAREN); 3518 done = (peek() == Token::RPAREN);
3222 if (!done) Expect(Token::COMMA, CHECK_OK); 3519 if (!done) Expect(Token::COMMA, CHECK_OK);
3223 } 3520 }
3224 Expect(Token::RPAREN, CHECK_OK); 3521 Expect(Token::RPAREN, CHECK_OK);
3225 3522
3226 Expect(Token::LBRACE, CHECK_OK); 3523 Expect(Token::LBRACE, CHECK_OK);
3227 ZoneList<Statement*>* body = new ZoneList<Statement*>(8); 3524 ZoneList<Statement*>* body = new ZoneList<Statement*>(8);
3228 3525
3229 // If we have a named function expression, we add a local variable 3526 // If we have a named function expression, we add a local variable
3230 // declaration to the body of the function with the name of the 3527 // declaration to the body of the function with the name of the
3231 // function and let it refer to the function itself (closure). 3528 // function and let it refer to the function itself (closure).
3232 // NOTE: We create a proxy and resolve it here so that in the 3529 // NOTE: We create a proxy and resolve it here so that in the
3233 // future we can change the AST to only refer to VariableProxies 3530 // future we can change the AST to only refer to VariableProxies
3234 // instead of Variables and Proxis as is the case now. 3531 // instead of Variables and Proxis as is the case now.
3235 if (!function_name.is_null() && function_name->length() > 0) { 3532 if (!function_name.is_null() && function_name->length() > 0) {
3236 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); 3533 Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
3237 VariableProxy* fproxy = 3534 VariableProxy* fproxy =
3238 top_scope_->NewUnresolved(function_name, inside_with()); 3535 top_scope_->NewUnresolved(function_name, inside_with());
3239 fproxy->BindTo(fvar); 3536 fproxy->BindTo(fvar);
3240 body->Add(new ExpressionStatement( 3537 body->Add(new ExpressionStatement(
3241 new Assignment(Token::INIT_CONST, fproxy, 3538 new Assignment(Token::INIT_CONST, fproxy,
3242 new ThisFunction(), 3539 new ThisFunction(),
3243 RelocInfo::kNoPosition))); 3540 RelocInfo::kNoPosition)));
3244 } 3541 }
3245 3542
3246 // Determine if the function will be lazily compiled. The mode can 3543 // Determine if the function will be lazily compiled. The mode can
3247 // only be PARSE_LAZILY if the --lazy flag is true. 3544 // only be PARSE_LAZILY if the --lazy flag is true.
3248 bool is_lazily_compiled = 3545 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
3249 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); 3546 top_scope_->outer_scope()->is_global_scope() &&
3547 top_scope_->HasTrivialOuterContext() &&
3548 !parenthesized_function_);
3549 parenthesized_function_ = false; // The bit was set for this function only.
3250 3550
3251 int function_block_pos = scanner().location().beg_pos; 3551 int function_block_pos = scanner().location().beg_pos;
3252 int materialized_literal_count; 3552 int materialized_literal_count;
3253 int expected_property_count; 3553 int expected_property_count;
3254 int end_pos; 3554 int end_pos;
3255 bool only_simple_this_property_assignments; 3555 bool only_simple_this_property_assignments;
3256 Handle<FixedArray> this_property_assignments; 3556 Handle<FixedArray> this_property_assignments;
3257 if (is_lazily_compiled && pre_data() != NULL) { 3557 if (is_lazily_compiled && pre_data() != NULL) {
3258 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); 3558 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos);
3259 if (!entry.is_valid()) { 3559 if (!entry.is_valid()) {
(...skipping 18 matching lines...) Expand all
3278 materialized_literal_count = temp_scope.materialized_literal_count(); 3578 materialized_literal_count = temp_scope.materialized_literal_count();
3279 expected_property_count = temp_scope.expected_property_count(); 3579 expected_property_count = temp_scope.expected_property_count();
3280 only_simple_this_property_assignments = 3580 only_simple_this_property_assignments =
3281 temp_scope.only_simple_this_property_assignments(); 3581 temp_scope.only_simple_this_property_assignments();
3282 this_property_assignments = temp_scope.this_property_assignments(); 3582 this_property_assignments = temp_scope.this_property_assignments();
3283 3583
3284 Expect(Token::RBRACE, CHECK_OK); 3584 Expect(Token::RBRACE, CHECK_OK);
3285 end_pos = scanner().location().end_pos; 3585 end_pos = scanner().location().end_pos;
3286 } 3586 }
3287 3587
3588 // Validate strict mode.
3589 if (temp_scope_->StrictMode()) {
3590 if (IsEvalOrArguments(name)) {
3591 int position = function_token_position != RelocInfo::kNoPosition
3592 ? function_token_position
3593 : (start_pos > 0 ? start_pos - 1 : start_pos);
3594 Scanner::Location location = Scanner::Location(position, start_pos);
3595 ReportMessageAt(location,
3596 "strict_function_name", Vector<const char*>::empty());
3597 *ok = false;
3598 return NULL;
3599 }
3600 if (name_loc.IsValid()) {
3601 ReportMessageAt(name_loc, "strict_param_name",
3602 Vector<const char*>::empty());
3603 *ok = false;
3604 return NULL;
3605 }
3606 if (dupe_loc.IsValid()) {
3607 ReportMessageAt(dupe_loc, "strict_param_dupe",
3608 Vector<const char*>::empty());
3609 *ok = false;
3610 return NULL;
3611 }
3612 if (name_is_reserved) {
3613 int position = function_token_position != RelocInfo::kNoPosition
3614 ? function_token_position
3615 : (start_pos > 0 ? start_pos - 1 : start_pos);
3616 Scanner::Location location = Scanner::Location(position, start_pos);
3617 ReportMessageAt(location, "strict_reserved_word",
3618 Vector<const char*>::empty());
3619 *ok = false;
3620 return NULL;
3621 }
3622 if (reserved_loc.IsValid()) {
3623 ReportMessageAt(reserved_loc, "strict_reserved_word",
3624 Vector<const char*>::empty());
3625 *ok = false;
3626 return NULL;
3627 }
3628 CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
3629 }
3630
3288 FunctionLiteral* function_literal = 3631 FunctionLiteral* function_literal =
3289 new FunctionLiteral(name, 3632 new FunctionLiteral(name,
3290 top_scope_, 3633 top_scope_,
3291 body, 3634 body,
3292 materialized_literal_count, 3635 materialized_literal_count,
3293 expected_property_count, 3636 expected_property_count,
3294 only_simple_this_property_assignments, 3637 only_simple_this_property_assignments,
3295 this_property_assignments, 3638 this_property_assignments,
3296 num_parameters, 3639 num_parameters,
3297 start_pos, 3640 start_pos,
3298 end_pos, 3641 end_pos,
3299 function_name->length() > 0, 3642 function_name->length() > 0,
3300 temp_scope.ContainsLoops()); 3643 temp_scope.ContainsLoops(),
3644 temp_scope.StrictMode());
3301 function_literal->set_function_token_position(function_token_position); 3645 function_literal->set_function_token_position(function_token_position);
3302 3646
3303 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); 3647 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
3304 return function_literal; 3648 return function_literal;
3305 } 3649 }
3306 } 3650 }
3307 3651
3308 3652
3309 Expression* Parser::ParseV8Intrinsic(bool* ok) { 3653 Expression* Parser::ParseV8Intrinsic(bool* ok) {
3310 // CallRuntime :: 3654 // CallRuntime ::
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3345 ReportMessage("illegal_access", Vector<const char*>::empty()); 3689 ReportMessage("illegal_access", Vector<const char*>::empty());
3346 *ok = false; 3690 *ok = false;
3347 return NULL; 3691 return NULL;
3348 } 3692 }
3349 3693
3350 // We have a valid intrinsics call or a call to a builtin. 3694 // We have a valid intrinsics call or a call to a builtin.
3351 return new CallRuntime(name, function, args); 3695 return new CallRuntime(name, function, args);
3352 } 3696 }
3353 3697
3354 3698
3699 bool Parser::peek_any_identifier() {
3700 Token::Value next = peek();
3701 return next == Token::IDENTIFIER ||
3702 next == Token::FUTURE_RESERVED_WORD;
3703 }
3704
3705
3355 void Parser::Consume(Token::Value token) { 3706 void Parser::Consume(Token::Value token) {
3356 Token::Value next = Next(); 3707 Token::Value next = Next();
3357 USE(next); 3708 USE(next);
3358 USE(token); 3709 USE(token);
3359 ASSERT(next == token); 3710 ASSERT(next == token);
3360 } 3711 }
3361 3712
3362 3713
3363 void Parser::Expect(Token::Value token, bool* ok) { 3714 void Parser::Expect(Token::Value token, bool* ok) {
3364 Token::Value next = Next(); 3715 Token::Value next = Next();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3404 return new Literal(Factory::the_hole_value()); 3755 return new Literal(Factory::the_hole_value());
3405 } 3756 }
3406 3757
3407 3758
3408 Literal* Parser::GetLiteralNumber(double value) { 3759 Literal* Parser::GetLiteralNumber(double value) {
3409 return NewNumberLiteral(value); 3760 return NewNumberLiteral(value);
3410 } 3761 }
3411 3762
3412 3763
3413 Handle<String> Parser::ParseIdentifier(bool* ok) { 3764 Handle<String> Parser::ParseIdentifier(bool* ok) {
3414 Expect(Token::IDENTIFIER, ok); 3765 bool is_reserved;
3766 return ParseIdentifierOrReservedWord(&is_reserved, ok);
3767 }
3768
3769
3770 Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved,
3771 bool* ok) {
3772 *is_reserved = false;
3773 if (temp_scope_->StrictMode()) {
3774 Expect(Token::IDENTIFIER, ok);
3775 } else {
3776 if (!Check(Token::IDENTIFIER)) {
3777 Expect(Token::FUTURE_RESERVED_WORD, ok);
3778 *is_reserved = true;
3779 }
3780 }
3415 if (!*ok) return Handle<String>(); 3781 if (!*ok) return Handle<String>();
3416 return GetSymbol(ok); 3782 return GetSymbol(ok);
3417 } 3783 }
3418 3784
3419 3785
3420 Handle<String> Parser::ParseIdentifierName(bool* ok) { 3786 Handle<String> Parser::ParseIdentifierName(bool* ok) {
3421 Token::Value next = Next(); 3787 Token::Value next = Next();
3422 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) { 3788 if (next != Token::IDENTIFIER &&
3789 next != Token::FUTURE_RESERVED_WORD &&
3790 !Token::IsKeyword(next)) {
3423 ReportUnexpectedToken(next); 3791 ReportUnexpectedToken(next);
3424 *ok = false; 3792 *ok = false;
3425 return Handle<String>(); 3793 return Handle<String>();
3426 } 3794 }
3427 return GetSymbol(ok); 3795 return GetSymbol(ok);
3428 } 3796 }
3429 3797
3430 3798
3799 // Checks LHS expression for assignment and prefix/postfix increment/decrement
3800 // in strict mode.
3801 void Parser::CheckStrictModeLValue(Expression* expression,
3802 const char* error,
3803 bool* ok) {
3804 ASSERT(temp_scope_->StrictMode());
3805 VariableProxy* lhs = expression != NULL
3806 ? expression->AsVariableProxy()
3807 : NULL;
3808
3809 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) {
3810 ReportMessage(error, Vector<const char*>::empty());
3811 *ok = false;
3812 }
3813 }
3814
3815
3816 // Checks whether octal literal last seen is between beg_pos and end_pos.
3817 // If so, reports an error.
3818 void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
3819 int octal = scanner().octal_position();
3820 if (beg_pos <= octal && octal <= end_pos) {
3821 ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal",
3822 Vector<const char*>::empty());
3823 scanner().clear_octal_position();
3824 *ok = false;
3825 }
3826 }
3827
3828
3431 // This function reads an identifier and determines whether or not it 3829 // This function reads an identifier and determines whether or not it
3432 // is 'get' or 'set'. The reason for not using ParseIdentifier and 3830 // is 'get' or 'set'.
3433 // checking on the output is that this involves heap allocation which
3434 // we can't do during preparsing.
3435 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, 3831 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get,
3436 bool* is_set, 3832 bool* is_set,
3437 bool* ok) { 3833 bool* ok) {
3438 Expect(Token::IDENTIFIER, ok); 3834 Handle<String> result = ParseIdentifier(ok);
3439 if (!*ok) return Handle<String>(); 3835 if (!*ok) return Handle<String>();
3440 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { 3836 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
3441 const char* token = scanner().literal_ascii_string().start(); 3837 const char* token = scanner().literal_ascii_string().start();
3442 *is_get = strncmp(token, "get", 3) == 0; 3838 *is_get = strncmp(token, "get", 3) == 0;
3443 *is_set = !*is_get && strncmp(token, "set", 3) == 0; 3839 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
3444 } 3840 }
3445 return GetSymbol(ok); 3841 return result;
3446 } 3842 }
3447 3843
3448 3844
3449 // ---------------------------------------------------------------------------- 3845 // ----------------------------------------------------------------------------
3450 // Parser support 3846 // Parser support
3451 3847
3452 3848
3453 bool Parser::TargetStackContainsLabel(Handle<String> label) { 3849 bool Parser::TargetStackContainsLabel(Handle<String> label) {
3454 for (Target* t = target_stack_; t != NULL; t = t->previous()) { 3850 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3455 BreakableStatement* stat = t->node()->AsBreakableStatement(); 3851 BreakableStatement* stat = t->node()->AsBreakableStatement();
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
3530 Vector< Handle<Object> > arguments = 3926 Vector< Handle<Object> > arguments =
3531 HandleVector<Object>(elements, ARRAY_SIZE(elements)); 3927 HandleVector<Object>(elements, ARRAY_SIZE(elements));
3532 return NewThrowError(Factory::MakeTypeError_symbol(), type, arguments); 3928 return NewThrowError(Factory::MakeTypeError_symbol(), type, arguments);
3533 } 3929 }
3534 3930
3535 3931
3536 Expression* Parser::NewThrowError(Handle<String> constructor, 3932 Expression* Parser::NewThrowError(Handle<String> constructor,
3537 Handle<String> type, 3933 Handle<String> type,
3538 Vector< Handle<Object> > arguments) { 3934 Vector< Handle<Object> > arguments) {
3539 int argc = arguments.length(); 3935 int argc = arguments.length();
3540 Handle<JSArray> array = Factory::NewJSArray(argc, TENURED); 3936 Handle<FixedArray> elements = Factory::NewFixedArray(argc, TENURED);
3541 ASSERT(array->IsJSArray() && array->HasFastElements());
3542 for (int i = 0; i < argc; i++) { 3937 for (int i = 0; i < argc; i++) {
3543 Handle<Object> element = arguments[i]; 3938 Handle<Object> element = arguments[i];
3544 if (!element.is_null()) { 3939 if (!element.is_null()) {
3545 // We know this doesn't cause a GC here because we allocated the JSArray 3940 elements->set(i, *element);
3546 // large enough.
3547 array->SetFastElement(i, *element)->ToObjectUnchecked();
3548 } 3941 }
3549 } 3942 }
3943 Handle<JSArray> array = Factory::NewJSArrayWithElements(elements, TENURED);
3944
3550 ZoneList<Expression*>* args = new ZoneList<Expression*>(2); 3945 ZoneList<Expression*>* args = new ZoneList<Expression*>(2);
3551 args->Add(new Literal(type)); 3946 args->Add(new Literal(type));
3552 args->Add(new Literal(array)); 3947 args->Add(new Literal(array));
3553 return new Throw(new CallRuntime(constructor, NULL, args), 3948 return new Throw(new CallRuntime(constructor, NULL, args),
3554 scanner().location().beg_pos); 3949 scanner().location().beg_pos);
3555 } 3950 }
3556 3951
3557 // ---------------------------------------------------------------------------- 3952 // ----------------------------------------------------------------------------
3558 // JSON 3953 // JSON
3559 3954
(...skipping 17 matching lines...) Expand all
3577 case Token::EOS: 3972 case Token::EOS:
3578 message = "unexpected_eos"; 3973 message = "unexpected_eos";
3579 break; 3974 break;
3580 case Token::NUMBER: 3975 case Token::NUMBER:
3581 message = "unexpected_token_number"; 3976 message = "unexpected_token_number";
3582 break; 3977 break;
3583 case Token::STRING: 3978 case Token::STRING:
3584 message = "unexpected_token_string"; 3979 message = "unexpected_token_string";
3585 break; 3980 break;
3586 case Token::IDENTIFIER: 3981 case Token::IDENTIFIER:
3982 case Token::FUTURE_RESERVED_WORD:
3587 message = "unexpected_token_identifier"; 3983 message = "unexpected_token_identifier";
3588 break; 3984 break;
3589 default: 3985 default:
3590 message = "unexpected_token"; 3986 message = "unexpected_token";
3591 name_opt = Token::String(token); 3987 name_opt = Token::String(token);
3592 ASSERT(name_opt != NULL); 3988 ASSERT(name_opt != NULL);
3593 break; 3989 break;
3594 } 3990 }
3595 3991
3596 Scanner::Location source_location = scanner_.location(); 3992 Scanner::Location source_location = scanner_.location();
(...skipping 26 matching lines...) Expand all
3623 } else { 4019 } else {
3624 return Factory::NewStringFromTwoByte(scanner_.literal_uc16_string()); 4020 return Factory::NewStringFromTwoByte(scanner_.literal_uc16_string());
3625 } 4021 }
3626 } 4022 }
3627 4023
3628 4024
3629 // Parse any JSON value. 4025 // Parse any JSON value.
3630 Handle<Object> JsonParser::ParseJsonValue() { 4026 Handle<Object> JsonParser::ParseJsonValue() {
3631 Token::Value token = scanner_.Next(); 4027 Token::Value token = scanner_.Next();
3632 switch (token) { 4028 switch (token) {
3633 case Token::STRING: { 4029 case Token::STRING:
3634 return GetString(); 4030 return GetString();
3635 } 4031 case Token::NUMBER:
3636 case Token::NUMBER: { 4032 return Factory::NewNumber(scanner_.number());
3637 ASSERT(scanner_.is_literal_ascii());
3638 double value = StringToDouble(scanner_.literal_ascii_string(),
3639 NO_FLAGS, // Hex, octal or trailing junk.
3640 OS::nan_value());
3641 return Factory::NewNumber(value);
3642 }
3643 case Token::FALSE_LITERAL: 4033 case Token::FALSE_LITERAL:
3644 return Factory::false_value(); 4034 return Factory::false_value();
3645 case Token::TRUE_LITERAL: 4035 case Token::TRUE_LITERAL:
3646 return Factory::true_value(); 4036 return Factory::true_value();
3647 case Token::NULL_LITERAL: 4037 case Token::NULL_LITERAL:
3648 return Factory::null_value(); 4038 return Factory::null_value();
3649 case Token::LBRACE: 4039 case Token::LBRACE:
3650 return ParseJsonObject(); 4040 return ParseJsonObject();
3651 case Token::LBRACK: 4041 case Token::LBRACK:
3652 return ParseJsonArray(); 4042 return ParseJsonArray();
(...skipping 20 matching lines...) Expand all
3673 return ReportUnexpectedToken(); 4063 return ReportUnexpectedToken();
3674 } 4064 }
3675 Handle<String> key = GetString(); 4065 Handle<String> key = GetString();
3676 if (scanner_.Next() != Token::COLON) { 4066 if (scanner_.Next() != Token::COLON) {
3677 return ReportUnexpectedToken(); 4067 return ReportUnexpectedToken();
3678 } 4068 }
3679 Handle<Object> value = ParseJsonValue(); 4069 Handle<Object> value = ParseJsonValue();
3680 if (value.is_null()) return Handle<Object>::null(); 4070 if (value.is_null()) return Handle<Object>::null();
3681 uint32_t index; 4071 uint32_t index;
3682 if (key->AsArrayIndex(&index)) { 4072 if (key->AsArrayIndex(&index)) {
3683 CALL_HEAP_FUNCTION_INLINE( 4073 SetOwnElement(json_object, index, value);
3684 (*json_object)->SetElement(index, *value, true)); 4074 } else if (key->Equals(Heap::Proto_symbol())) {
4075 // We can't remove the __proto__ accessor since it's hardcoded
4076 // in several places. Instead go along and add the value as
4077 // the prototype of the created object if possible.
4078 SetPrototype(json_object, value);
3685 } else { 4079 } else {
3686 CALL_HEAP_FUNCTION_INLINE( 4080 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE);
3687 (*json_object)->SetPropertyPostInterceptor(*key, *value, NONE));
3688 } 4081 }
3689 } while (scanner_.Next() == Token::COMMA); 4082 } while (scanner_.Next() == Token::COMMA);
3690 if (scanner_.current_token() != Token::RBRACE) { 4083 if (scanner_.current_token() != Token::RBRACE) {
3691 return ReportUnexpectedToken(); 4084 return ReportUnexpectedToken();
3692 } 4085 }
3693 } 4086 }
3694 return json_object; 4087 return json_object;
3695 } 4088 }
3696 4089
3697 4090
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
4037 break; 4430 break;
4038 case 't': 4431 case 't':
4039 Advance(2); 4432 Advance(2);
4040 builder->AddCharacter('\t'); 4433 builder->AddCharacter('\t');
4041 break; 4434 break;
4042 case 'v': 4435 case 'v':
4043 Advance(2); 4436 Advance(2);
4044 builder->AddCharacter('\v'); 4437 builder->AddCharacter('\v');
4045 break; 4438 break;
4046 case 'c': { 4439 case 'c': {
4047 Advance(2); 4440 Advance();
4048 uc32 control = ParseControlLetterEscape(); 4441 uc32 controlLetter = Next();
4049 builder->AddCharacter(control); 4442 // Special case if it is an ASCII letter.
4443 // Convert lower case letters to uppercase.
4444 uc32 letter = controlLetter & ~('a' ^ 'A');
4445 if (letter < 'A' || 'Z' < letter) {
4446 // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
4447 // This is outside the specification. We match JSC in
4448 // reading the backslash as a literal character instead
4449 // of as starting an escape.
4450 builder->AddCharacter('\\');
4451 } else {
4452 Advance(2);
4453 builder->AddCharacter(controlLetter & 0x1f);
4454 }
4050 break; 4455 break;
4051 } 4456 }
4052 case 'x': { 4457 case 'x': {
4053 Advance(2); 4458 Advance(2);
4054 uc32 value; 4459 uc32 value;
4055 if (ParseHexEscape(2, &value)) { 4460 if (ParseHexEscape(2, &value)) {
4056 builder->AddCharacter(value); 4461 builder->AddCharacter(value);
4057 } else { 4462 } else {
4058 builder->AddCharacter('x'); 4463 builder->AddCharacter('x');
4059 } 4464 }
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
4314 } else { 4719 } else {
4315 Reset(start); 4720 Reset(start);
4316 return false; 4721 return false;
4317 } 4722 }
4318 *min_out = min; 4723 *min_out = min;
4319 *max_out = max; 4724 *max_out = max;
4320 return true; 4725 return true;
4321 } 4726 }
4322 4727
4323 4728
4324 // Upper and lower case letters differ by one bit.
4325 STATIC_CHECK(('a' ^ 'A') == 0x20);
4326
4327 uc32 RegExpParser::ParseControlLetterEscape() {
4328 if (!has_more())
4329 return 'c';
4330 uc32 letter = current() & ~(0x20); // Collapse upper and lower case letters.
4331 if (letter < 'A' || 'Z' < letter) {
4332 // Non-spec error-correction: "\c" followed by non-control letter is
4333 // interpreted as an IdentityEscape of 'c'.
4334 return 'c';
4335 }
4336 Advance();
4337 return letter & 0x1f; // Remainder modulo 32, per specification.
4338 }
4339
4340
4341 uc32 RegExpParser::ParseOctalLiteral() { 4729 uc32 RegExpParser::ParseOctalLiteral() {
4342 ASSERT('0' <= current() && current() <= '7'); 4730 ASSERT('0' <= current() && current() <= '7');
4343 // For compatibility with some other browsers (not all), we parse 4731 // For compatibility with some other browsers (not all), we parse
4344 // up to three octal digits with a value below 256. 4732 // up to three octal digits with a value below 256.
4345 uc32 value = current() - '0'; 4733 uc32 value = current() - '0';
4346 Advance(); 4734 Advance();
4347 if ('0' <= current() && current() <= '7') { 4735 if ('0' <= current() && current() <= '7') {
4348 value = value * 8 + current() - '0'; 4736 value = value * 8 + current() - '0';
4349 Advance(); 4737 Advance();
4350 if (value < 32 && '0' <= current() && current() <= '7') { 4738 if (value < 32 && '0' <= current() && current() <= '7') {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4396 return '\n'; 4784 return '\n';
4397 case 'r': 4785 case 'r':
4398 Advance(); 4786 Advance();
4399 return '\r'; 4787 return '\r';
4400 case 't': 4788 case 't':
4401 Advance(); 4789 Advance();
4402 return '\t'; 4790 return '\t';
4403 case 'v': 4791 case 'v':
4404 Advance(); 4792 Advance();
4405 return '\v'; 4793 return '\v';
4406 case 'c': 4794 case 'c': {
4407 Advance(); 4795 uc32 controlLetter = Next();
4408 return ParseControlLetterEscape(); 4796 uc32 letter = controlLetter & ~('A' ^ 'a');
4797 // For compatibility with JSC, inside a character class
4798 // we also accept digits and underscore as control characters.
4799 if ((controlLetter >= '0' && controlLetter <= '9') ||
4800 controlLetter == '_' ||
4801 (letter >= 'A' && letter <= 'Z')) {
4802 Advance(2);
4803 // Control letters mapped to ASCII control characters in the range
4804 // 0x00-0x1f.
4805 return controlLetter & 0x1f;
4806 }
4807 // We match JSC in reading the backslash as a literal
4808 // character instead of as starting an escape.
4809 return '\\';
4810 }
4409 case '0': case '1': case '2': case '3': case '4': case '5': 4811 case '0': case '1': case '2': case '3': case '4': case '5':
4410 case '6': case '7': 4812 case '6': case '7':
4411 // For compatibility, we interpret a decimal escape that isn't 4813 // For compatibility, we interpret a decimal escape that isn't
4412 // a back reference (and therefore either \0 or not valid according 4814 // a back reference (and therefore either \0 or not valid according
4413 // to the specification) as a 1..3 digit octal character code. 4815 // to the specification) as a 1..3 digit octal character code.
4414 return ParseOctalLiteral(); 4816 return ParseOctalLiteral();
4415 case 'x': { 4817 case 'x': {
4416 Advance(); 4818 Advance();
4417 uc32 value; 4819 uc32 value;
4418 if (ParseHexEscape(2, &value)) { 4820 if (ParseHexEscape(2, &value)) {
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
4699 Vector<const char*> args = pre_data->BuildArgs(); 5101 Vector<const char*> args = pre_data->BuildArgs();
4700 parser.ReportMessageAt(loc, message, args); 5102 parser.ReportMessageAt(loc, message, args);
4701 DeleteArray(message); 5103 DeleteArray(message);
4702 for (int i = 0; i < args.length(); i++) { 5104 for (int i = 0; i < args.length(); i++) {
4703 DeleteArray(args[i]); 5105 DeleteArray(args[i]);
4704 } 5106 }
4705 DeleteArray(args.start()); 5107 DeleteArray(args.start());
4706 ASSERT(Top::has_pending_exception()); 5108 ASSERT(Top::has_pending_exception());
4707 } else { 5109 } else {
4708 Handle<String> source = Handle<String>(String::cast(script->source())); 5110 Handle<String> source = Handle<String>(String::cast(script->source()));
4709 result = parser.ParseProgram(source, info->is_global()); 5111 result = parser.ParseProgram(source,
5112 info->is_global(),
5113 info->StrictMode());
4710 } 5114 }
4711 } 5115 }
4712 5116
4713 info->SetFunction(result); 5117 info->SetFunction(result);
4714 return (result != NULL); 5118 return (result != NULL);
4715 } 5119 }
4716 5120
4717 } } // namespace v8::internal 5121 } } // 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