| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 Handle<FixedArray> this_property_assignments() { | 276 Handle<FixedArray> this_property_assignments() { |
| 277 return this_property_assignments_; | 277 return this_property_assignments_; |
| 278 } | 278 } |
| 279 | 279 |
| 280 void AddProperty() { expected_property_count_++; } | 280 void AddProperty() { expected_property_count_++; } |
| 281 int expected_property_count() { return expected_property_count_; } | 281 int expected_property_count() { return expected_property_count_; } |
| 282 | 282 |
| 283 void AddLoop() { loop_count_++; } | 283 void AddLoop() { loop_count_++; } |
| 284 bool ContainsLoops() const { return loop_count_ > 0; } | 284 bool ContainsLoops() const { return loop_count_ > 0; } |
| 285 | 285 |
| 286 bool StrictMode() { return strict_mode_; } | |
| 287 void EnableStrictMode() { | |
| 288 strict_mode_ = FLAG_strict_mode; | |
| 289 } | |
| 290 | |
| 291 private: | 286 private: |
| 292 // Captures the number of literals that need materialization in the | 287 // Captures the number of literals that need materialization in the |
| 293 // function. Includes regexp literals, and boilerplate for object | 288 // function. Includes regexp literals, and boilerplate for object |
| 294 // and array literals. | 289 // and array literals. |
| 295 int materialized_literal_count_; | 290 int materialized_literal_count_; |
| 296 | 291 |
| 297 // Properties count estimation. | 292 // Properties count estimation. |
| 298 int expected_property_count_; | 293 int expected_property_count_; |
| 299 | 294 |
| 300 // Keeps track of assignments to properties of this. Used for | 295 // Keeps track of assignments to properties of this. Used for |
| 301 // optimizing constructors. | 296 // optimizing constructors. |
| 302 bool only_simple_this_property_assignments_; | 297 bool only_simple_this_property_assignments_; |
| 303 Handle<FixedArray> this_property_assignments_; | 298 Handle<FixedArray> this_property_assignments_; |
| 304 | 299 |
| 305 // Captures the number of loops inside the scope. | 300 // Captures the number of loops inside the scope. |
| 306 int loop_count_; | 301 int loop_count_; |
| 307 | 302 |
| 308 // Parsing strict mode code. | |
| 309 bool strict_mode_; | |
| 310 | |
| 311 // Bookkeeping | 303 // Bookkeeping |
| 312 TemporaryScope** variable_; | 304 TemporaryScope** variable_; |
| 313 TemporaryScope* parent_; | 305 TemporaryScope* parent_; |
| 314 }; | 306 }; |
| 315 | 307 |
| 316 | 308 |
| 317 TemporaryScope::TemporaryScope(TemporaryScope** variable) | 309 TemporaryScope::TemporaryScope(TemporaryScope** variable) |
| 318 : materialized_literal_count_(0), | 310 : materialized_literal_count_(0), |
| 319 expected_property_count_(0), | 311 expected_property_count_(0), |
| 320 only_simple_this_property_assignments_(false), | 312 only_simple_this_property_assignments_(false), |
| 321 this_property_assignments_(Factory::empty_fixed_array()), | 313 this_property_assignments_(Factory::empty_fixed_array()), |
| 322 loop_count_(0), | 314 loop_count_(0), |
| 323 variable_(variable), | 315 variable_(variable), |
| 324 parent_(*variable) { | 316 parent_(*variable) { |
| 325 // Inherit the strict mode from the parent scope. | |
| 326 strict_mode_ = (parent_ != NULL) && parent_->strict_mode_; | |
| 327 *variable = this; | 317 *variable = this; |
| 328 } | 318 } |
| 329 | 319 |
| 330 | 320 |
| 331 TemporaryScope::~TemporaryScope() { | 321 TemporaryScope::~TemporaryScope() { |
| 332 *variable_ = parent_; | 322 *variable_ = parent_; |
| 333 } | 323 } |
| 334 | 324 |
| 335 | 325 |
| 336 Handle<String> Parser::LookupSymbol(int symbol_id) { | 326 Handle<String> Parser::LookupSymbol(int symbol_id) { |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 ? Scope::GLOBAL_SCOPE | 648 ? Scope::GLOBAL_SCOPE |
| 659 : Scope::EVAL_SCOPE; | 649 : Scope::EVAL_SCOPE; |
| 660 Handle<String> no_name = Factory::empty_symbol(); | 650 Handle<String> no_name = Factory::empty_symbol(); |
| 661 | 651 |
| 662 FunctionLiteral* result = NULL; | 652 FunctionLiteral* result = NULL; |
| 663 { Scope* scope = NewScope(top_scope_, type, inside_with()); | 653 { Scope* scope = NewScope(top_scope_, type, inside_with()); |
| 664 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 654 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 665 scope); | 655 scope); |
| 666 TemporaryScope temp_scope(&this->temp_scope_); | 656 TemporaryScope temp_scope(&this->temp_scope_); |
| 667 if (strict_mode == kStrictMode) { | 657 if (strict_mode == kStrictMode) { |
| 668 temp_scope.EnableStrictMode(); | 658 top_scope_->EnableStrictMode(); |
| 669 } | 659 } |
| 670 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); | 660 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); |
| 671 bool ok = true; | 661 bool ok = true; |
| 672 int beg_loc = scanner().location().beg_pos; | 662 int beg_loc = scanner().location().beg_pos; |
| 673 ParseSourceElements(body, Token::EOS, &ok); | 663 ParseSourceElements(body, Token::EOS, &ok); |
| 674 if (ok && temp_scope_->StrictMode()) { | 664 if (ok && top_scope_->is_strict_mode()) { |
| 675 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 665 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 676 } | 666 } |
| 677 if (ok) { | 667 if (ok) { |
| 678 result = new FunctionLiteral( | 668 result = new FunctionLiteral( |
| 679 no_name, | 669 no_name, |
| 680 top_scope_, | 670 top_scope_, |
| 681 body, | 671 body, |
| 682 temp_scope.materialized_literal_count(), | 672 temp_scope.materialized_literal_count(), |
| 683 temp_scope.expected_property_count(), | 673 temp_scope.expected_property_count(), |
| 684 temp_scope.only_simple_this_property_assignments(), | 674 temp_scope.only_simple_this_property_assignments(), |
| 685 temp_scope.this_property_assignments(), | 675 temp_scope.this_property_assignments(), |
| 686 0, | 676 0, |
| 687 0, | 677 0, |
| 688 source->length(), | 678 source->length(), |
| 689 false, | 679 false, |
| 690 temp_scope.ContainsLoops(), | 680 temp_scope.ContainsLoops()); |
| 691 temp_scope.StrictMode()); | |
| 692 } else if (stack_overflow_) { | 681 } else if (stack_overflow_) { |
| 693 Top::StackOverflow(); | 682 Top::StackOverflow(); |
| 694 } | 683 } |
| 695 } | 684 } |
| 696 | 685 |
| 697 // Make sure the target stack is empty. | 686 // Make sure the target stack is empty. |
| 698 ASSERT(target_stack_ == NULL); | 687 ASSERT(target_stack_ == NULL); |
| 699 | 688 |
| 700 // If there was a syntax error we have to get rid of the AST | 689 // If there was a syntax error we have to get rid of the AST |
| 701 // and it is not safe to do so before the scope has been deleted. | 690 // and it is not safe to do so before the scope has been deleted. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 { | 735 { |
| 747 // Parse the function literal. | 736 // Parse the function literal. |
| 748 Handle<String> no_name = Factory::empty_symbol(); | 737 Handle<String> no_name = Factory::empty_symbol(); |
| 749 Scope* scope = | 738 Scope* scope = |
| 750 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); | 739 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); |
| 751 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 740 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 752 scope); | 741 scope); |
| 753 TemporaryScope temp_scope(&this->temp_scope_); | 742 TemporaryScope temp_scope(&this->temp_scope_); |
| 754 | 743 |
| 755 if (info->strict_mode()) { | 744 if (info->strict_mode()) { |
| 756 temp_scope.EnableStrictMode(); | 745 top_scope_->EnableStrictMode(); |
| 757 } | 746 } |
| 758 | 747 |
| 759 FunctionLiteralType type = | 748 FunctionLiteralType type = |
| 760 info->is_expression() ? EXPRESSION : DECLARATION; | 749 info->is_expression() ? EXPRESSION : DECLARATION; |
| 761 bool ok = true; | 750 bool ok = true; |
| 762 result = ParseFunctionLiteral(name, | 751 result = ParseFunctionLiteral(name, |
| 763 false, // Strict mode name already checked. | 752 false, // Strict mode name already checked. |
| 764 RelocInfo::kNoPosition, type, &ok); | 753 RelocInfo::kNoPosition, type, &ok); |
| 765 // Make sure the results agree. | 754 // Make sure the results agree. |
| 766 ASSERT(ok == (result != NULL)); | 755 ASSERT(ok == (result != NULL)); |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1133 // A shot at a directive. | 1122 // A shot at a directive. |
| 1134 ExpressionStatement *e_stat; | 1123 ExpressionStatement *e_stat; |
| 1135 Literal *literal; | 1124 Literal *literal; |
| 1136 // Still processing directive prologue? | 1125 // Still processing directive prologue? |
| 1137 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 1126 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 1138 (literal = e_stat->expression()->AsLiteral()) != NULL && | 1127 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 1139 literal->handle()->IsString()) { | 1128 literal->handle()->IsString()) { |
| 1140 Handle<String> directive = Handle<String>::cast(literal->handle()); | 1129 Handle<String> directive = Handle<String>::cast(literal->handle()); |
| 1141 | 1130 |
| 1142 // Check "use strict" directive (ES5 14.1). | 1131 // Check "use strict" directive (ES5 14.1). |
| 1143 if (!temp_scope_->StrictMode() && | 1132 if (!top_scope_->is_strict_mode() && |
| 1144 directive->Equals(Heap::use_strict()) && | 1133 directive->Equals(Heap::use_strict()) && |
| 1145 token_loc.end_pos - token_loc.beg_pos == | 1134 token_loc.end_pos - token_loc.beg_pos == |
| 1146 Heap::use_strict()->length() + 2) { | 1135 Heap::use_strict()->length() + 2) { |
| 1147 temp_scope_->EnableStrictMode(); | 1136 top_scope_->EnableStrictMode(); |
| 1148 // "use strict" is the only directive for now. | 1137 // "use strict" is the only directive for now. |
| 1149 directive_prologue = false; | 1138 directive_prologue = false; |
| 1150 } | 1139 } |
| 1151 } else { | 1140 } else { |
| 1152 // End of the directive prologue. | 1141 // End of the directive prologue. |
| 1153 directive_prologue = false; | 1142 directive_prologue = false; |
| 1154 } | 1143 } |
| 1155 } | 1144 } |
| 1156 | 1145 |
| 1157 // We find and mark the initialization blocks on top level code only. | 1146 // We find and mark the initialization blocks on top level code only. |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1275 if (statement) { | 1264 if (statement) { |
| 1276 statement->set_statement_pos(statement_pos); | 1265 statement->set_statement_pos(statement_pos); |
| 1277 } | 1266 } |
| 1278 if (result) result->AddStatement(statement); | 1267 if (result) result->AddStatement(statement); |
| 1279 return result; | 1268 return result; |
| 1280 } | 1269 } |
| 1281 | 1270 |
| 1282 case Token::FUNCTION: { | 1271 case Token::FUNCTION: { |
| 1283 // In strict mode, FunctionDeclaration is only allowed in the context | 1272 // In strict mode, FunctionDeclaration is only allowed in the context |
| 1284 // of SourceElements. | 1273 // of SourceElements. |
| 1285 if (temp_scope_->StrictMode()) { | 1274 if (top_scope_->is_strict_mode()) { |
| 1286 ReportMessageAt(scanner().peek_location(), "strict_function", | 1275 ReportMessageAt(scanner().peek_location(), "strict_function", |
| 1287 Vector<const char*>::empty()); | 1276 Vector<const char*>::empty()); |
| 1288 *ok = false; | 1277 *ok = false; |
| 1289 return NULL; | 1278 return NULL; |
| 1290 } | 1279 } |
| 1291 return ParseFunctionDeclaration(ok); | 1280 return ParseFunctionDeclaration(ok); |
| 1292 } | 1281 } |
| 1293 | 1282 |
| 1294 case Token::NATIVE: | 1283 case Token::NATIVE: |
| 1295 return ParseNativeDeclaration(ok); | 1284 return ParseNativeDeclaration(ok); |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1533 bool* ok) { | 1522 bool* ok) { |
| 1534 // VariableDeclarations :: | 1523 // VariableDeclarations :: |
| 1535 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] | 1524 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] |
| 1536 | 1525 |
| 1537 Variable::Mode mode = Variable::VAR; | 1526 Variable::Mode mode = Variable::VAR; |
| 1538 bool is_const = false; | 1527 bool is_const = false; |
| 1539 if (peek() == Token::VAR) { | 1528 if (peek() == Token::VAR) { |
| 1540 Consume(Token::VAR); | 1529 Consume(Token::VAR); |
| 1541 } else if (peek() == Token::CONST) { | 1530 } else if (peek() == Token::CONST) { |
| 1542 Consume(Token::CONST); | 1531 Consume(Token::CONST); |
| 1543 if (temp_scope_->StrictMode()) { | 1532 if (top_scope_->is_strict_mode()) { |
| 1544 ReportMessage("strict_const", Vector<const char*>::empty()); | 1533 ReportMessage("strict_const", Vector<const char*>::empty()); |
| 1545 *ok = false; | 1534 *ok = false; |
| 1546 return NULL; | 1535 return NULL; |
| 1547 } | 1536 } |
| 1548 mode = Variable::CONST; | 1537 mode = Variable::CONST; |
| 1549 is_const = true; | 1538 is_const = true; |
| 1550 } else { | 1539 } else { |
| 1551 UNREACHABLE(); // by current callers | 1540 UNREACHABLE(); // by current callers |
| 1552 } | 1541 } |
| 1553 | 1542 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1569 int nvars = 0; // the number of variables declared | 1558 int nvars = 0; // the number of variables declared |
| 1570 do { | 1559 do { |
| 1571 if (fni_ != NULL) fni_->Enter(); | 1560 if (fni_ != NULL) fni_->Enter(); |
| 1572 | 1561 |
| 1573 // Parse variable name. | 1562 // Parse variable name. |
| 1574 if (nvars > 0) Consume(Token::COMMA); | 1563 if (nvars > 0) Consume(Token::COMMA); |
| 1575 Handle<String> name = ParseIdentifier(CHECK_OK); | 1564 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1576 if (fni_ != NULL) fni_->PushVariableName(name); | 1565 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1577 | 1566 |
| 1578 // Strict mode variables may not be named eval or arguments | 1567 // Strict mode variables may not be named eval or arguments |
| 1579 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) { | 1568 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { |
| 1580 ReportMessage("strict_var_name", Vector<const char*>::empty()); | 1569 ReportMessage("strict_var_name", Vector<const char*>::empty()); |
| 1581 *ok = false; | 1570 *ok = false; |
| 1582 return NULL; | 1571 return NULL; |
| 1583 } | 1572 } |
| 1584 | 1573 |
| 1585 // Declare variable. | 1574 // Declare variable. |
| 1586 // Note that we *always* must treat the initial value via a separate init | 1575 // Note that we *always* must treat the initial value via a separate init |
| 1587 // assignment for variables and constants because the value must be assigned | 1576 // assignment for variables and constants because the value must be assigned |
| 1588 // when the variable is encountered in the source. But the variable/constant | 1577 // when the variable is encountered in the source. But the variable/constant |
| 1589 // is declared (and set to 'undefined') upon entering the function within | 1578 // is declared (and set to 'undefined') upon entering the function within |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1678 // the number of arguments (1 or 2). | 1667 // the number of arguments (1 or 2). |
| 1679 initialize = | 1668 initialize = |
| 1680 new CallRuntime( | 1669 new CallRuntime( |
| 1681 Factory::InitializeConstGlobal_symbol(), | 1670 Factory::InitializeConstGlobal_symbol(), |
| 1682 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), | 1671 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
| 1683 arguments); | 1672 arguments); |
| 1684 } else { | 1673 } else { |
| 1685 // Add strict mode. | 1674 // Add strict mode. |
| 1686 // We may want to pass singleton to avoid Literal allocations. | 1675 // We may want to pass singleton to avoid Literal allocations. |
| 1687 arguments->Add(NewNumberLiteral( | 1676 arguments->Add(NewNumberLiteral( |
| 1688 temp_scope_->StrictMode() ? kStrictMode : kNonStrictMode)); | 1677 top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode)); |
| 1689 | 1678 |
| 1690 // Be careful not to assign a value to the global variable if | 1679 // Be careful not to assign a value to the global variable if |
| 1691 // we're in a with. The initialization value should not | 1680 // we're in a with. The initialization value should not |
| 1692 // necessarily be stored in the global object in that case, | 1681 // necessarily be stored in the global object in that case, |
| 1693 // which is why we need to generate a separate assignment node. | 1682 // which is why we need to generate a separate assignment node. |
| 1694 if (value != NULL && !inside_with()) { | 1683 if (value != NULL && !inside_with()) { |
| 1695 arguments->Add(value); | 1684 arguments->Add(value); |
| 1696 value = NULL; // zap the value to avoid the unnecessary assignment | 1685 value = NULL; // zap the value to avoid the unnecessary assignment |
| 1697 } | 1686 } |
| 1698 | 1687 |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1951 return result; | 1940 return result; |
| 1952 } | 1941 } |
| 1953 | 1942 |
| 1954 | 1943 |
| 1955 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 1944 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 1956 // WithStatement :: | 1945 // WithStatement :: |
| 1957 // 'with' '(' Expression ')' Statement | 1946 // 'with' '(' Expression ')' Statement |
| 1958 | 1947 |
| 1959 Expect(Token::WITH, CHECK_OK); | 1948 Expect(Token::WITH, CHECK_OK); |
| 1960 | 1949 |
| 1961 if (temp_scope_->StrictMode()) { | 1950 if (top_scope_->is_strict_mode()) { |
| 1962 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | 1951 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
| 1963 *ok = false; | 1952 *ok = false; |
| 1964 return NULL; | 1953 return NULL; |
| 1965 } | 1954 } |
| 1966 | 1955 |
| 1967 Expect(Token::LPAREN, CHECK_OK); | 1956 Expect(Token::LPAREN, CHECK_OK); |
| 1968 Expression* expr = ParseExpression(true, CHECK_OK); | 1957 Expression* expr = ParseExpression(true, CHECK_OK); |
| 1969 Expect(Token::RPAREN, CHECK_OK); | 1958 Expect(Token::RPAREN, CHECK_OK); |
| 1970 | 1959 |
| 1971 return WithHelper(expr, labels, false, CHECK_OK); | 1960 return WithHelper(expr, labels, false, CHECK_OK); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2090 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); | 2079 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); |
| 2091 TargetCollector catch_collector(catch_target_list); | 2080 TargetCollector catch_collector(catch_target_list); |
| 2092 bool has_catch = false; | 2081 bool has_catch = false; |
| 2093 if (tok == Token::CATCH) { | 2082 if (tok == Token::CATCH) { |
| 2094 has_catch = true; | 2083 has_catch = true; |
| 2095 Consume(Token::CATCH); | 2084 Consume(Token::CATCH); |
| 2096 | 2085 |
| 2097 Expect(Token::LPAREN, CHECK_OK); | 2086 Expect(Token::LPAREN, CHECK_OK); |
| 2098 Handle<String> name = ParseIdentifier(CHECK_OK); | 2087 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2099 | 2088 |
| 2100 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) { | 2089 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { |
| 2101 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); | 2090 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); |
| 2102 *ok = false; | 2091 *ok = false; |
| 2103 return NULL; | 2092 return NULL; |
| 2104 } | 2093 } |
| 2105 | 2094 |
| 2106 Expect(Token::RPAREN, CHECK_OK); | 2095 Expect(Token::RPAREN, CHECK_OK); |
| 2107 | 2096 |
| 2108 if (peek() == Token::LBRACE) { | 2097 if (peek() == Token::LBRACE) { |
| 2109 // Allocate a temporary for holding the finally state while | 2098 // Allocate a temporary for holding the finally state while |
| 2110 // executing the finally block. | 2099 // executing the finally block. |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2341 | 2330 |
| 2342 // Signal a reference error if the expression is an invalid left-hand | 2331 // Signal a reference error if the expression is an invalid left-hand |
| 2343 // side expression. We could report this as a syntax error here but | 2332 // side expression. We could report this as a syntax error here but |
| 2344 // for compatibility with JSC we choose to report the error at | 2333 // for compatibility with JSC we choose to report the error at |
| 2345 // runtime. | 2334 // runtime. |
| 2346 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2335 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2347 Handle<String> type = Factory::invalid_lhs_in_assignment_symbol(); | 2336 Handle<String> type = Factory::invalid_lhs_in_assignment_symbol(); |
| 2348 expression = NewThrowReferenceError(type); | 2337 expression = NewThrowReferenceError(type); |
| 2349 } | 2338 } |
| 2350 | 2339 |
| 2351 if (temp_scope_->StrictMode()) { | 2340 if (top_scope_->is_strict_mode()) { |
| 2352 // Assignment to eval or arguments is disallowed in strict mode. | 2341 // Assignment to eval or arguments is disallowed in strict mode. |
| 2353 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); | 2342 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); |
| 2354 } | 2343 } |
| 2355 | 2344 |
| 2356 Token::Value op = Next(); // Get assignment operator. | 2345 Token::Value op = Next(); // Get assignment operator. |
| 2357 int pos = scanner().location().beg_pos; | 2346 int pos = scanner().location().beg_pos; |
| 2358 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2347 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2359 | 2348 |
| 2360 // TODO(1231235): We try to estimate the set of properties set by | 2349 // TODO(1231235): We try to estimate the set of properties set by |
| 2361 // constructors. We define a new property whenever there is an | 2350 // constructors. We define a new property whenever there is an |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2560 return expression; | 2549 return expression; |
| 2561 case Token::SUB: | 2550 case Token::SUB: |
| 2562 return NewNumberLiteral(-value); | 2551 return NewNumberLiteral(-value); |
| 2563 case Token::BIT_NOT: | 2552 case Token::BIT_NOT: |
| 2564 return NewNumberLiteral(~DoubleToInt32(value)); | 2553 return NewNumberLiteral(~DoubleToInt32(value)); |
| 2565 default: break; | 2554 default: break; |
| 2566 } | 2555 } |
| 2567 } | 2556 } |
| 2568 | 2557 |
| 2569 // "delete identifier" is a syntax error in strict mode. | 2558 // "delete identifier" is a syntax error in strict mode. |
| 2570 if (op == Token::DELETE && temp_scope_->StrictMode()) { | 2559 if (op == Token::DELETE && top_scope_->is_strict_mode()) { |
| 2571 VariableProxy* operand = expression->AsVariableProxy(); | 2560 VariableProxy* operand = expression->AsVariableProxy(); |
| 2572 if (operand != NULL && !operand->is_this()) { | 2561 if (operand != NULL && !operand->is_this()) { |
| 2573 ReportMessage("strict_delete", Vector<const char*>::empty()); | 2562 ReportMessage("strict_delete", Vector<const char*>::empty()); |
| 2574 *ok = false; | 2563 *ok = false; |
| 2575 return NULL; | 2564 return NULL; |
| 2576 } | 2565 } |
| 2577 } | 2566 } |
| 2578 | 2567 |
| 2579 return new UnaryOperation(op, expression); | 2568 return new UnaryOperation(op, expression); |
| 2580 | 2569 |
| 2581 } else if (Token::IsCountOp(op)) { | 2570 } else if (Token::IsCountOp(op)) { |
| 2582 op = Next(); | 2571 op = Next(); |
| 2583 Expression* expression = ParseUnaryExpression(CHECK_OK); | 2572 Expression* expression = ParseUnaryExpression(CHECK_OK); |
| 2584 // Signal a reference error if the expression is an invalid | 2573 // Signal a reference error if the expression is an invalid |
| 2585 // left-hand side expression. We could report this as a syntax | 2574 // left-hand side expression. We could report this as a syntax |
| 2586 // error here but for compatibility with JSC we choose to report the | 2575 // error here but for compatibility with JSC we choose to report the |
| 2587 // error at runtime. | 2576 // error at runtime. |
| 2588 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2577 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2589 Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol(); | 2578 Handle<String> type = Factory::invalid_lhs_in_prefix_op_symbol(); |
| 2590 expression = NewThrowReferenceError(type); | 2579 expression = NewThrowReferenceError(type); |
| 2591 } | 2580 } |
| 2592 | 2581 |
| 2593 if (temp_scope_->StrictMode()) { | 2582 if (top_scope_->is_strict_mode()) { |
| 2594 // Prefix expression operand in strict mode may not be eval or arguments. | 2583 // Prefix expression operand in strict mode may not be eval or arguments. |
| 2595 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 2584 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 2596 } | 2585 } |
| 2597 | 2586 |
| 2598 int position = scanner().location().beg_pos; | 2587 int position = scanner().location().beg_pos; |
| 2599 IncrementOperation* increment = new IncrementOperation(op, expression); | 2588 IncrementOperation* increment = new IncrementOperation(op, expression); |
| 2600 return new CountOperation(true /* prefix */, increment, position); | 2589 return new CountOperation(true /* prefix */, increment, position); |
| 2601 | 2590 |
| 2602 } else { | 2591 } else { |
| 2603 return ParsePostfixExpression(ok); | 2592 return ParsePostfixExpression(ok); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2614 Token::IsCountOp(peek())) { | 2603 Token::IsCountOp(peek())) { |
| 2615 // Signal a reference error if the expression is an invalid | 2604 // Signal a reference error if the expression is an invalid |
| 2616 // left-hand side expression. We could report this as a syntax | 2605 // left-hand side expression. We could report this as a syntax |
| 2617 // error here but for compatibility with JSC we choose to report the | 2606 // error here but for compatibility with JSC we choose to report the |
| 2618 // error at runtime. | 2607 // error at runtime. |
| 2619 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2608 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2620 Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol(); | 2609 Handle<String> type = Factory::invalid_lhs_in_postfix_op_symbol(); |
| 2621 expression = NewThrowReferenceError(type); | 2610 expression = NewThrowReferenceError(type); |
| 2622 } | 2611 } |
| 2623 | 2612 |
| 2624 if (temp_scope_->StrictMode()) { | 2613 if (top_scope_->is_strict_mode()) { |
| 2625 // Postfix expression operand in strict mode may not be eval or arguments. | 2614 // Postfix expression operand in strict mode may not be eval or arguments. |
| 2626 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 2615 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 2627 } | 2616 } |
| 2628 | 2617 |
| 2629 Token::Value next = Next(); | 2618 Token::Value next = Next(); |
| 2630 int position = scanner().location().beg_pos; | 2619 int position = scanner().location().beg_pos; |
| 2631 IncrementOperation* increment = new IncrementOperation(next, expression); | 2620 IncrementOperation* increment = new IncrementOperation(next, expression); |
| 2632 expression = new CountOperation(false /* postfix */, increment, position); | 2621 expression = new CountOperation(false /* postfix */, increment, position); |
| 2633 } | 2622 } |
| 2634 return expression; | 2623 return expression; |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2822 case Token::NUMBER: | 2811 case Token::NUMBER: |
| 2823 return ReportMessage("unexpected_token_number", | 2812 return ReportMessage("unexpected_token_number", |
| 2824 Vector<const char*>::empty()); | 2813 Vector<const char*>::empty()); |
| 2825 case Token::STRING: | 2814 case Token::STRING: |
| 2826 return ReportMessage("unexpected_token_string", | 2815 return ReportMessage("unexpected_token_string", |
| 2827 Vector<const char*>::empty()); | 2816 Vector<const char*>::empty()); |
| 2828 case Token::IDENTIFIER: | 2817 case Token::IDENTIFIER: |
| 2829 return ReportMessage("unexpected_token_identifier", | 2818 return ReportMessage("unexpected_token_identifier", |
| 2830 Vector<const char*>::empty()); | 2819 Vector<const char*>::empty()); |
| 2831 case Token::FUTURE_RESERVED_WORD: | 2820 case Token::FUTURE_RESERVED_WORD: |
| 2832 return ReportMessage(temp_scope_->StrictMode() ? | 2821 return ReportMessage(top_scope_->is_strict_mode() ? |
| 2833 "unexpected_strict_reserved" : | 2822 "unexpected_strict_reserved" : |
| 2834 "unexpected_token_identifier", | 2823 "unexpected_token_identifier", |
| 2835 Vector<const char*>::empty()); | 2824 Vector<const char*>::empty()); |
| 2836 default: | 2825 default: |
| 2837 const char* name = Token::String(token); | 2826 const char* name = Token::String(token); |
| 2838 ASSERT(name != NULL); | 2827 ASSERT(name != NULL); |
| 2839 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); | 2828 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); |
| 2840 } | 2829 } |
| 2841 } | 2830 } |
| 2842 | 2831 |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3327 // ObjectLiteral :: | 3316 // ObjectLiteral :: |
| 3328 // '{' ( | 3317 // '{' ( |
| 3329 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 3318 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 3330 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 3319 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 3331 // )*[','] '}' | 3320 // )*[','] '}' |
| 3332 | 3321 |
| 3333 ZoneList<ObjectLiteral::Property*>* properties = | 3322 ZoneList<ObjectLiteral::Property*>* properties = |
| 3334 new ZoneList<ObjectLiteral::Property*>(4); | 3323 new ZoneList<ObjectLiteral::Property*>(4); |
| 3335 int number_of_boilerplate_properties = 0; | 3324 int number_of_boilerplate_properties = 0; |
| 3336 | 3325 |
| 3337 ObjectLiteralPropertyChecker checker(this, temp_scope_->StrictMode()); | 3326 ObjectLiteralPropertyChecker checker(this, top_scope_->is_strict_mode()); |
| 3338 | 3327 |
| 3339 Expect(Token::LBRACE, CHECK_OK); | 3328 Expect(Token::LBRACE, CHECK_OK); |
| 3340 Scanner::Location loc = scanner().location(); | 3329 Scanner::Location loc = scanner().location(); |
| 3341 | 3330 |
| 3342 while (peek() != Token::RBRACE) { | 3331 while (peek() != Token::RBRACE) { |
| 3343 if (fni_ != NULL) fni_->Enter(); | 3332 if (fni_ != NULL) fni_->Enter(); |
| 3344 | 3333 |
| 3345 Literal* key = NULL; | 3334 Literal* key = NULL; |
| 3346 Token::Value next = peek(); | 3335 Token::Value next = peek(); |
| 3347 | 3336 |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3624 expected_property_count = temp_scope.expected_property_count(); | 3613 expected_property_count = temp_scope.expected_property_count(); |
| 3625 only_simple_this_property_assignments = | 3614 only_simple_this_property_assignments = |
| 3626 temp_scope.only_simple_this_property_assignments(); | 3615 temp_scope.only_simple_this_property_assignments(); |
| 3627 this_property_assignments = temp_scope.this_property_assignments(); | 3616 this_property_assignments = temp_scope.this_property_assignments(); |
| 3628 | 3617 |
| 3629 Expect(Token::RBRACE, CHECK_OK); | 3618 Expect(Token::RBRACE, CHECK_OK); |
| 3630 end_pos = scanner().location().end_pos; | 3619 end_pos = scanner().location().end_pos; |
| 3631 } | 3620 } |
| 3632 | 3621 |
| 3633 // Validate strict mode. | 3622 // Validate strict mode. |
| 3634 if (temp_scope_->StrictMode()) { | 3623 if (top_scope_->is_strict_mode()) { |
| 3635 if (IsEvalOrArguments(name)) { | 3624 if (IsEvalOrArguments(name)) { |
| 3636 int position = function_token_position != RelocInfo::kNoPosition | 3625 int position = function_token_position != RelocInfo::kNoPosition |
| 3637 ? function_token_position | 3626 ? function_token_position |
| 3638 : (start_pos > 0 ? start_pos - 1 : start_pos); | 3627 : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 3639 Scanner::Location location = Scanner::Location(position, start_pos); | 3628 Scanner::Location location = Scanner::Location(position, start_pos); |
| 3640 ReportMessageAt(location, | 3629 ReportMessageAt(location, |
| 3641 "strict_function_name", Vector<const char*>::empty()); | 3630 "strict_function_name", Vector<const char*>::empty()); |
| 3642 *ok = false; | 3631 *ok = false; |
| 3643 return NULL; | 3632 return NULL; |
| 3644 } | 3633 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3678 top_scope_, | 3667 top_scope_, |
| 3679 body, | 3668 body, |
| 3680 materialized_literal_count, | 3669 materialized_literal_count, |
| 3681 expected_property_count, | 3670 expected_property_count, |
| 3682 only_simple_this_property_assignments, | 3671 only_simple_this_property_assignments, |
| 3683 this_property_assignments, | 3672 this_property_assignments, |
| 3684 num_parameters, | 3673 num_parameters, |
| 3685 start_pos, | 3674 start_pos, |
| 3686 end_pos, | 3675 end_pos, |
| 3687 function_name->length() > 0, | 3676 function_name->length() > 0, |
| 3688 temp_scope.ContainsLoops(), | 3677 temp_scope.ContainsLoops()); |
| 3689 temp_scope.StrictMode()); | |
| 3690 function_literal->set_function_token_position(function_token_position); | 3678 function_literal->set_function_token_position(function_token_position); |
| 3691 | 3679 |
| 3692 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); | 3680 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); |
| 3693 return function_literal; | 3681 return function_literal; |
| 3694 } | 3682 } |
| 3695 } | 3683 } |
| 3696 | 3684 |
| 3697 | 3685 |
| 3698 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3686 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3699 // CallRuntime :: | 3687 // CallRuntime :: |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3808 | 3796 |
| 3809 Handle<String> Parser::ParseIdentifier(bool* ok) { | 3797 Handle<String> Parser::ParseIdentifier(bool* ok) { |
| 3810 bool is_reserved; | 3798 bool is_reserved; |
| 3811 return ParseIdentifierOrReservedWord(&is_reserved, ok); | 3799 return ParseIdentifierOrReservedWord(&is_reserved, ok); |
| 3812 } | 3800 } |
| 3813 | 3801 |
| 3814 | 3802 |
| 3815 Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved, | 3803 Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved, |
| 3816 bool* ok) { | 3804 bool* ok) { |
| 3817 *is_reserved = false; | 3805 *is_reserved = false; |
| 3818 if (temp_scope_->StrictMode()) { | 3806 if (top_scope_->is_strict_mode()) { |
| 3819 Expect(Token::IDENTIFIER, ok); | 3807 Expect(Token::IDENTIFIER, ok); |
| 3820 } else { | 3808 } else { |
| 3821 if (!Check(Token::IDENTIFIER)) { | 3809 if (!Check(Token::IDENTIFIER)) { |
| 3822 Expect(Token::FUTURE_RESERVED_WORD, ok); | 3810 Expect(Token::FUTURE_RESERVED_WORD, ok); |
| 3823 *is_reserved = true; | 3811 *is_reserved = true; |
| 3824 } | 3812 } |
| 3825 } | 3813 } |
| 3826 if (!*ok) return Handle<String>(); | 3814 if (!*ok) return Handle<String>(); |
| 3827 return GetSymbol(ok); | 3815 return GetSymbol(ok); |
| 3828 } | 3816 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3839 } | 3827 } |
| 3840 return GetSymbol(ok); | 3828 return GetSymbol(ok); |
| 3841 } | 3829 } |
| 3842 | 3830 |
| 3843 | 3831 |
| 3844 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 3832 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
| 3845 // in strict mode. | 3833 // in strict mode. |
| 3846 void Parser::CheckStrictModeLValue(Expression* expression, | 3834 void Parser::CheckStrictModeLValue(Expression* expression, |
| 3847 const char* error, | 3835 const char* error, |
| 3848 bool* ok) { | 3836 bool* ok) { |
| 3849 ASSERT(temp_scope_->StrictMode()); | 3837 ASSERT(top_scope_->is_strict_mode()); |
| 3850 VariableProxy* lhs = expression != NULL | 3838 VariableProxy* lhs = expression != NULL |
| 3851 ? expression->AsVariableProxy() | 3839 ? expression->AsVariableProxy() |
| 3852 : NULL; | 3840 : NULL; |
| 3853 | 3841 |
| 3854 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 3842 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 3855 ReportMessage(error, Vector<const char*>::empty()); | 3843 ReportMessage(error, Vector<const char*>::empty()); |
| 3856 *ok = false; | 3844 *ok = false; |
| 3857 } | 3845 } |
| 3858 } | 3846 } |
| 3859 | 3847 |
| (...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5161 info->is_global(), | 5149 info->is_global(), |
| 5162 info->StrictMode()); | 5150 info->StrictMode()); |
| 5163 } | 5151 } |
| 5164 } | 5152 } |
| 5165 | 5153 |
| 5166 info->SetFunction(result); | 5154 info->SetFunction(result); |
| 5167 return (result != NULL); | 5155 return (result != NULL); |
| 5168 } | 5156 } |
| 5169 | 5157 |
| 5170 } } // namespace v8::internal | 5158 } } // namespace v8::internal |
| OLD | NEW |