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

Side by Side Diff: src/parser.cc

Issue 6597029: [Isolates] Merge r 6300:6500 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
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_( 321 this_property_assignments_(
314 Isolate::Current()->factory()->empty_fixed_array()), 322 Isolate::Current()->factory()->empty_fixed_array()),
315 loop_count_(0), 323 loop_count_(0),
316 variable_(variable), 324 variable_(variable),
317 parent_(*variable) { 325 parent_(*variable) {
326 // Inherit the strict mode from the parent scope.
327 strict_mode_ = (parent_ != NULL) && parent_->strict_mode_;
318 *variable = this; 328 *variable = this;
319 } 329 }
320 330
321 331
322 TemporaryScope::~TemporaryScope() { 332 TemporaryScope::~TemporaryScope() {
323 *variable_ = parent_; 333 *variable_ = parent_;
324 } 334 }
325 335
326 336
327 Handle<String> Parser::LookupSymbol(int symbol_id) { 337 Handle<String> Parser::LookupSymbol(int symbol_id) {
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 *with_nesting_level_variable_ = prev_level_; 569 *with_nesting_level_variable_ = prev_level_;
560 } 570 }
561 571
562 private: 572 private:
563 Scope** scope_variable_; 573 Scope** scope_variable_;
564 int* with_nesting_level_variable_; 574 int* with_nesting_level_variable_;
565 Scope* prev_scope_; 575 Scope* prev_scope_;
566 int prev_level_; 576 int prev_level_;
567 }; 577 };
568 578
569
570 // ---------------------------------------------------------------------------- 579 // ----------------------------------------------------------------------------
571 // The CHECK_OK macro is a convenient macro to enforce error 580 // The CHECK_OK macro is a convenient macro to enforce error
572 // handling for functions that may fail (by returning !*ok). 581 // handling for functions that may fail (by returning !*ok).
573 // 582 //
574 // CAUTION: This macro appends extra statements after a call, 583 // CAUTION: This macro appends extra statements after a call,
575 // thus it must never be used where only a single statement 584 // thus it must never be used where only a single statement
576 // is correct (e.g. an if statement branch w/o braces)! 585 // is correct (e.g. an if statement branch w/o braces)!
577 586
578 #define CHECK_OK ok); \ 587 #define CHECK_OK ok); \
579 if (!*ok) return NULL; \ 588 if (!*ok) return NULL; \
(...skipping 19 matching lines...) Expand all
599 script_(script), 608 script_(script),
600 scanner_(isolate_), 609 scanner_(isolate_),
601 top_scope_(NULL), 610 top_scope_(NULL),
602 with_nesting_level_(0), 611 with_nesting_level_(0),
603 temp_scope_(NULL), 612 temp_scope_(NULL),
604 target_stack_(NULL), 613 target_stack_(NULL),
605 allow_natives_syntax_(allow_natives_syntax), 614 allow_natives_syntax_(allow_natives_syntax),
606 extension_(extension), 615 extension_(extension),
607 pre_data_(pre_data), 616 pre_data_(pre_data),
608 fni_(NULL), 617 fni_(NULL),
609 stack_overflow_(false) { 618 stack_overflow_(false),
619 parenthesized_function_(false) {
610 AstNode::ResetIds(); 620 AstNode::ResetIds();
611 } 621 }
612 622
613 623
614 FunctionLiteral* Parser::ParseProgram(Handle<String> source, 624 FunctionLiteral* Parser::ParseProgram(Handle<String> source,
615 bool in_global_context) { 625 bool in_global_context) {
616 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); 626 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT);
617 627
618 HistogramTimerScope timer(COUNTERS->parse()); 628 HistogramTimerScope timer(COUNTERS->parse());
619 COUNTERS->total_parse_size()->Increment(source->length()); 629 COUNTERS->total_parse_size()->Increment(source->length());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 : Scope::EVAL_SCOPE; 663 : Scope::EVAL_SCOPE;
654 Handle<String> no_name = isolate()->factory()->empty_symbol(); 664 Handle<String> no_name = isolate()->factory()->empty_symbol();
655 665
656 FunctionLiteral* result = NULL; 666 FunctionLiteral* result = NULL;
657 { Scope* scope = NewScope(top_scope_, type, inside_with()); 667 { Scope* scope = NewScope(top_scope_, type, inside_with());
658 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, 668 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
659 scope); 669 scope);
660 TemporaryScope temp_scope(&this->temp_scope_); 670 TemporaryScope temp_scope(&this->temp_scope_);
661 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); 671 ZoneList<Statement*>* body = new ZoneList<Statement*>(16);
662 bool ok = true; 672 bool ok = true;
673 int beg_loc = scanner().location().beg_pos;
663 ParseSourceElements(body, Token::EOS, &ok); 674 ParseSourceElements(body, Token::EOS, &ok);
675 if (ok && temp_scope_->StrictMode()) {
676 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok);
677 }
664 if (ok) { 678 if (ok) {
665 result = new FunctionLiteral( 679 result = new FunctionLiteral(
666 no_name, 680 no_name,
667 top_scope_, 681 top_scope_,
668 body, 682 body,
669 temp_scope.materialized_literal_count(), 683 temp_scope.materialized_literal_count(),
670 temp_scope.expected_property_count(), 684 temp_scope.expected_property_count(),
671 temp_scope.only_simple_this_property_assignments(), 685 temp_scope.only_simple_this_property_assignments(),
672 temp_scope.this_property_assignments(), 686 temp_scope.this_property_assignments(),
673 0, 687 0,
674 0, 688 0,
675 source->length(), 689 source->length(),
676 false, 690 false,
677 temp_scope.ContainsLoops()); 691 temp_scope.ContainsLoops(),
692 temp_scope.StrictMode());
678 } else if (stack_overflow_) { 693 } else if (stack_overflow_) {
679 isolate()->StackOverflow(); 694 isolate()->StackOverflow();
680 } 695 }
681 } 696 }
682 697
683 // Make sure the target stack is empty. 698 // Make sure the target stack is empty.
684 ASSERT(target_stack_ == NULL); 699 ASSERT(target_stack_ == NULL);
685 700
686 // If there was a syntax error we have to get rid of the AST 701 // If there was a syntax error we have to get rid of the AST
687 // and it is not safe to do so before the scope has been deleted. 702 // and it is not safe to do so before the scope has been deleted.
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 void Parser::ReportMessage(const char* type, Vector<const char*> args) { 791 void Parser::ReportMessage(const char* type, Vector<const char*> args) {
777 Scanner::Location source_location = scanner().location(); 792 Scanner::Location source_location = scanner().location();
778 ReportMessageAt(source_location, type, args); 793 ReportMessageAt(source_location, type, args);
779 } 794 }
780 795
781 796
782 void Parser::ReportMessageAt(Scanner::Location source_location, 797 void Parser::ReportMessageAt(Scanner::Location source_location,
783 const char* type, 798 const char* type,
784 Vector<const char*> args) { 799 Vector<const char*> args) {
785 MessageLocation location(script_, 800 MessageLocation location(script_,
786 source_location.beg_pos, source_location.end_pos); 801 source_location.beg_pos,
802 source_location.end_pos);
787 Handle<JSArray> array = isolate()->factory()->NewJSArray(args.length()); 803 Handle<JSArray> array = isolate()->factory()->NewJSArray(args.length());
788 for (int i = 0; i < args.length(); i++) { 804 for (int i = 0; i < args.length(); i++) {
789 SetElement(array, i, 805 SetElement(array, i,
790 isolate()->factory()->NewStringFromUtf8(CStrVector(args[i]))); 806 isolate()->factory()->NewStringFromUtf8(CStrVector(args[i])));
791 } 807 }
792 Handle<Object> result = isolate()->factory()->NewSyntaxError(type, array); 808 Handle<Object> result = isolate()->factory()->NewSyntaxError(type, array);
793 isolate()->Throw(*result, &location); 809 isolate()->Throw(*result, &location);
794 } 810 }
795 811
796 812
813 void Parser::ReportMessageAt(Scanner::Location source_location,
814 const char* type,
815 Vector<Handle<String> > args) {
816 MessageLocation location(script_,
817 source_location.beg_pos,
818 source_location.end_pos);
819 Handle<JSArray> array = FACTORY->NewJSArray(args.length());
820 for (int i = 0; i < args.length(); i++) {
821 SetElement(array, i, args[i]);
822 }
823 Handle<Object> result = FACTORY->NewSyntaxError(type, array);
824 isolate()->Throw(*result, &location);
825 }
826
827
797 // Base class containing common code for the different finder classes used by 828 // Base class containing common code for the different finder classes used by
798 // the parser. 829 // the parser.
799 class ParserFinder { 830 class ParserFinder {
800 protected: 831 protected:
801 ParserFinder() {} 832 ParserFinder() {}
802 static Assignment* AsAssignment(Statement* stat) { 833 static Assignment* AsAssignment(Statement* stat) {
803 if (stat == NULL) return NULL; 834 if (stat == NULL) return NULL;
804 ExpressionStatement* exp_stat = stat->AsExpressionStatement(); 835 ExpressionStatement* exp_stat = stat->AsExpressionStatement();
805 if (exp_stat == NULL) return NULL; 836 if (exp_stat == NULL) return NULL;
806 return exp_stat->expression()->AsAssignment(); 837 return exp_stat->expression()->AsAssignment();
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 1089
1059 // Allocate a target stack to use for this set of source 1090 // Allocate a target stack to use for this set of source
1060 // elements. This way, all scripts and functions get their own 1091 // elements. This way, all scripts and functions get their own
1061 // target stack thus avoiding illegal breaks and continues across 1092 // target stack thus avoiding illegal breaks and continues across
1062 // functions. 1093 // functions.
1063 TargetScope scope(&this->target_stack_); 1094 TargetScope scope(&this->target_stack_);
1064 1095
1065 ASSERT(processor != NULL); 1096 ASSERT(processor != NULL);
1066 InitializationBlockFinder block_finder; 1097 InitializationBlockFinder block_finder;
1067 ThisNamedPropertyAssigmentFinder this_property_assignment_finder; 1098 ThisNamedPropertyAssigmentFinder this_property_assignment_finder;
1099 bool directive_prologue = true; // Parsing directive prologue.
1100
1068 while (peek() != end_token) { 1101 while (peek() != end_token) {
1102 if (directive_prologue && peek() != Token::STRING) {
1103 directive_prologue = false;
1104 }
1105
1106 Scanner::Location token_loc = scanner().peek_location();
1069 Statement* stat = ParseStatement(NULL, CHECK_OK); 1107 Statement* stat = ParseStatement(NULL, CHECK_OK);
1070 if (stat == NULL || stat->IsEmpty()) continue; 1108
1109 if (stat == NULL || stat->IsEmpty()) {
1110 directive_prologue = false; // End of directive prologue.
1111 continue;
1112 }
1113
1114 if (directive_prologue) {
1115 // A shot at a directive.
1116 ExpressionStatement *e_stat;
1117 Literal *literal;
1118 // Still processing directive prologue?
1119 if ((e_stat = stat->AsExpressionStatement()) != NULL &&
1120 (literal = e_stat->expression()->AsLiteral()) != NULL &&
1121 literal->handle()->IsString()) {
1122 Handle<String> directive = Handle<String>::cast(literal->handle());
1123
1124 // Check "use strict" directive (ES5 14.1).
1125 if (!temp_scope_->StrictMode() &&
1126 directive->Equals(isolate()->heap()->use_strict()) &&
1127 token_loc.end_pos - token_loc.beg_pos ==
1128 isolate()->heap()->use_strict()->length() + 2) {
1129 temp_scope_->EnableStrictMode();
1130 // "use strict" is the only directive for now.
1131 directive_prologue = false;
1132 }
1133 } else {
1134 // End of the directive prologue.
1135 directive_prologue = false;
1136 }
1137 }
1138
1071 // We find and mark the initialization blocks on top level code only. 1139 // We find and mark the initialization blocks on top level code only.
1072 // This is because the optimization prevents reuse of the map transitions, 1140 // This is because the optimization prevents reuse of the map transitions,
1073 // so it should be used only for code that will only be run once. 1141 // so it should be used only for code that will only be run once.
1074 if (top_scope_->is_global_scope()) { 1142 if (top_scope_->is_global_scope()) {
1075 block_finder.Update(stat); 1143 block_finder.Update(stat);
1076 } 1144 }
1077 // Find and mark all assignments to named properties in this (this.x =) 1145 // Find and mark all assignments to named properties in this (this.x =)
1078 if (top_scope_->is_function_scope()) { 1146 if (top_scope_->is_function_scope()) {
1079 this_property_assignment_finder.Update(top_scope_, stat); 1147 this_property_assignment_finder.Update(top_scope_, stat);
1080 } 1148 }
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
1414 Block* Parser::ParseVariableStatement(bool* ok) { 1482 Block* Parser::ParseVariableStatement(bool* ok) {
1415 // VariableStatement :: 1483 // VariableStatement ::
1416 // VariableDeclarations ';' 1484 // VariableDeclarations ';'
1417 1485
1418 Expression* dummy; // to satisfy the ParseVariableDeclarations() signature 1486 Expression* dummy; // to satisfy the ParseVariableDeclarations() signature
1419 Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK); 1487 Block* result = ParseVariableDeclarations(true, &dummy, CHECK_OK);
1420 ExpectSemicolon(CHECK_OK); 1488 ExpectSemicolon(CHECK_OK);
1421 return result; 1489 return result;
1422 } 1490 }
1423 1491
1492 static bool IsEvalOrArguments(Handle<String> string) {
1493 return string.is_identical_to(FACTORY->eval_symbol()) ||
1494 string.is_identical_to(FACTORY->arguments_symbol());
1495 }
1424 1496
1425 // If the variable declaration declares exactly one non-const 1497 // If the variable declaration declares exactly one non-const
1426 // variable, then *var is set to that variable. In all other cases, 1498 // variable, then *var is set to that variable. In all other cases,
1427 // *var is untouched; in particular, it is the caller's responsibility 1499 // *var is untouched; in particular, it is the caller's responsibility
1428 // to initialize it properly. This mechanism is used for the parsing 1500 // to initialize it properly. This mechanism is used for the parsing
1429 // of 'for-in' loops. 1501 // of 'for-in' loops.
1430 Block* Parser::ParseVariableDeclarations(bool accept_IN, 1502 Block* Parser::ParseVariableDeclarations(bool accept_IN,
1431 Expression** var, 1503 Expression** var,
1432 bool* ok) { 1504 bool* ok) {
1433 // VariableDeclarations :: 1505 // VariableDeclarations ::
(...skipping 28 matching lines...) Expand all
1462 VariableProxy* last_var = NULL; // the last variable declared 1534 VariableProxy* last_var = NULL; // the last variable declared
1463 int nvars = 0; // the number of variables declared 1535 int nvars = 0; // the number of variables declared
1464 do { 1536 do {
1465 if (fni_ != NULL) fni_->Enter(); 1537 if (fni_ != NULL) fni_->Enter();
1466 1538
1467 // Parse variable name. 1539 // Parse variable name.
1468 if (nvars > 0) Consume(Token::COMMA); 1540 if (nvars > 0) Consume(Token::COMMA);
1469 Handle<String> name = ParseIdentifier(CHECK_OK); 1541 Handle<String> name = ParseIdentifier(CHECK_OK);
1470 if (fni_ != NULL) fni_->PushVariableName(name); 1542 if (fni_ != NULL) fni_->PushVariableName(name);
1471 1543
1544 // Strict mode variables may not be named eval or arguments
1545 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
1546 ReportMessage("strict_var_name", Vector<const char*>::empty());
1547 *ok = false;
1548 return NULL;
1549 }
1550
1472 // Declare variable. 1551 // Declare variable.
1473 // Note that we *always* must treat the initial value via a separate init 1552 // Note that we *always* must treat the initial value via a separate init
1474 // assignment for variables and constants because the value must be assigned 1553 // assignment for variables and constants because the value must be assigned
1475 // when the variable is encountered in the source. But the variable/constant 1554 // when the variable is encountered in the source. But the variable/constant
1476 // is declared (and set to 'undefined') upon entering the function within 1555 // is declared (and set to 'undefined') upon entering the function within
1477 // which the variable or constant is declared. Only function variables have 1556 // which the variable or constant is declared. Only function variables have
1478 // an initial value in the declaration (because they are initialized upon 1557 // an initial value in the declaration (because they are initialized upon
1479 // entering the function). 1558 // entering the function).
1480 // 1559 //
1481 // If we have a const declaration, in an inner scope, the proxy is always 1560 // If we have a const declaration, in an inner scope, the proxy is always
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
1692 Expect(Token::CONTINUE, CHECK_OK); 1771 Expect(Token::CONTINUE, CHECK_OK);
1693 Handle<String> label = Handle<String>::null(); 1772 Handle<String> label = Handle<String>::null();
1694 Token::Value tok = peek(); 1773 Token::Value tok = peek();
1695 if (!scanner().has_line_terminator_before_next() && 1774 if (!scanner().has_line_terminator_before_next() &&
1696 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 1775 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
1697 label = ParseIdentifier(CHECK_OK); 1776 label = ParseIdentifier(CHECK_OK);
1698 } 1777 }
1699 IterationStatement* target = NULL; 1778 IterationStatement* target = NULL;
1700 target = LookupContinueTarget(label, CHECK_OK); 1779 target = LookupContinueTarget(label, CHECK_OK);
1701 if (target == NULL) { 1780 if (target == NULL) {
1702 // Illegal continue statement. To be consistent with KJS we delay 1781 // Illegal continue statement.
1703 // reporting of the syntax error until runtime. 1782 const char* message = "illegal_continue";
1704 Handle<String> error_type = isolate()->factory()->illegal_continue_symbol(); 1783 Vector<Handle<String> > args;
1705 if (!label.is_null()) { 1784 if (!label.is_null()) {
1706 error_type = isolate()->factory()->unknown_label_symbol(); 1785 message = "unknown_label";
1786 args = Vector<Handle<String> >(&label, 1);
1707 } 1787 }
1708 Expression* throw_error = NewThrowSyntaxError(error_type, label); 1788 ReportMessageAt(scanner().location(), message, args);
1709 return new ExpressionStatement(throw_error); 1789 *ok = false;
1790 return NULL;
1710 } 1791 }
1711 ExpectSemicolon(CHECK_OK); 1792 ExpectSemicolon(CHECK_OK);
1712 return new ContinueStatement(target); 1793 return new ContinueStatement(target);
1713 } 1794 }
1714 1795
1715 1796
1716 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { 1797 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) {
1717 // BreakStatement :: 1798 // BreakStatement ::
1718 // 'break' Identifier? ';' 1799 // 'break' Identifier? ';'
1719 1800
1720 Expect(Token::BREAK, CHECK_OK); 1801 Expect(Token::BREAK, CHECK_OK);
1721 Handle<String> label; 1802 Handle<String> label;
1722 Token::Value tok = peek(); 1803 Token::Value tok = peek();
1723 if (!scanner().has_line_terminator_before_next() && 1804 if (!scanner().has_line_terminator_before_next() &&
1724 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { 1805 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) {
1725 label = ParseIdentifier(CHECK_OK); 1806 label = ParseIdentifier(CHECK_OK);
1726 } 1807 }
1727 // Parse labeled break statements that target themselves into 1808 // Parse labeled break statements that target themselves into
1728 // empty statements, e.g. 'l1: l2: l3: break l2;' 1809 // empty statements, e.g. 'l1: l2: l3: break l2;'
1729 if (!label.is_null() && ContainsLabel(labels, label)) { 1810 if (!label.is_null() && ContainsLabel(labels, label)) {
1730 return EmptyStatement(); 1811 return EmptyStatement();
1731 } 1812 }
1732 BreakableStatement* target = NULL; 1813 BreakableStatement* target = NULL;
1733 target = LookupBreakTarget(label, CHECK_OK); 1814 target = LookupBreakTarget(label, CHECK_OK);
1734 if (target == NULL) { 1815 if (target == NULL) {
1735 // Illegal break statement. To be consistent with KJS we delay 1816 // Illegal break statement.
1736 // reporting of the syntax error until runtime. 1817 const char* message = "illegal_break";
1737 Handle<String> error_type = isolate()->factory()->illegal_break_symbol(); 1818 Vector<Handle<String> > args;
1738 if (!label.is_null()) { 1819 if (!label.is_null()) {
1739 error_type = isolate()->factory()->unknown_label_symbol(); 1820 message = "unknown_label";
1821 args = Vector<Handle<String> >(&label, 1);
1740 } 1822 }
1741 Expression* throw_error = NewThrowSyntaxError(error_type, label); 1823 ReportMessageAt(scanner().location(), message, args);
1742 return new ExpressionStatement(throw_error); 1824 *ok = false;
1825 return NULL;
1743 } 1826 }
1744 ExpectSemicolon(CHECK_OK); 1827 ExpectSemicolon(CHECK_OK);
1745 return new BreakStatement(target); 1828 return new BreakStatement(target);
1746 } 1829 }
1747 1830
1748 1831
1749 Statement* Parser::ParseReturnStatement(bool* ok) { 1832 Statement* Parser::ParseReturnStatement(bool* ok) {
1750 // ReturnStatement :: 1833 // ReturnStatement ::
1751 // 'return' Expression? ';' 1834 // 'return' Expression? ';'
1752 1835
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1818 } 1901 }
1819 return result; 1902 return result;
1820 } 1903 }
1821 1904
1822 1905
1823 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { 1906 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) {
1824 // WithStatement :: 1907 // WithStatement ::
1825 // 'with' '(' Expression ')' Statement 1908 // 'with' '(' Expression ')' Statement
1826 1909
1827 Expect(Token::WITH, CHECK_OK); 1910 Expect(Token::WITH, CHECK_OK);
1911
1912 if (temp_scope_->StrictMode()) {
1913 ReportMessage("strict_mode_with", Vector<const char*>::empty());
1914 *ok = false;
1915 return NULL;
1916 }
1917
1828 Expect(Token::LPAREN, CHECK_OK); 1918 Expect(Token::LPAREN, CHECK_OK);
1829 Expression* expr = ParseExpression(true, CHECK_OK); 1919 Expression* expr = ParseExpression(true, CHECK_OK);
1830 Expect(Token::RPAREN, CHECK_OK); 1920 Expect(Token::RPAREN, CHECK_OK);
1831 1921
1832 return WithHelper(expr, labels, false, CHECK_OK); 1922 return WithHelper(expr, labels, false, CHECK_OK);
1833 } 1923 }
1834 1924
1835 1925
1836 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) { 1926 CaseClause* Parser::ParseCaseClause(bool* default_seen_ptr, bool* ok) {
1837 // CaseClause :: 1927 // CaseClause ::
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1950 // the jump targets. 2040 // the jump targets.
1951 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); 2041 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0);
1952 TargetCollector catch_collector(catch_target_list); 2042 TargetCollector catch_collector(catch_target_list);
1953 bool has_catch = false; 2043 bool has_catch = false;
1954 if (tok == Token::CATCH) { 2044 if (tok == Token::CATCH) {
1955 has_catch = true; 2045 has_catch = true;
1956 Consume(Token::CATCH); 2046 Consume(Token::CATCH);
1957 2047
1958 Expect(Token::LPAREN, CHECK_OK); 2048 Expect(Token::LPAREN, CHECK_OK);
1959 Handle<String> name = ParseIdentifier(CHECK_OK); 2049 Handle<String> name = ParseIdentifier(CHECK_OK);
2050
2051 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) {
2052 ReportMessage("strict_catch_variable", Vector<const char*>::empty());
2053 *ok = false;
2054 return NULL;
2055 }
2056
1960 Expect(Token::RPAREN, CHECK_OK); 2057 Expect(Token::RPAREN, CHECK_OK);
1961 2058
1962 if (peek() == Token::LBRACE) { 2059 if (peek() == Token::LBRACE) {
1963 // Allocate a temporary for holding the finally state while 2060 // Allocate a temporary for holding the finally state while
1964 // executing the finally block. 2061 // executing the finally block.
1965 catch_var = 2062 catch_var =
1966 top_scope_->NewTemporary(isolate()->factory()->catch_var_symbol()); 2063 top_scope_->NewTemporary(isolate()->factory()->catch_var_symbol());
1967 Literal* name_literal = new Literal(name); 2064 Literal* name_literal = new Literal(name);
1968 VariableProxy* catch_var_use = new VariableProxy(catch_var); 2065 VariableProxy* catch_var_use = new VariableProxy(catch_var);
1969 Expression* obj = new CatchExtensionObject(name_literal, catch_var_use); 2066 Expression* obj = new CatchExtensionObject(name_literal, catch_var_use);
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
2491 2588
2492 case Token::LPAREN: { 2589 case Token::LPAREN: {
2493 int pos = scanner().location().beg_pos; 2590 int pos = scanner().location().beg_pos;
2494 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); 2591 ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
2495 2592
2496 // Keep track of eval() calls since they disable all local variable 2593 // Keep track of eval() calls since they disable all local variable
2497 // optimizations. 2594 // optimizations.
2498 // The calls that need special treatment are the 2595 // The calls that need special treatment are the
2499 // direct (i.e. not aliased) eval calls. These calls are all of the 2596 // direct (i.e. not aliased) eval calls. These calls are all of the
2500 // form eval(...) with no explicit receiver object where eval is not 2597 // form eval(...) with no explicit receiver object where eval is not
2501 // declared in the current scope chain. These calls are marked as 2598 // declared in the current scope chain.
2502 // potentially direct eval calls. Whether they are actually direct calls 2599 // These calls are marked as potentially direct eval calls. Whether
2503 // to eval is determined at run time. 2600 // they are actually direct calls to eval is determined at run time.
2601 // TODO(994): In ES5, it doesn't matter if the "eval" var is declared
2602 // in the local scope chain. It only matters that it's called "eval",
2603 // is called without a receiver and it refers to the original eval
2604 // function.
2504 VariableProxy* callee = result->AsVariableProxy(); 2605 VariableProxy* callee = result->AsVariableProxy();
2505 if (callee != NULL && 2606 if (callee != NULL &&
2506 callee->IsVariable(isolate()->factory()->eval_symbol())) { 2607 callee->IsVariable(isolate()->factory()->eval_symbol())) {
2507 Handle<String> name = callee->name(); 2608 Handle<String> name = callee->name();
2508 Variable* var = top_scope_->Lookup(name); 2609 Variable* var = top_scope_->Lookup(name);
2509 if (var == NULL) { 2610 if (var == NULL) {
2510 top_scope_->RecordEvalCall(); 2611 top_scope_->RecordEvalCall();
2511 } 2612 }
2512 } 2613 }
2513 result = NewCall(result, args, pos); 2614 result = NewCall(result, args, pos);
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
2744 case Token::LBRACK: 2845 case Token::LBRACK:
2745 result = ParseArrayLiteral(CHECK_OK); 2846 result = ParseArrayLiteral(CHECK_OK);
2746 break; 2847 break;
2747 2848
2748 case Token::LBRACE: 2849 case Token::LBRACE:
2749 result = ParseObjectLiteral(CHECK_OK); 2850 result = ParseObjectLiteral(CHECK_OK);
2750 break; 2851 break;
2751 2852
2752 case Token::LPAREN: 2853 case Token::LPAREN:
2753 Consume(Token::LPAREN); 2854 Consume(Token::LPAREN);
2855 // Heuristically try to detect immediately called functions before
2856 // seeing the call parentheses.
2857 parenthesized_function_ = (peek() == Token::FUNCTION);
2754 result = ParseExpression(true, CHECK_OK); 2858 result = ParseExpression(true, CHECK_OK);
2755 Expect(Token::RPAREN, CHECK_OK); 2859 Expect(Token::RPAREN, CHECK_OK);
2756 break; 2860 break;
2757 2861
2758 case Token::MOD: 2862 case Token::MOD:
2759 if (allow_natives_syntax_ || extension_ != NULL) { 2863 if (allow_natives_syntax_ || extension_ != NULL) {
2760 result = ParseV8Intrinsic(CHECK_OK); 2864 result = ParseV8Intrinsic(CHECK_OK);
2761 break; 2865 break;
2762 } 2866 }
2763 // If we're not allowing special syntax we fall-through to the 2867 // If we're not allowing special syntax we fall-through to the
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
2918 Handle<Object> Parser::GetBoilerplateValue(Expression* expression) { 3022 Handle<Object> Parser::GetBoilerplateValue(Expression* expression) {
2919 if (expression->AsLiteral() != NULL) { 3023 if (expression->AsLiteral() != NULL) {
2920 return expression->AsLiteral()->handle(); 3024 return expression->AsLiteral()->handle();
2921 } 3025 }
2922 if (CompileTimeValue::IsCompileTimeValue(expression)) { 3026 if (CompileTimeValue::IsCompileTimeValue(expression)) {
2923 return CompileTimeValue::GetValue(expression); 3027 return CompileTimeValue::GetValue(expression);
2924 } 3028 }
2925 return isolate()->factory()->undefined_value(); 3029 return isolate()->factory()->undefined_value();
2926 } 3030 }
2927 3031
3032 // Defined in ast.cc
3033 bool IsEqualString(void* first, void* second);
3034 bool IsEqualSmi(void* first, void* second);
3035
3036
3037 // Validation per 11.1.5 Object Initialiser
3038 class ObjectLiteralPropertyChecker {
3039 public:
3040 ObjectLiteralPropertyChecker(Parser* parser, bool strict) :
3041 props(&IsEqualString),
3042 elems(&IsEqualSmi),
3043 parser_(parser),
3044 strict_(strict) {
3045 }
3046
3047 void CheckProperty(
3048 ObjectLiteral::Property* property,
3049 Scanner::Location loc,
3050 bool* ok);
3051
3052 private:
3053 enum PropertyKind {
3054 kGetAccessor = 0x01,
3055 kSetAccessor = 0x02,
3056 kAccessor = kGetAccessor | kSetAccessor,
3057 kData = 0x04
3058 };
3059
3060 static intptr_t GetPropertyKind(ObjectLiteral::Property* property) {
3061 switch (property->kind()) {
3062 case ObjectLiteral::Property::GETTER:
3063 return kGetAccessor;
3064 case ObjectLiteral::Property::SETTER:
3065 return kSetAccessor;
3066 default:
3067 return kData;
3068 }
3069 }
3070
3071 HashMap props;
3072 HashMap elems;
3073 Parser* parser_;
3074 bool strict_;
3075 };
3076
3077
3078 void ObjectLiteralPropertyChecker::CheckProperty(
3079 ObjectLiteral::Property* property,
3080 Scanner::Location loc,
3081 bool* ok) {
3082
3083 ASSERT(property != NULL);
3084
3085 Literal *lit = property->key();
3086 Handle<Object> handle = lit->handle();
3087
3088 uint32_t hash;
3089 HashMap* map;
3090 void* key;
3091 Smi* smi_key_location;
3092
3093 if (handle->IsSymbol()) {
3094 Handle<String> name(String::cast(*handle));
3095 if (name->AsArrayIndex(&hash)) {
3096 smi_key_location = Smi::FromInt(hash);
3097 key = &smi_key_location;
3098 map = &elems;
3099 } else {
3100 key = handle.location();
3101 hash = name->Hash();
3102 map = &props;
3103 }
3104 } else if (handle->ToArrayIndex(&hash)) {
3105 key = handle.location();
3106 map = &elems;
3107 } else {
3108 ASSERT(handle->IsNumber());
3109 double num = handle->Number();
3110 char arr[100];
3111 Vector<char> buffer(arr, ARRAY_SIZE(arr));
3112 const char* str = DoubleToCString(num, buffer);
3113 Handle<String> name = FACTORY->NewStringFromAscii(CStrVector(str));
3114 key = name.location();
3115 hash = name->Hash();
3116 map = &props;
3117 }
3118
3119 // Lookup property previously defined, if any.
3120 HashMap::Entry* entry = map->Lookup(key, hash, true);
3121 intptr_t prev = reinterpret_cast<intptr_t> (entry->value);
3122 intptr_t curr = GetPropertyKind(property);
3123
3124 // Duplicate data properties are illegal in strict mode.
3125 if (strict_ && (curr & prev & kData) != 0) {
3126 parser_->ReportMessageAt(loc, "strict_duplicate_property",
3127 Vector<const char*>::empty());
3128 *ok = false;
3129 return;
3130 }
3131 // Data property conflicting with an accessor.
3132 if (((curr & kData) && (prev & kAccessor)) ||
3133 ((prev & kData) && (curr & kAccessor))) {
3134 parser_->ReportMessageAt(loc, "accessor_data_property",
3135 Vector<const char*>::empty());
3136 *ok = false;
3137 return;
3138 }
3139 // Two accessors of the same type conflicting
3140 if ((curr & prev & kAccessor) != 0) {
3141 parser_->ReportMessageAt(loc, "accessor_get_set",
3142 Vector<const char*>::empty());
3143 *ok = false;
3144 return;
3145 }
3146
3147 // Update map
3148 entry->value = reinterpret_cast<void*> (prev | curr);
3149 *ok = true;
3150 }
3151
2928 3152
2929 void Parser::BuildObjectLiteralConstantProperties( 3153 void Parser::BuildObjectLiteralConstantProperties(
2930 ZoneList<ObjectLiteral::Property*>* properties, 3154 ZoneList<ObjectLiteral::Property*>* properties,
2931 Handle<FixedArray> constant_properties, 3155 Handle<FixedArray> constant_properties,
2932 bool* is_simple, 3156 bool* is_simple,
2933 bool* fast_elements, 3157 bool* fast_elements,
2934 int* depth) { 3158 int* depth) {
2935 int position = 0; 3159 int position = 0;
2936 // Accumulate the value in local variables and store it at the end. 3160 // Accumulate the value in local variables and store it at the end.
2937 bool is_simple_acc = true; 3161 bool is_simple_acc = true;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
3023 // ObjectLiteral :: 3247 // ObjectLiteral ::
3024 // '{' ( 3248 // '{' (
3025 // ((IdentifierName | String | Number) ':' AssignmentExpression) 3249 // ((IdentifierName | String | Number) ':' AssignmentExpression)
3026 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) 3250 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
3027 // )*[','] '}' 3251 // )*[','] '}'
3028 3252
3029 ZoneList<ObjectLiteral::Property*>* properties = 3253 ZoneList<ObjectLiteral::Property*>* properties =
3030 new ZoneList<ObjectLiteral::Property*>(4); 3254 new ZoneList<ObjectLiteral::Property*>(4);
3031 int number_of_boilerplate_properties = 0; 3255 int number_of_boilerplate_properties = 0;
3032 3256
3257 ObjectLiteralPropertyChecker checker(this, temp_scope_->StrictMode());
3258
3033 Expect(Token::LBRACE, CHECK_OK); 3259 Expect(Token::LBRACE, CHECK_OK);
3260 Scanner::Location loc = scanner().location();
3261
3034 while (peek() != Token::RBRACE) { 3262 while (peek() != Token::RBRACE) {
3035 if (fni_ != NULL) fni_->Enter(); 3263 if (fni_ != NULL) fni_->Enter();
3036 3264
3037 Literal* key = NULL; 3265 Literal* key = NULL;
3038 Token::Value next = peek(); 3266 Token::Value next = peek();
3267
3268 // Location of the property name token
3269 Scanner::Location loc = scanner().peek_location();
3270
3039 switch (next) { 3271 switch (next) {
3040 case Token::IDENTIFIER: { 3272 case Token::IDENTIFIER: {
3041 bool is_getter = false; 3273 bool is_getter = false;
3042 bool is_setter = false; 3274 bool is_setter = false;
3043 Handle<String> id = 3275 Handle<String> id =
3044 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 3276 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
3045 if (fni_ != NULL) fni_->PushLiteralName(id); 3277 if (fni_ != NULL) fni_->PushLiteralName(id);
3046 3278
3047 if ((is_getter || is_setter) && peek() != Token::COLON) { 3279 if ((is_getter || is_setter) && peek() != Token::COLON) {
3280 // Update loc to point to the identifier
3281 loc = scanner().peek_location();
3048 ObjectLiteral::Property* property = 3282 ObjectLiteral::Property* property =
3049 ParseObjectLiteralGetSet(is_getter, CHECK_OK); 3283 ParseObjectLiteralGetSet(is_getter, CHECK_OK);
3050 if (IsBoilerplateProperty(property)) { 3284 if (IsBoilerplateProperty(property)) {
3051 number_of_boilerplate_properties++; 3285 number_of_boilerplate_properties++;
3052 } 3286 }
3287 // Validate the property.
3288 checker.CheckProperty(property, loc, CHECK_OK);
3053 properties->Add(property); 3289 properties->Add(property);
3054 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 3290 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
3055 3291
3056 if (fni_ != NULL) { 3292 if (fni_ != NULL) {
3057 fni_->Infer(); 3293 fni_->Infer();
3058 fni_->Leave(); 3294 fni_->Leave();
3059 } 3295 }
3060 continue; // restart the while 3296 continue; // restart the while
3061 } 3297 }
3062 // Failed to parse as get/set property, so it's just a property 3298 // 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
3099 } 3335 }
3100 3336
3101 Expect(Token::COLON, CHECK_OK); 3337 Expect(Token::COLON, CHECK_OK);
3102 Expression* value = ParseAssignmentExpression(true, CHECK_OK); 3338 Expression* value = ParseAssignmentExpression(true, CHECK_OK);
3103 3339
3104 ObjectLiteral::Property* property = 3340 ObjectLiteral::Property* property =
3105 new ObjectLiteral::Property(key, value); 3341 new ObjectLiteral::Property(key, value);
3106 3342
3107 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 3343 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
3108 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; 3344 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++;
3345 // Validate the property
3346 checker.CheckProperty(property, loc, CHECK_OK);
3109 properties->Add(property); 3347 properties->Add(property);
3110 3348
3111 // TODO(1240767): Consider allowing trailing comma. 3349 // TODO(1240767): Consider allowing trailing comma.
3112 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); 3350 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK);
3113 3351
3114 if (fni_ != NULL) { 3352 if (fni_ != NULL) {
3115 fni_->Infer(); 3353 fni_->Infer();
3116 fni_->Leave(); 3354 fni_->Leave();
3117 } 3355 }
3118 } 3356 }
3119 Expect(Token::RBRACE, CHECK_OK); 3357 Expect(Token::RBRACE, CHECK_OK);
3358
3120 // Computation of literal_index must happen before pre parse bailout. 3359 // Computation of literal_index must happen before pre parse bailout.
3121 int literal_index = temp_scope_->NextMaterializedLiteralIndex(); 3360 int literal_index = temp_scope_->NextMaterializedLiteralIndex();
3122 3361
3123 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray( 3362 Handle<FixedArray> constant_properties = isolate()->factory()->NewFixedArray(
3124 number_of_boilerplate_properties * 2, TENURED); 3363 number_of_boilerplate_properties * 2, TENURED);
3125 3364
3126 bool is_simple = true; 3365 bool is_simple = true;
3127 bool fast_elements = true; 3366 bool fast_elements = true;
3128 int depth = 1; 3367 int depth = 1;
3129 BuildObjectLiteralConstantProperties(properties, 3368 BuildObjectLiteralConstantProperties(properties,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
3203 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with()); 3442 NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
3204 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, 3443 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
3205 scope); 3444 scope);
3206 TemporaryScope temp_scope(&this->temp_scope_); 3445 TemporaryScope temp_scope(&this->temp_scope_);
3207 top_scope_->SetScopeName(name); 3446 top_scope_->SetScopeName(name);
3208 3447
3209 // FormalParameterList :: 3448 // FormalParameterList ::
3210 // '(' (Identifier)*[','] ')' 3449 // '(' (Identifier)*[','] ')'
3211 Expect(Token::LPAREN, CHECK_OK); 3450 Expect(Token::LPAREN, CHECK_OK);
3212 int start_pos = scanner().location().beg_pos; 3451 int start_pos = scanner().location().beg_pos;
3452 Scanner::Location name_loc = Scanner::NoLocation();
3453 Scanner::Location dupe_loc = Scanner::NoLocation();
3454
3213 bool done = (peek() == Token::RPAREN); 3455 bool done = (peek() == Token::RPAREN);
3214 while (!done) { 3456 while (!done) {
3215 Handle<String> param_name = ParseIdentifier(CHECK_OK); 3457 Handle<String> param_name = ParseIdentifier(CHECK_OK);
3216 top_scope_->AddParameter(top_scope_->DeclareLocal(param_name, 3458
3217 Variable::VAR)); 3459 // Store locations for possible future error reports.
3460 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
3461 name_loc = scanner().location();
3462 }
3463 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
3464 dupe_loc = scanner().location();
3465 }
3466
3467 Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR);
3468 top_scope_->AddParameter(parameter);
3218 num_parameters++; 3469 num_parameters++;
3219 done = (peek() == Token::RPAREN); 3470 done = (peek() == Token::RPAREN);
3220 if (!done) Expect(Token::COMMA, CHECK_OK); 3471 if (!done) Expect(Token::COMMA, CHECK_OK);
3221 } 3472 }
3222 Expect(Token::RPAREN, CHECK_OK); 3473 Expect(Token::RPAREN, CHECK_OK);
3223 3474
3224 Expect(Token::LBRACE, CHECK_OK); 3475 Expect(Token::LBRACE, CHECK_OK);
3225 ZoneList<Statement*>* body = new ZoneList<Statement*>(8); 3476 ZoneList<Statement*>* body = new ZoneList<Statement*>(8);
3226 3477
3227 // If we have a named function expression, we add a local variable 3478 // If we have a named function expression, we add a local variable
3228 // declaration to the body of the function with the name of the 3479 // declaration to the body of the function with the name of the
3229 // function and let it refer to the function itself (closure). 3480 // function and let it refer to the function itself (closure).
3230 // NOTE: We create a proxy and resolve it here so that in the 3481 // NOTE: We create a proxy and resolve it here so that in the
3231 // future we can change the AST to only refer to VariableProxies 3482 // future we can change the AST to only refer to VariableProxies
3232 // instead of Variables and Proxis as is the case now. 3483 // instead of Variables and Proxis as is the case now.
3233 if (!function_name.is_null() && function_name->length() > 0) { 3484 if (!function_name.is_null() && function_name->length() > 0) {
3234 Variable* fvar = top_scope_->DeclareFunctionVar(function_name); 3485 Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
3235 VariableProxy* fproxy = 3486 VariableProxy* fproxy =
3236 top_scope_->NewUnresolved(function_name, inside_with()); 3487 top_scope_->NewUnresolved(function_name, inside_with());
3237 fproxy->BindTo(fvar); 3488 fproxy->BindTo(fvar);
3238 body->Add(new ExpressionStatement( 3489 body->Add(new ExpressionStatement(
3239 new Assignment(Token::INIT_CONST, fproxy, 3490 new Assignment(Token::INIT_CONST, fproxy,
3240 new ThisFunction(), 3491 new ThisFunction(),
3241 RelocInfo::kNoPosition))); 3492 RelocInfo::kNoPosition)));
3242 } 3493 }
3243 3494
3244 // Determine if the function will be lazily compiled. The mode can 3495 // Determine if the function will be lazily compiled. The mode can
3245 // only be PARSE_LAZILY if the --lazy flag is true. 3496 // only be PARSE_LAZILY if the --lazy flag is true.
3246 bool is_lazily_compiled = 3497 bool is_lazily_compiled = (mode() == PARSE_LAZILY &&
3247 mode() == PARSE_LAZILY && top_scope_->HasTrivialOuterContext(); 3498 top_scope_->outer_scope()->is_global_scope() &&
3499 top_scope_->HasTrivialOuterContext() &&
3500 !parenthesized_function_);
3501 parenthesized_function_ = false; // The bit was set for this function only.
3248 3502
3249 int function_block_pos = scanner().location().beg_pos; 3503 int function_block_pos = scanner().location().beg_pos;
3250 int materialized_literal_count; 3504 int materialized_literal_count;
3251 int expected_property_count; 3505 int expected_property_count;
3252 int end_pos; 3506 int end_pos;
3253 bool only_simple_this_property_assignments; 3507 bool only_simple_this_property_assignments;
3254 Handle<FixedArray> this_property_assignments; 3508 Handle<FixedArray> this_property_assignments;
3255 if (is_lazily_compiled && pre_data() != NULL) { 3509 if (is_lazily_compiled && pre_data() != NULL) {
3256 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos); 3510 FunctionEntry entry = pre_data()->GetFunctionEntry(function_block_pos);
3257 if (!entry.is_valid()) { 3511 if (!entry.is_valid()) {
(...skipping 19 matching lines...) Expand all
3277 materialized_literal_count = temp_scope.materialized_literal_count(); 3531 materialized_literal_count = temp_scope.materialized_literal_count();
3278 expected_property_count = temp_scope.expected_property_count(); 3532 expected_property_count = temp_scope.expected_property_count();
3279 only_simple_this_property_assignments = 3533 only_simple_this_property_assignments =
3280 temp_scope.only_simple_this_property_assignments(); 3534 temp_scope.only_simple_this_property_assignments();
3281 this_property_assignments = temp_scope.this_property_assignments(); 3535 this_property_assignments = temp_scope.this_property_assignments();
3282 3536
3283 Expect(Token::RBRACE, CHECK_OK); 3537 Expect(Token::RBRACE, CHECK_OK);
3284 end_pos = scanner().location().end_pos; 3538 end_pos = scanner().location().end_pos;
3285 } 3539 }
3286 3540
3541 // Validate strict mode.
3542 if (temp_scope_->StrictMode()) {
3543 if (IsEvalOrArguments(name)) {
3544 int position = function_token_position != RelocInfo::kNoPosition
3545 ? function_token_position
3546 : (start_pos > 0 ? start_pos - 1 : start_pos);
3547 ReportMessageAt(Scanner::Location(position, start_pos),
3548 "strict_function_name", Vector<const char*>::empty());
3549 *ok = false;
3550 return NULL;
3551 }
3552 if (name_loc.IsValid()) {
3553 ReportMessageAt(name_loc, "strict_param_name",
3554 Vector<const char*>::empty());
3555 *ok = false;
3556 return NULL;
3557 }
3558 if (dupe_loc.IsValid()) {
3559 ReportMessageAt(dupe_loc, "strict_param_dupe",
3560 Vector<const char*>::empty());
3561 *ok = false;
3562 return NULL;
3563 }
3564 CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
3565 }
3566
3287 FunctionLiteral* function_literal = 3567 FunctionLiteral* function_literal =
3288 new FunctionLiteral(name, 3568 new FunctionLiteral(name,
3289 top_scope_, 3569 top_scope_,
3290 body, 3570 body,
3291 materialized_literal_count, 3571 materialized_literal_count,
3292 expected_property_count, 3572 expected_property_count,
3293 only_simple_this_property_assignments, 3573 only_simple_this_property_assignments,
3294 this_property_assignments, 3574 this_property_assignments,
3295 num_parameters, 3575 num_parameters,
3296 start_pos, 3576 start_pos,
3297 end_pos, 3577 end_pos,
3298 function_name->length() > 0, 3578 function_name->length() > 0,
3299 temp_scope.ContainsLoops()); 3579 temp_scope.ContainsLoops(),
3580 temp_scope.StrictMode());
3300 function_literal->set_function_token_position(function_token_position); 3581 function_literal->set_function_token_position(function_token_position);
3301 3582
3302 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); 3583 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal);
3303 return function_literal; 3584 return function_literal;
3304 } 3585 }
3305 } 3586 }
3306 3587
3307 3588
3308 Expression* Parser::ParseV8Intrinsic(bool* ok) { 3589 Expression* Parser::ParseV8Intrinsic(bool* ok) {
3309 // CallRuntime :: 3590 // CallRuntime ::
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
3419 Handle<String> Parser::ParseIdentifierName(bool* ok) { 3700 Handle<String> Parser::ParseIdentifierName(bool* ok) {
3420 Token::Value next = Next(); 3701 Token::Value next = Next();
3421 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) { 3702 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) {
3422 ReportUnexpectedToken(next); 3703 ReportUnexpectedToken(next);
3423 *ok = false; 3704 *ok = false;
3424 return Handle<String>(); 3705 return Handle<String>();
3425 } 3706 }
3426 return GetSymbol(ok); 3707 return GetSymbol(ok);
3427 } 3708 }
3428 3709
3710 // Checks whether octal literal last seen is between beg_pos and end_pos.
3711 // If so, reports an error.
3712 void Parser::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
3713 int octal = scanner().octal_position();
3714 if (beg_pos <= octal && octal <= end_pos) {
3715 ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal",
3716 Vector<const char*>::empty());
3717 scanner().clear_octal_position();
3718 *ok = false;
3719 }
3720 }
3721
3429 3722
3430 // This function reads an identifier and determines whether or not it 3723 // This function reads an identifier and determines whether or not it
3431 // is 'get' or 'set'. The reason for not using ParseIdentifier and 3724 // is 'get' or 'set'. The reason for not using ParseIdentifier and
3432 // checking on the output is that this involves heap allocation which 3725 // checking on the output is that this involves heap allocation which
3433 // we can't do during preparsing. 3726 // we can't do during preparsing.
3434 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, 3727 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get,
3435 bool* is_set, 3728 bool* is_set,
3436 bool* ok) { 3729 bool* ok) {
3437 Expect(Token::IDENTIFIER, ok); 3730 Expect(Token::IDENTIFIER, ok);
3438 if (!*ok) return Handle<String>(); 3731 if (!*ok) return Handle<String>();
(...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after
4700 Handle<String> source = Handle<String>(String::cast(script->source())); 4993 Handle<String> source = Handle<String>(String::cast(script->source()));
4701 result = parser.ParseProgram(source, info->is_global()); 4994 result = parser.ParseProgram(source, info->is_global());
4702 } 4995 }
4703 } 4996 }
4704 4997
4705 info->SetFunction(result); 4998 info->SetFunction(result);
4706 return (result != NULL); 4999 return (result != NULL);
4707 } 5000 }
4708 5001
4709 } } // namespace v8::internal 5002 } } // 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