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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
656 Scope::Type type = | 646 Scope::Type type = |
657 in_global_context | 647 in_global_context |
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_); |
Kevin Millikin (Chromium)
2011/03/07 11:46:48
Hmmm. TemporaryScope seems like a bad name---it's
Martin Maly
2011/03/07 19:09:40
Putting it on my list of opportunistic changes to
| |
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 |