| 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_( | 313 this_property_assignments_( |
| 322 Isolate::Current()->factory()->empty_fixed_array()), | 314 Isolate::Current()->factory()->empty_fixed_array()), |
| 323 loop_count_(0), | 315 loop_count_(0), |
| 324 variable_(variable), | 316 variable_(variable), |
| 325 parent_(*variable) { | 317 parent_(*variable) { |
| 326 // Inherit the strict mode from the parent scope. | |
| 327 strict_mode_ = (parent_ != NULL) && parent_->strict_mode_; | |
| 328 *variable = this; | 318 *variable = this; |
| 329 } | 319 } |
| 330 | 320 |
| 331 | 321 |
| 332 TemporaryScope::~TemporaryScope() { | 322 TemporaryScope::~TemporaryScope() { |
| 333 *variable_ = parent_; | 323 *variable_ = parent_; |
| 334 } | 324 } |
| 335 | 325 |
| 336 | 326 |
| 337 Handle<String> Parser::LookupSymbol(int symbol_id) { | 327 Handle<String> Parser::LookupSymbol(int symbol_id) { |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 ? Scope::GLOBAL_SCOPE | 654 ? Scope::GLOBAL_SCOPE |
| 665 : Scope::EVAL_SCOPE; | 655 : Scope::EVAL_SCOPE; |
| 666 Handle<String> no_name = isolate()->factory()->empty_symbol(); | 656 Handle<String> no_name = isolate()->factory()->empty_symbol(); |
| 667 | 657 |
| 668 FunctionLiteral* result = NULL; | 658 FunctionLiteral* result = NULL; |
| 669 { Scope* scope = NewScope(top_scope_, type, inside_with()); | 659 { Scope* scope = NewScope(top_scope_, type, inside_with()); |
| 670 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 660 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 671 scope); | 661 scope); |
| 672 TemporaryScope temp_scope(&this->temp_scope_); | 662 TemporaryScope temp_scope(&this->temp_scope_); |
| 673 if (strict_mode == kStrictMode) { | 663 if (strict_mode == kStrictMode) { |
| 674 temp_scope.EnableStrictMode(); | 664 top_scope_->EnableStrictMode(); |
| 675 } | 665 } |
| 676 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); | 666 ZoneList<Statement*>* body = new ZoneList<Statement*>(16); |
| 677 bool ok = true; | 667 bool ok = true; |
| 678 int beg_loc = scanner().location().beg_pos; | 668 int beg_loc = scanner().location().beg_pos; |
| 679 ParseSourceElements(body, Token::EOS, &ok); | 669 ParseSourceElements(body, Token::EOS, &ok); |
| 680 if (ok && temp_scope_->StrictMode()) { | 670 if (ok && top_scope_->is_strict_mode()) { |
| 681 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); | 671 CheckOctalLiteral(beg_loc, scanner().location().end_pos, &ok); |
| 682 } | 672 } |
| 683 if (ok) { | 673 if (ok) { |
| 684 result = new FunctionLiteral( | 674 result = new FunctionLiteral( |
| 685 no_name, | 675 no_name, |
| 686 top_scope_, | 676 top_scope_, |
| 687 body, | 677 body, |
| 688 temp_scope.materialized_literal_count(), | 678 temp_scope.materialized_literal_count(), |
| 689 temp_scope.expected_property_count(), | 679 temp_scope.expected_property_count(), |
| 690 temp_scope.only_simple_this_property_assignments(), | 680 temp_scope.only_simple_this_property_assignments(), |
| 691 temp_scope.this_property_assignments(), | 681 temp_scope.this_property_assignments(), |
| 692 0, | 682 0, |
| 693 0, | 683 0, |
| 694 source->length(), | 684 source->length(), |
| 695 false, | 685 false, |
| 696 temp_scope.ContainsLoops(), | 686 temp_scope.ContainsLoops()); |
| 697 temp_scope.StrictMode()); | |
| 698 } else if (stack_overflow_) { | 687 } else if (stack_overflow_) { |
| 699 isolate()->StackOverflow(); | 688 isolate()->StackOverflow(); |
| 700 } | 689 } |
| 701 } | 690 } |
| 702 | 691 |
| 703 // Make sure the target stack is empty. | 692 // Make sure the target stack is empty. |
| 704 ASSERT(target_stack_ == NULL); | 693 ASSERT(target_stack_ == NULL); |
| 705 | 694 |
| 706 // If there was a syntax error we have to get rid of the AST | 695 // If there was a syntax error we have to get rid of the AST |
| 707 // and it is not safe to do so before the scope has been deleted. | 696 // 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... |
| 752 { | 741 { |
| 753 // Parse the function literal. | 742 // Parse the function literal. |
| 754 Handle<String> no_name = isolate()->factory()->empty_symbol(); | 743 Handle<String> no_name = isolate()->factory()->empty_symbol(); |
| 755 Scope* scope = | 744 Scope* scope = |
| 756 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); | 745 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); |
| 757 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, | 746 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, |
| 758 scope); | 747 scope); |
| 759 TemporaryScope temp_scope(&this->temp_scope_); | 748 TemporaryScope temp_scope(&this->temp_scope_); |
| 760 | 749 |
| 761 if (info->strict_mode()) { | 750 if (info->strict_mode()) { |
| 762 temp_scope.EnableStrictMode(); | 751 top_scope_->EnableStrictMode(); |
| 763 } | 752 } |
| 764 | 753 |
| 765 FunctionLiteralType type = | 754 FunctionLiteralType type = |
| 766 info->is_expression() ? EXPRESSION : DECLARATION; | 755 info->is_expression() ? EXPRESSION : DECLARATION; |
| 767 bool ok = true; | 756 bool ok = true; |
| 768 result = ParseFunctionLiteral(name, | 757 result = ParseFunctionLiteral(name, |
| 769 false, // Strict mode name already checked. | 758 false, // Strict mode name already checked. |
| 770 RelocInfo::kNoPosition, type, &ok); | 759 RelocInfo::kNoPosition, type, &ok); |
| 771 // Make sure the results agree. | 760 // Make sure the results agree. |
| 772 ASSERT(ok == (result != NULL)); | 761 ASSERT(ok == (result != NULL)); |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1141 // A shot at a directive. | 1130 // A shot at a directive. |
| 1142 ExpressionStatement *e_stat; | 1131 ExpressionStatement *e_stat; |
| 1143 Literal *literal; | 1132 Literal *literal; |
| 1144 // Still processing directive prologue? | 1133 // Still processing directive prologue? |
| 1145 if ((e_stat = stat->AsExpressionStatement()) != NULL && | 1134 if ((e_stat = stat->AsExpressionStatement()) != NULL && |
| 1146 (literal = e_stat->expression()->AsLiteral()) != NULL && | 1135 (literal = e_stat->expression()->AsLiteral()) != NULL && |
| 1147 literal->handle()->IsString()) { | 1136 literal->handle()->IsString()) { |
| 1148 Handle<String> directive = Handle<String>::cast(literal->handle()); | 1137 Handle<String> directive = Handle<String>::cast(literal->handle()); |
| 1149 | 1138 |
| 1150 // Check "use strict" directive (ES5 14.1). | 1139 // Check "use strict" directive (ES5 14.1). |
| 1151 if (!temp_scope_->StrictMode() && | 1140 if (!top_scope_->is_strict_mode() && |
| 1152 directive->Equals(isolate()->heap()->use_strict()) && | 1141 directive->Equals(isolate()->heap()->use_strict()) && |
| 1153 token_loc.end_pos - token_loc.beg_pos == | 1142 token_loc.end_pos - token_loc.beg_pos == |
| 1154 isolate()->heap()->use_strict()->length() + 2) { | 1143 isolate()->heap()->use_strict()->length() + 2) { |
| 1155 temp_scope_->EnableStrictMode(); | 1144 top_scope_->EnableStrictMode(); |
| 1156 // "use strict" is the only directive for now. | 1145 // "use strict" is the only directive for now. |
| 1157 directive_prologue = false; | 1146 directive_prologue = false; |
| 1158 } | 1147 } |
| 1159 } else { | 1148 } else { |
| 1160 // End of the directive prologue. | 1149 // End of the directive prologue. |
| 1161 directive_prologue = false; | 1150 directive_prologue = false; |
| 1162 } | 1151 } |
| 1163 } | 1152 } |
| 1164 | 1153 |
| 1165 // We find and mark the initialization blocks on top level code only. | 1154 // 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... |
| 1283 if (statement) { | 1272 if (statement) { |
| 1284 statement->set_statement_pos(statement_pos); | 1273 statement->set_statement_pos(statement_pos); |
| 1285 } | 1274 } |
| 1286 if (result) result->AddStatement(statement); | 1275 if (result) result->AddStatement(statement); |
| 1287 return result; | 1276 return result; |
| 1288 } | 1277 } |
| 1289 | 1278 |
| 1290 case Token::FUNCTION: { | 1279 case Token::FUNCTION: { |
| 1291 // In strict mode, FunctionDeclaration is only allowed in the context | 1280 // In strict mode, FunctionDeclaration is only allowed in the context |
| 1292 // of SourceElements. | 1281 // of SourceElements. |
| 1293 if (temp_scope_->StrictMode()) { | 1282 if (top_scope_->is_strict_mode()) { |
| 1294 ReportMessageAt(scanner().peek_location(), "strict_function", | 1283 ReportMessageAt(scanner().peek_location(), "strict_function", |
| 1295 Vector<const char*>::empty()); | 1284 Vector<const char*>::empty()); |
| 1296 *ok = false; | 1285 *ok = false; |
| 1297 return NULL; | 1286 return NULL; |
| 1298 } | 1287 } |
| 1299 return ParseFunctionDeclaration(ok); | 1288 return ParseFunctionDeclaration(ok); |
| 1300 } | 1289 } |
| 1301 | 1290 |
| 1302 case Token::NATIVE: | 1291 case Token::NATIVE: |
| 1303 return ParseNativeDeclaration(ok); | 1292 return ParseNativeDeclaration(ok); |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 bool* ok) { | 1530 bool* ok) { |
| 1542 // VariableDeclarations :: | 1531 // VariableDeclarations :: |
| 1543 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] | 1532 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] |
| 1544 | 1533 |
| 1545 Variable::Mode mode = Variable::VAR; | 1534 Variable::Mode mode = Variable::VAR; |
| 1546 bool is_const = false; | 1535 bool is_const = false; |
| 1547 if (peek() == Token::VAR) { | 1536 if (peek() == Token::VAR) { |
| 1548 Consume(Token::VAR); | 1537 Consume(Token::VAR); |
| 1549 } else if (peek() == Token::CONST) { | 1538 } else if (peek() == Token::CONST) { |
| 1550 Consume(Token::CONST); | 1539 Consume(Token::CONST); |
| 1551 if (temp_scope_->StrictMode()) { | 1540 if (top_scope_->is_strict_mode()) { |
| 1552 ReportMessage("strict_const", Vector<const char*>::empty()); | 1541 ReportMessage("strict_const", Vector<const char*>::empty()); |
| 1553 *ok = false; | 1542 *ok = false; |
| 1554 return NULL; | 1543 return NULL; |
| 1555 } | 1544 } |
| 1556 mode = Variable::CONST; | 1545 mode = Variable::CONST; |
| 1557 is_const = true; | 1546 is_const = true; |
| 1558 } else { | 1547 } else { |
| 1559 UNREACHABLE(); // by current callers | 1548 UNREACHABLE(); // by current callers |
| 1560 } | 1549 } |
| 1561 | 1550 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1577 int nvars = 0; // the number of variables declared | 1566 int nvars = 0; // the number of variables declared |
| 1578 do { | 1567 do { |
| 1579 if (fni_ != NULL) fni_->Enter(); | 1568 if (fni_ != NULL) fni_->Enter(); |
| 1580 | 1569 |
| 1581 // Parse variable name. | 1570 // Parse variable name. |
| 1582 if (nvars > 0) Consume(Token::COMMA); | 1571 if (nvars > 0) Consume(Token::COMMA); |
| 1583 Handle<String> name = ParseIdentifier(CHECK_OK); | 1572 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1584 if (fni_ != NULL) fni_->PushVariableName(name); | 1573 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1585 | 1574 |
| 1586 // Strict mode variables may not be named eval or arguments | 1575 // Strict mode variables may not be named eval or arguments |
| 1587 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) { | 1576 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { |
| 1588 ReportMessage("strict_var_name", Vector<const char*>::empty()); | 1577 ReportMessage("strict_var_name", Vector<const char*>::empty()); |
| 1589 *ok = false; | 1578 *ok = false; |
| 1590 return NULL; | 1579 return NULL; |
| 1591 } | 1580 } |
| 1592 | 1581 |
| 1593 // Declare variable. | 1582 // Declare variable. |
| 1594 // Note that we *always* must treat the initial value via a separate init | 1583 // Note that we *always* must treat the initial value via a separate init |
| 1595 // assignment for variables and constants because the value must be assigned | 1584 // assignment for variables and constants because the value must be assigned |
| 1596 // when the variable is encountered in the source. But the variable/constant | 1585 // when the variable is encountered in the source. But the variable/constant |
| 1597 // is declared (and set to 'undefined') upon entering the function within | 1586 // is declared (and set to 'undefined') upon entering the function within |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1686 // the number of arguments (1 or 2). | 1675 // the number of arguments (1 or 2). |
| 1687 initialize = | 1676 initialize = |
| 1688 new CallRuntime( | 1677 new CallRuntime( |
| 1689 isolate()->factory()->InitializeConstGlobal_symbol(), | 1678 isolate()->factory()->InitializeConstGlobal_symbol(), |
| 1690 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), | 1679 Runtime::FunctionForId(Runtime::kInitializeConstGlobal), |
| 1691 arguments); | 1680 arguments); |
| 1692 } else { | 1681 } else { |
| 1693 // Add strict mode. | 1682 // Add strict mode. |
| 1694 // We may want to pass singleton to avoid Literal allocations. | 1683 // We may want to pass singleton to avoid Literal allocations. |
| 1695 arguments->Add(NewNumberLiteral( | 1684 arguments->Add(NewNumberLiteral( |
| 1696 temp_scope_->StrictMode() ? kStrictMode : kNonStrictMode)); | 1685 top_scope_->is_strict_mode() ? kStrictMode : kNonStrictMode)); |
| 1697 | 1686 |
| 1698 // Be careful not to assign a value to the global variable if | 1687 // Be careful not to assign a value to the global variable if |
| 1699 // we're in a with. The initialization value should not | 1688 // we're in a with. The initialization value should not |
| 1700 // necessarily be stored in the global object in that case, | 1689 // necessarily be stored in the global object in that case, |
| 1701 // which is why we need to generate a separate assignment node. | 1690 // which is why we need to generate a separate assignment node. |
| 1702 if (value != NULL && !inside_with()) { | 1691 if (value != NULL && !inside_with()) { |
| 1703 arguments->Add(value); | 1692 arguments->Add(value); |
| 1704 value = NULL; // zap the value to avoid the unnecessary assignment | 1693 value = NULL; // zap the value to avoid the unnecessary assignment |
| 1705 } | 1694 } |
| 1706 | 1695 |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1959 return result; | 1948 return result; |
| 1960 } | 1949 } |
| 1961 | 1950 |
| 1962 | 1951 |
| 1963 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { | 1952 Statement* Parser::ParseWithStatement(ZoneStringList* labels, bool* ok) { |
| 1964 // WithStatement :: | 1953 // WithStatement :: |
| 1965 // 'with' '(' Expression ')' Statement | 1954 // 'with' '(' Expression ')' Statement |
| 1966 | 1955 |
| 1967 Expect(Token::WITH, CHECK_OK); | 1956 Expect(Token::WITH, CHECK_OK); |
| 1968 | 1957 |
| 1969 if (temp_scope_->StrictMode()) { | 1958 if (top_scope_->is_strict_mode()) { |
| 1970 ReportMessage("strict_mode_with", Vector<const char*>::empty()); | 1959 ReportMessage("strict_mode_with", Vector<const char*>::empty()); |
| 1971 *ok = false; | 1960 *ok = false; |
| 1972 return NULL; | 1961 return NULL; |
| 1973 } | 1962 } |
| 1974 | 1963 |
| 1975 Expect(Token::LPAREN, CHECK_OK); | 1964 Expect(Token::LPAREN, CHECK_OK); |
| 1976 Expression* expr = ParseExpression(true, CHECK_OK); | 1965 Expression* expr = ParseExpression(true, CHECK_OK); |
| 1977 Expect(Token::RPAREN, CHECK_OK); | 1966 Expect(Token::RPAREN, CHECK_OK); |
| 1978 | 1967 |
| 1979 return WithHelper(expr, labels, false, CHECK_OK); | 1968 return WithHelper(expr, labels, false, CHECK_OK); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2098 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); | 2087 ZoneList<BreakTarget*>* catch_target_list = new ZoneList<BreakTarget*>(0); |
| 2099 TargetCollector catch_collector(catch_target_list); | 2088 TargetCollector catch_collector(catch_target_list); |
| 2100 bool has_catch = false; | 2089 bool has_catch = false; |
| 2101 if (tok == Token::CATCH) { | 2090 if (tok == Token::CATCH) { |
| 2102 has_catch = true; | 2091 has_catch = true; |
| 2103 Consume(Token::CATCH); | 2092 Consume(Token::CATCH); |
| 2104 | 2093 |
| 2105 Expect(Token::LPAREN, CHECK_OK); | 2094 Expect(Token::LPAREN, CHECK_OK); |
| 2106 Handle<String> name = ParseIdentifier(CHECK_OK); | 2095 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 2107 | 2096 |
| 2108 if (temp_scope_->StrictMode() && IsEvalOrArguments(name)) { | 2097 if (top_scope_->is_strict_mode() && IsEvalOrArguments(name)) { |
| 2109 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); | 2098 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); |
| 2110 *ok = false; | 2099 *ok = false; |
| 2111 return NULL; | 2100 return NULL; |
| 2112 } | 2101 } |
| 2113 | 2102 |
| 2114 Expect(Token::RPAREN, CHECK_OK); | 2103 Expect(Token::RPAREN, CHECK_OK); |
| 2115 | 2104 |
| 2116 if (peek() == Token::LBRACE) { | 2105 if (peek() == Token::LBRACE) { |
| 2117 // Allocate a temporary for holding the finally state while | 2106 // Allocate a temporary for holding the finally state while |
| 2118 // executing the finally block. | 2107 // executing the finally block. |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2352 // Signal a reference error if the expression is an invalid left-hand | 2341 // Signal a reference error if the expression is an invalid left-hand |
| 2353 // side expression. We could report this as a syntax error here but | 2342 // side expression. We could report this as a syntax error here but |
| 2354 // for compatibility with JSC we choose to report the error at | 2343 // for compatibility with JSC we choose to report the error at |
| 2355 // runtime. | 2344 // runtime. |
| 2356 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2345 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2357 Handle<String> type = | 2346 Handle<String> type = |
| 2358 isolate()->factory()->invalid_lhs_in_assignment_symbol(); | 2347 isolate()->factory()->invalid_lhs_in_assignment_symbol(); |
| 2359 expression = NewThrowReferenceError(type); | 2348 expression = NewThrowReferenceError(type); |
| 2360 } | 2349 } |
| 2361 | 2350 |
| 2362 if (temp_scope_->StrictMode()) { | 2351 if (top_scope_->is_strict_mode()) { |
| 2363 // Assignment to eval or arguments is disallowed in strict mode. | 2352 // Assignment to eval or arguments is disallowed in strict mode. |
| 2364 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); | 2353 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); |
| 2365 } | 2354 } |
| 2366 | 2355 |
| 2367 Token::Value op = Next(); // Get assignment operator. | 2356 Token::Value op = Next(); // Get assignment operator. |
| 2368 int pos = scanner().location().beg_pos; | 2357 int pos = scanner().location().beg_pos; |
| 2369 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2358 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2370 | 2359 |
| 2371 // TODO(1231235): We try to estimate the set of properties set by | 2360 // TODO(1231235): We try to estimate the set of properties set by |
| 2372 // constructors. We define a new property whenever there is an | 2361 // constructors. We define a new property whenever there is an |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2571 return expression; | 2560 return expression; |
| 2572 case Token::SUB: | 2561 case Token::SUB: |
| 2573 return NewNumberLiteral(-value); | 2562 return NewNumberLiteral(-value); |
| 2574 case Token::BIT_NOT: | 2563 case Token::BIT_NOT: |
| 2575 return NewNumberLiteral(~DoubleToInt32(value)); | 2564 return NewNumberLiteral(~DoubleToInt32(value)); |
| 2576 default: break; | 2565 default: break; |
| 2577 } | 2566 } |
| 2578 } | 2567 } |
| 2579 | 2568 |
| 2580 // "delete identifier" is a syntax error in strict mode. | 2569 // "delete identifier" is a syntax error in strict mode. |
| 2581 if (op == Token::DELETE && temp_scope_->StrictMode()) { | 2570 if (op == Token::DELETE && top_scope_->is_strict_mode()) { |
| 2582 VariableProxy* operand = expression->AsVariableProxy(); | 2571 VariableProxy* operand = expression->AsVariableProxy(); |
| 2583 if (operand != NULL && !operand->is_this()) { | 2572 if (operand != NULL && !operand->is_this()) { |
| 2584 ReportMessage("strict_delete", Vector<const char*>::empty()); | 2573 ReportMessage("strict_delete", Vector<const char*>::empty()); |
| 2585 *ok = false; | 2574 *ok = false; |
| 2586 return NULL; | 2575 return NULL; |
| 2587 } | 2576 } |
| 2588 } | 2577 } |
| 2589 | 2578 |
| 2590 return new UnaryOperation(op, expression); | 2579 return new UnaryOperation(op, expression); |
| 2591 | 2580 |
| 2592 } else if (Token::IsCountOp(op)) { | 2581 } else if (Token::IsCountOp(op)) { |
| 2593 op = Next(); | 2582 op = Next(); |
| 2594 Expression* expression = ParseUnaryExpression(CHECK_OK); | 2583 Expression* expression = ParseUnaryExpression(CHECK_OK); |
| 2595 // Signal a reference error if the expression is an invalid | 2584 // Signal a reference error if the expression is an invalid |
| 2596 // left-hand side expression. We could report this as a syntax | 2585 // left-hand side expression. We could report this as a syntax |
| 2597 // error here but for compatibility with JSC we choose to report the | 2586 // error here but for compatibility with JSC we choose to report the |
| 2598 // error at runtime. | 2587 // error at runtime. |
| 2599 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2588 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2600 Handle<String> type = | 2589 Handle<String> type = |
| 2601 isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); | 2590 isolate()->factory()->invalid_lhs_in_prefix_op_symbol(); |
| 2602 expression = NewThrowReferenceError(type); | 2591 expression = NewThrowReferenceError(type); |
| 2603 } | 2592 } |
| 2604 | 2593 |
| 2605 if (temp_scope_->StrictMode()) { | 2594 if (top_scope_->is_strict_mode()) { |
| 2606 // Prefix expression operand in strict mode may not be eval or arguments. | 2595 // Prefix expression operand in strict mode may not be eval or arguments. |
| 2607 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 2596 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 2608 } | 2597 } |
| 2609 | 2598 |
| 2610 int position = scanner().location().beg_pos; | 2599 int position = scanner().location().beg_pos; |
| 2611 IncrementOperation* increment = new IncrementOperation(op, expression); | 2600 IncrementOperation* increment = new IncrementOperation(op, expression); |
| 2612 return new CountOperation(true /* prefix */, increment, position); | 2601 return new CountOperation(true /* prefix */, increment, position); |
| 2613 | 2602 |
| 2614 } else { | 2603 } else { |
| 2615 return ParsePostfixExpression(ok); | 2604 return ParsePostfixExpression(ok); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2627 // Signal a reference error if the expression is an invalid | 2616 // Signal a reference error if the expression is an invalid |
| 2628 // left-hand side expression. We could report this as a syntax | 2617 // left-hand side expression. We could report this as a syntax |
| 2629 // error here but for compatibility with JSC we choose to report the | 2618 // error here but for compatibility with JSC we choose to report the |
| 2630 // error at runtime. | 2619 // error at runtime. |
| 2631 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2620 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2632 Handle<String> type = | 2621 Handle<String> type = |
| 2633 isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); | 2622 isolate()->factory()->invalid_lhs_in_postfix_op_symbol(); |
| 2634 expression = NewThrowReferenceError(type); | 2623 expression = NewThrowReferenceError(type); |
| 2635 } | 2624 } |
| 2636 | 2625 |
| 2637 if (temp_scope_->StrictMode()) { | 2626 if (top_scope_->is_strict_mode()) { |
| 2638 // Postfix expression operand in strict mode may not be eval or arguments. | 2627 // Postfix expression operand in strict mode may not be eval or arguments. |
| 2639 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 2628 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); |
| 2640 } | 2629 } |
| 2641 | 2630 |
| 2642 Token::Value next = Next(); | 2631 Token::Value next = Next(); |
| 2643 int position = scanner().location().beg_pos; | 2632 int position = scanner().location().beg_pos; |
| 2644 IncrementOperation* increment = new IncrementOperation(next, expression); | 2633 IncrementOperation* increment = new IncrementOperation(next, expression); |
| 2645 expression = new CountOperation(false /* postfix */, increment, position); | 2634 expression = new CountOperation(false /* postfix */, increment, position); |
| 2646 } | 2635 } |
| 2647 return expression; | 2636 return expression; |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2836 case Token::NUMBER: | 2825 case Token::NUMBER: |
| 2837 return ReportMessage("unexpected_token_number", | 2826 return ReportMessage("unexpected_token_number", |
| 2838 Vector<const char*>::empty()); | 2827 Vector<const char*>::empty()); |
| 2839 case Token::STRING: | 2828 case Token::STRING: |
| 2840 return ReportMessage("unexpected_token_string", | 2829 return ReportMessage("unexpected_token_string", |
| 2841 Vector<const char*>::empty()); | 2830 Vector<const char*>::empty()); |
| 2842 case Token::IDENTIFIER: | 2831 case Token::IDENTIFIER: |
| 2843 return ReportMessage("unexpected_token_identifier", | 2832 return ReportMessage("unexpected_token_identifier", |
| 2844 Vector<const char*>::empty()); | 2833 Vector<const char*>::empty()); |
| 2845 case Token::FUTURE_RESERVED_WORD: | 2834 case Token::FUTURE_RESERVED_WORD: |
| 2846 return ReportMessage(temp_scope_->StrictMode() ? | 2835 return ReportMessage(top_scope_->is_strict_mode() ? |
| 2847 "unexpected_strict_reserved" : | 2836 "unexpected_strict_reserved" : |
| 2848 "unexpected_token_identifier", | 2837 "unexpected_token_identifier", |
| 2849 Vector<const char*>::empty()); | 2838 Vector<const char*>::empty()); |
| 2850 default: | 2839 default: |
| 2851 const char* name = Token::String(token); | 2840 const char* name = Token::String(token); |
| 2852 ASSERT(name != NULL); | 2841 ASSERT(name != NULL); |
| 2853 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); | 2842 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); |
| 2854 } | 2843 } |
| 2855 } | 2844 } |
| 2856 | 2845 |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3341 // ObjectLiteral :: | 3330 // ObjectLiteral :: |
| 3342 // '{' ( | 3331 // '{' ( |
| 3343 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 3332 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 3344 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 3333 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 3345 // )*[','] '}' | 3334 // )*[','] '}' |
| 3346 | 3335 |
| 3347 ZoneList<ObjectLiteral::Property*>* properties = | 3336 ZoneList<ObjectLiteral::Property*>* properties = |
| 3348 new ZoneList<ObjectLiteral::Property*>(4); | 3337 new ZoneList<ObjectLiteral::Property*>(4); |
| 3349 int number_of_boilerplate_properties = 0; | 3338 int number_of_boilerplate_properties = 0; |
| 3350 | 3339 |
| 3351 ObjectLiteralPropertyChecker checker(this, temp_scope_->StrictMode()); | 3340 ObjectLiteralPropertyChecker checker(this, top_scope_->is_strict_mode()); |
| 3352 | 3341 |
| 3353 Expect(Token::LBRACE, CHECK_OK); | 3342 Expect(Token::LBRACE, CHECK_OK); |
| 3354 Scanner::Location loc = scanner().location(); | 3343 Scanner::Location loc = scanner().location(); |
| 3355 | 3344 |
| 3356 while (peek() != Token::RBRACE) { | 3345 while (peek() != Token::RBRACE) { |
| 3357 if (fni_ != NULL) fni_->Enter(); | 3346 if (fni_ != NULL) fni_->Enter(); |
| 3358 | 3347 |
| 3359 Literal* key = NULL; | 3348 Literal* key = NULL; |
| 3360 Token::Value next = peek(); | 3349 Token::Value next = peek(); |
| 3361 | 3350 |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3640 expected_property_count = temp_scope.expected_property_count(); | 3629 expected_property_count = temp_scope.expected_property_count(); |
| 3641 only_simple_this_property_assignments = | 3630 only_simple_this_property_assignments = |
| 3642 temp_scope.only_simple_this_property_assignments(); | 3631 temp_scope.only_simple_this_property_assignments(); |
| 3643 this_property_assignments = temp_scope.this_property_assignments(); | 3632 this_property_assignments = temp_scope.this_property_assignments(); |
| 3644 | 3633 |
| 3645 Expect(Token::RBRACE, CHECK_OK); | 3634 Expect(Token::RBRACE, CHECK_OK); |
| 3646 end_pos = scanner().location().end_pos; | 3635 end_pos = scanner().location().end_pos; |
| 3647 } | 3636 } |
| 3648 | 3637 |
| 3649 // Validate strict mode. | 3638 // Validate strict mode. |
| 3650 if (temp_scope_->StrictMode()) { | 3639 if (top_scope_->is_strict_mode()) { |
| 3651 if (IsEvalOrArguments(name)) { | 3640 if (IsEvalOrArguments(name)) { |
| 3652 int position = function_token_position != RelocInfo::kNoPosition | 3641 int position = function_token_position != RelocInfo::kNoPosition |
| 3653 ? function_token_position | 3642 ? function_token_position |
| 3654 : (start_pos > 0 ? start_pos - 1 : start_pos); | 3643 : (start_pos > 0 ? start_pos - 1 : start_pos); |
| 3655 Scanner::Location location = Scanner::Location(position, start_pos); | 3644 Scanner::Location location = Scanner::Location(position, start_pos); |
| 3656 ReportMessageAt(location, | 3645 ReportMessageAt(location, |
| 3657 "strict_function_name", Vector<const char*>::empty()); | 3646 "strict_function_name", Vector<const char*>::empty()); |
| 3658 *ok = false; | 3647 *ok = false; |
| 3659 return NULL; | 3648 return NULL; |
| 3660 } | 3649 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3694 top_scope_, | 3683 top_scope_, |
| 3695 body, | 3684 body, |
| 3696 materialized_literal_count, | 3685 materialized_literal_count, |
| 3697 expected_property_count, | 3686 expected_property_count, |
| 3698 only_simple_this_property_assignments, | 3687 only_simple_this_property_assignments, |
| 3699 this_property_assignments, | 3688 this_property_assignments, |
| 3700 num_parameters, | 3689 num_parameters, |
| 3701 start_pos, | 3690 start_pos, |
| 3702 end_pos, | 3691 end_pos, |
| 3703 function_name->length() > 0, | 3692 function_name->length() > 0, |
| 3704 temp_scope.ContainsLoops(), | 3693 temp_scope.ContainsLoops()); |
| 3705 temp_scope.StrictMode()); | |
| 3706 function_literal->set_function_token_position(function_token_position); | 3694 function_literal->set_function_token_position(function_token_position); |
| 3707 | 3695 |
| 3708 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); | 3696 if (fni_ != NULL && !is_named) fni_->AddFunction(function_literal); |
| 3709 return function_literal; | 3697 return function_literal; |
| 3710 } | 3698 } |
| 3711 } | 3699 } |
| 3712 | 3700 |
| 3713 | 3701 |
| 3714 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3702 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3715 // CallRuntime :: | 3703 // CallRuntime :: |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3824 | 3812 |
| 3825 Handle<String> Parser::ParseIdentifier(bool* ok) { | 3813 Handle<String> Parser::ParseIdentifier(bool* ok) { |
| 3826 bool is_reserved; | 3814 bool is_reserved; |
| 3827 return ParseIdentifierOrReservedWord(&is_reserved, ok); | 3815 return ParseIdentifierOrReservedWord(&is_reserved, ok); |
| 3828 } | 3816 } |
| 3829 | 3817 |
| 3830 | 3818 |
| 3831 Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved, | 3819 Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved, |
| 3832 bool* ok) { | 3820 bool* ok) { |
| 3833 *is_reserved = false; | 3821 *is_reserved = false; |
| 3834 if (temp_scope_->StrictMode()) { | 3822 if (top_scope_->is_strict_mode()) { |
| 3835 Expect(Token::IDENTIFIER, ok); | 3823 Expect(Token::IDENTIFIER, ok); |
| 3836 } else { | 3824 } else { |
| 3837 if (!Check(Token::IDENTIFIER)) { | 3825 if (!Check(Token::IDENTIFIER)) { |
| 3838 Expect(Token::FUTURE_RESERVED_WORD, ok); | 3826 Expect(Token::FUTURE_RESERVED_WORD, ok); |
| 3839 *is_reserved = true; | 3827 *is_reserved = true; |
| 3840 } | 3828 } |
| 3841 } | 3829 } |
| 3842 if (!*ok) return Handle<String>(); | 3830 if (!*ok) return Handle<String>(); |
| 3843 return GetSymbol(ok); | 3831 return GetSymbol(ok); |
| 3844 } | 3832 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3855 } | 3843 } |
| 3856 return GetSymbol(ok); | 3844 return GetSymbol(ok); |
| 3857 } | 3845 } |
| 3858 | 3846 |
| 3859 | 3847 |
| 3860 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 3848 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
| 3861 // in strict mode. | 3849 // in strict mode. |
| 3862 void Parser::CheckStrictModeLValue(Expression* expression, | 3850 void Parser::CheckStrictModeLValue(Expression* expression, |
| 3863 const char* error, | 3851 const char* error, |
| 3864 bool* ok) { | 3852 bool* ok) { |
| 3865 ASSERT(temp_scope_->StrictMode()); | 3853 ASSERT(top_scope_->is_strict_mode()); |
| 3866 VariableProxy* lhs = expression != NULL | 3854 VariableProxy* lhs = expression != NULL |
| 3867 ? expression->AsVariableProxy() | 3855 ? expression->AsVariableProxy() |
| 3868 : NULL; | 3856 : NULL; |
| 3869 | 3857 |
| 3870 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 3858 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 3871 ReportMessage(error, Vector<const char*>::empty()); | 3859 ReportMessage(error, Vector<const char*>::empty()); |
| 3872 *ok = false; | 3860 *ok = false; |
| 3873 } | 3861 } |
| 3874 } | 3862 } |
| 3875 | 3863 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4134 return ReportUnexpectedToken(); | 4122 return ReportUnexpectedToken(); |
| 4135 } | 4123 } |
| 4136 Handle<String> key = GetString(); | 4124 Handle<String> key = GetString(); |
| 4137 if (scanner_.Next() != Token::COLON) { | 4125 if (scanner_.Next() != Token::COLON) { |
| 4138 return ReportUnexpectedToken(); | 4126 return ReportUnexpectedToken(); |
| 4139 } | 4127 } |
| 4140 Handle<Object> value = ParseJsonValue(); | 4128 Handle<Object> value = ParseJsonValue(); |
| 4141 if (value.is_null()) return Handle<Object>::null(); | 4129 if (value.is_null()) return Handle<Object>::null(); |
| 4142 uint32_t index; | 4130 uint32_t index; |
| 4143 if (key->AsArrayIndex(&index)) { | 4131 if (key->AsArrayIndex(&index)) { |
| 4144 SetOwnElement(json_object, index, value); | 4132 SetOwnElement(json_object, index, value, kNonStrictMode); |
| 4145 } else if (key->Equals(isolate()->heap()->Proto_symbol())) { | 4133 } else if (key->Equals(isolate()->heap()->Proto_symbol())) { |
| 4146 // We can't remove the __proto__ accessor since it's hardcoded | 4134 // We can't remove the __proto__ accessor since it's hardcoded |
| 4147 // in several places. Instead go along and add the value as | 4135 // in several places. Instead go along and add the value as |
| 4148 // the prototype of the created object if possible. | 4136 // the prototype of the created object if possible. |
| 4149 SetPrototype(json_object, value); | 4137 SetPrototype(json_object, value); |
| 4150 } else { | 4138 } else { |
| 4151 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE); | 4139 SetLocalPropertyIgnoreAttributes(json_object, key, value, NONE); |
| 4152 } | 4140 } |
| 4153 } while (scanner_.Next() == Token::COMMA); | 4141 } while (scanner_.Next() == Token::COMMA); |
| 4154 if (scanner_.current_token() != Token::RBRACE) { | 4142 if (scanner_.current_token() != Token::RBRACE) { |
| (...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5164 info->is_global(), | 5152 info->is_global(), |
| 5165 info->StrictMode()); | 5153 info->StrictMode()); |
| 5166 } | 5154 } |
| 5167 } | 5155 } |
| 5168 | 5156 |
| 5169 info->SetFunction(result); | 5157 info->SetFunction(result); |
| 5170 return (result != NULL); | 5158 return (result != NULL); |
| 5171 } | 5159 } |
| 5172 | 5160 |
| 5173 } } // namespace v8::internal | 5161 } } // namespace v8::internal |
| OLD | NEW |