| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 info()->is_extended_mode()); | 763 info()->is_extended_mode()); |
| 764 ASSERT(info()->language_mode() == shared_info->language_mode()); | 764 ASSERT(info()->language_mode() == shared_info->language_mode()); |
| 765 scope->SetLanguageMode(shared_info->language_mode()); | 765 scope->SetLanguageMode(shared_info->language_mode()); |
| 766 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 766 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
| 767 ? (shared_info->is_anonymous() | 767 ? (shared_info->is_anonymous() |
| 768 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 768 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 769 : FunctionLiteral::NAMED_EXPRESSION) | 769 : FunctionLiteral::NAMED_EXPRESSION) |
| 770 : FunctionLiteral::DECLARATION; | 770 : FunctionLiteral::DECLARATION; |
| 771 bool ok = true; | 771 bool ok = true; |
| 772 result = ParseFunctionLiteral(name, | 772 result = ParseFunctionLiteral(name, |
| 773 Scanner::Location::invalid(), |
| 773 false, // Strict mode name already checked. | 774 false, // Strict mode name already checked. |
| 774 shared_info->is_generator(), | 775 shared_info->is_generator(), |
| 775 RelocInfo::kNoPosition, | 776 RelocInfo::kNoPosition, |
| 776 function_type, | 777 function_type, |
| 777 &ok); | 778 &ok); |
| 778 // Make sure the results agree. | 779 // Make sure the results agree. |
| 779 ASSERT(ok == (result != NULL)); | 780 ASSERT(ok == (result != NULL)); |
| 780 } | 781 } |
| 781 | 782 |
| 782 // Make sure the target stack is empty. | 783 // Make sure the target stack is empty. |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 } | 976 } |
| 976 } | 977 } |
| 977 } | 978 } |
| 978 | 979 |
| 979 | 980 |
| 980 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { | 981 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
| 981 // ModuleDeclaration: | 982 // ModuleDeclaration: |
| 982 // 'module' Identifier Module | 983 // 'module' Identifier Module |
| 983 | 984 |
| 984 int pos = peek_position(); | 985 int pos = peek_position(); |
| 985 Handle<String> name = ParseIdentifier(CHECK_OK); | 986 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 986 | 987 |
| 987 #ifdef DEBUG | 988 #ifdef DEBUG |
| 988 if (FLAG_print_interface_details) | 989 if (FLAG_print_interface_details) |
| 989 PrintF("# Module %s...\n", name->ToAsciiArray()); | 990 PrintF("# Module %s...\n", name->ToAsciiArray()); |
| 990 #endif | 991 #endif |
| 991 | 992 |
| 992 Module* module = ParseModule(CHECK_OK); | 993 Module* module = ParseModule(CHECK_OK); |
| 993 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 994 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
| 994 Declaration* declaration = | 995 Declaration* declaration = |
| 995 factory()->NewModuleDeclaration(proxy, module, top_scope_, pos); | 996 factory()->NewModuleDeclaration(proxy, module, top_scope_, pos); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 | 1129 |
| 1129 return result; | 1130 return result; |
| 1130 } | 1131 } |
| 1131 | 1132 |
| 1132 | 1133 |
| 1133 Module* Parser::ParseModuleVariable(bool* ok) { | 1134 Module* Parser::ParseModuleVariable(bool* ok) { |
| 1134 // ModulePath: | 1135 // ModulePath: |
| 1135 // Identifier | 1136 // Identifier |
| 1136 | 1137 |
| 1137 int pos = peek_position(); | 1138 int pos = peek_position(); |
| 1138 Handle<String> name = ParseIdentifier(CHECK_OK); | 1139 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1139 #ifdef DEBUG | 1140 #ifdef DEBUG |
| 1140 if (FLAG_print_interface_details) | 1141 if (FLAG_print_interface_details) |
| 1141 PrintF("# Module variable %s ", name->ToAsciiArray()); | 1142 PrintF("# Module variable %s ", name->ToAsciiArray()); |
| 1142 #endif | 1143 #endif |
| 1143 VariableProxy* proxy = top_scope_->NewUnresolved( | 1144 VariableProxy* proxy = top_scope_->NewUnresolved( |
| 1144 factory(), name, Interface::NewModule(zone()), | 1145 factory(), name, Interface::NewModule(zone()), |
| 1145 scanner().location().beg_pos); | 1146 scanner().location().beg_pos); |
| 1146 | 1147 |
| 1147 return factory()->NewModuleVariable(proxy, pos); | 1148 return factory()->NewModuleVariable(proxy, pos); |
| 1148 } | 1149 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1253 // | 1254 // |
| 1254 // TODO(ES6): implement structuring ExportSpecifiers | 1255 // TODO(ES6): implement structuring ExportSpecifiers |
| 1255 | 1256 |
| 1256 Expect(Token::EXPORT, CHECK_OK); | 1257 Expect(Token::EXPORT, CHECK_OK); |
| 1257 | 1258 |
| 1258 Statement* result = NULL; | 1259 Statement* result = NULL; |
| 1259 ZoneStringList names(1, zone()); | 1260 ZoneStringList names(1, zone()); |
| 1260 switch (peek()) { | 1261 switch (peek()) { |
| 1261 case Token::IDENTIFIER: { | 1262 case Token::IDENTIFIER: { |
| 1262 int pos = position(); | 1263 int pos = position(); |
| 1263 Handle<String> name = ParseIdentifier(CHECK_OK); | 1264 Handle<String> name = |
| 1265 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1264 // Handle 'module' as a context-sensitive keyword. | 1266 // Handle 'module' as a context-sensitive keyword. |
| 1265 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { | 1267 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { |
| 1266 names.Add(name, zone()); | 1268 names.Add(name, zone()); |
| 1267 while (peek() == Token::COMMA) { | 1269 while (peek() == Token::COMMA) { |
| 1268 Consume(Token::COMMA); | 1270 Consume(Token::COMMA); |
| 1269 name = ParseIdentifier(CHECK_OK); | 1271 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1270 names.Add(name, zone()); | 1272 names.Add(name, zone()); |
| 1271 } | 1273 } |
| 1272 ExpectSemicolon(CHECK_OK); | 1274 ExpectSemicolon(CHECK_OK); |
| 1273 result = factory()->NewEmptyStatement(pos); | 1275 result = factory()->NewEmptyStatement(pos); |
| 1274 } else { | 1276 } else { |
| 1275 result = ParseModuleDeclaration(&names, CHECK_OK); | 1277 result = ParseModuleDeclaration(&names, CHECK_OK); |
| 1276 } | 1278 } |
| 1277 break; | 1279 break; |
| 1278 } | 1280 } |
| 1279 | 1281 |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1624 } | 1626 } |
| 1625 | 1627 |
| 1626 | 1628 |
| 1627 // Language extension which is only enabled for source files loaded | 1629 // Language extension which is only enabled for source files loaded |
| 1628 // through the API's extension mechanism. A native function | 1630 // through the API's extension mechanism. A native function |
| 1629 // declaration is resolved by looking up the function through a | 1631 // declaration is resolved by looking up the function through a |
| 1630 // callback provided by the extension. | 1632 // callback provided by the extension. |
| 1631 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1633 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
| 1632 int pos = peek_position(); | 1634 int pos = peek_position(); |
| 1633 Expect(Token::FUNCTION, CHECK_OK); | 1635 Expect(Token::FUNCTION, CHECK_OK); |
| 1634 Handle<String> name = ParseIdentifier(CHECK_OK); | 1636 // Allow "eval" or "arguments" for backward compatibility. |
| 1637 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1635 Expect(Token::LPAREN, CHECK_OK); | 1638 Expect(Token::LPAREN, CHECK_OK); |
| 1636 bool done = (peek() == Token::RPAREN); | 1639 bool done = (peek() == Token::RPAREN); |
| 1637 while (!done) { | 1640 while (!done) { |
| 1638 ParseIdentifier(CHECK_OK); | 1641 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1639 done = (peek() == Token::RPAREN); | 1642 done = (peek() == Token::RPAREN); |
| 1640 if (!done) { | 1643 if (!done) { |
| 1641 Expect(Token::COMMA, CHECK_OK); | 1644 Expect(Token::COMMA, CHECK_OK); |
| 1642 } | 1645 } |
| 1643 } | 1646 } |
| 1644 Expect(Token::RPAREN, CHECK_OK); | 1647 Expect(Token::RPAREN, CHECK_OK); |
| 1645 Expect(Token::SEMICOLON, CHECK_OK); | 1648 Expect(Token::SEMICOLON, CHECK_OK); |
| 1646 | 1649 |
| 1647 // Make sure that the function containing the native declaration | 1650 // Make sure that the function containing the native declaration |
| 1648 // isn't lazily compiled. The extension structures are only | 1651 // isn't lazily compiled. The extension structures are only |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1672 // GeneratorDeclaration :: | 1675 // GeneratorDeclaration :: |
| 1673 // 'function' '*' Identifier '(' FormalParameterListopt ')' | 1676 // 'function' '*' Identifier '(' FormalParameterListopt ')' |
| 1674 // '{' FunctionBody '}' | 1677 // '{' FunctionBody '}' |
| 1675 Expect(Token::FUNCTION, CHECK_OK); | 1678 Expect(Token::FUNCTION, CHECK_OK); |
| 1676 int pos = position(); | 1679 int pos = position(); |
| 1677 bool is_generator = allow_generators() && Check(Token::MUL); | 1680 bool is_generator = allow_generators() && Check(Token::MUL); |
| 1678 bool is_strict_reserved = false; | 1681 bool is_strict_reserved = false; |
| 1679 Handle<String> name = ParseIdentifierOrStrictReservedWord( | 1682 Handle<String> name = ParseIdentifierOrStrictReservedWord( |
| 1680 &is_strict_reserved, CHECK_OK); | 1683 &is_strict_reserved, CHECK_OK); |
| 1681 FunctionLiteral* fun = ParseFunctionLiteral(name, | 1684 FunctionLiteral* fun = ParseFunctionLiteral(name, |
| 1685 scanner().location(), |
| 1682 is_strict_reserved, | 1686 is_strict_reserved, |
| 1683 is_generator, | 1687 is_generator, |
| 1684 pos, | 1688 pos, |
| 1685 FunctionLiteral::DECLARATION, | 1689 FunctionLiteral::DECLARATION, |
| 1686 CHECK_OK); | 1690 CHECK_OK); |
| 1687 // Even if we're not at the top-level of the global or a function | 1691 // Even if we're not at the top-level of the global or a function |
| 1688 // scope, we treat it as such and introduce the function with its | 1692 // scope, we treat it as such and introduce the function with its |
| 1689 // initial value upon entering the corresponding scope. | 1693 // initial value upon entering the corresponding scope. |
| 1690 // In extended mode, a function behaves as a lexical binding, except in the | 1694 // In extended mode, a function behaves as a lexical binding, except in the |
| 1691 // global scope. | 1695 // global scope. |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1891 // | 1895 // |
| 1892 // Create new block with one expected declaration. | 1896 // Create new block with one expected declaration. |
| 1893 Block* block = factory()->NewBlock(NULL, 1, true, pos); | 1897 Block* block = factory()->NewBlock(NULL, 1, true, pos); |
| 1894 int nvars = 0; // the number of variables declared | 1898 int nvars = 0; // the number of variables declared |
| 1895 Handle<String> name; | 1899 Handle<String> name; |
| 1896 do { | 1900 do { |
| 1897 if (fni_ != NULL) fni_->Enter(); | 1901 if (fni_ != NULL) fni_->Enter(); |
| 1898 | 1902 |
| 1899 // Parse variable name. | 1903 // Parse variable name. |
| 1900 if (nvars > 0) Consume(Token::COMMA); | 1904 if (nvars > 0) Consume(Token::COMMA); |
| 1901 name = ParseIdentifier(CHECK_OK); | 1905 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1902 if (fni_ != NULL) fni_->PushVariableName(name); | 1906 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1903 | 1907 |
| 1904 // Strict mode variables may not be named eval or arguments | |
| 1905 if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) { | |
| 1906 ReportMessage("strict_var_name", Vector<const char*>::empty()); | |
| 1907 *ok = false; | |
| 1908 return NULL; | |
| 1909 } | |
| 1910 | |
| 1911 // Declare variable. | 1908 // Declare variable. |
| 1912 // Note that we *always* must treat the initial value via a separate init | 1909 // Note that we *always* must treat the initial value via a separate init |
| 1913 // assignment for variables and constants because the value must be assigned | 1910 // assignment for variables and constants because the value must be assigned |
| 1914 // when the variable is encountered in the source. But the variable/constant | 1911 // when the variable is encountered in the source. But the variable/constant |
| 1915 // is declared (and set to 'undefined') upon entering the function within | 1912 // is declared (and set to 'undefined') upon entering the function within |
| 1916 // which the variable or constant is declared. Only function variables have | 1913 // which the variable or constant is declared. Only function variables have |
| 1917 // an initial value in the declaration (because they are initialized upon | 1914 // an initial value in the declaration (because they are initialized upon |
| 1918 // entering the function). | 1915 // entering the function). |
| 1919 // | 1916 // |
| 1920 // If we have a const declaration, in an inner scope, the proxy is always | 1917 // If we have a const declaration, in an inner scope, the proxy is always |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2215 Statement* Parser::ParseContinueStatement(bool* ok) { | 2212 Statement* Parser::ParseContinueStatement(bool* ok) { |
| 2216 // ContinueStatement :: | 2213 // ContinueStatement :: |
| 2217 // 'continue' Identifier? ';' | 2214 // 'continue' Identifier? ';' |
| 2218 | 2215 |
| 2219 int pos = peek_position(); | 2216 int pos = peek_position(); |
| 2220 Expect(Token::CONTINUE, CHECK_OK); | 2217 Expect(Token::CONTINUE, CHECK_OK); |
| 2221 Handle<String> label = Handle<String>::null(); | 2218 Handle<String> label = Handle<String>::null(); |
| 2222 Token::Value tok = peek(); | 2219 Token::Value tok = peek(); |
| 2223 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 2220 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
| 2224 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2221 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2225 label = ParseIdentifier(CHECK_OK); | 2222 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2223 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2226 } | 2224 } |
| 2227 IterationStatement* target = NULL; | 2225 IterationStatement* target = NULL; |
| 2228 target = LookupContinueTarget(label, CHECK_OK); | 2226 target = LookupContinueTarget(label, CHECK_OK); |
| 2229 if (target == NULL) { | 2227 if (target == NULL) { |
| 2230 // Illegal continue statement. | 2228 // Illegal continue statement. |
| 2231 const char* message = "illegal_continue"; | 2229 const char* message = "illegal_continue"; |
| 2232 Vector<Handle<String> > args; | 2230 Vector<Handle<String> > args; |
| 2233 if (!label.is_null()) { | 2231 if (!label.is_null()) { |
| 2234 message = "unknown_label"; | 2232 message = "unknown_label"; |
| 2235 args = Vector<Handle<String> >(&label, 1); | 2233 args = Vector<Handle<String> >(&label, 1); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2246 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2244 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| 2247 // BreakStatement :: | 2245 // BreakStatement :: |
| 2248 // 'break' Identifier? ';' | 2246 // 'break' Identifier? ';' |
| 2249 | 2247 |
| 2250 int pos = peek_position(); | 2248 int pos = peek_position(); |
| 2251 Expect(Token::BREAK, CHECK_OK); | 2249 Expect(Token::BREAK, CHECK_OK); |
| 2252 Handle<String> label; | 2250 Handle<String> label; |
| 2253 Token::Value tok = peek(); | 2251 Token::Value tok = peek(); |
| 2254 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 2252 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
| 2255 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2253 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2256 label = ParseIdentifier(CHECK_OK); | 2254 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2255 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2257 } | 2256 } |
| 2258 // Parse labeled break statements that target themselves into | 2257 // Parse labeled break statements that target themselves into |
| 2259 // empty statements, e.g. 'l1: l2: l3: break l2;' | 2258 // empty statements, e.g. 'l1: l2: l3: break l2;' |
| 2260 if (!label.is_null() && ContainsLabel(labels, label)) { | 2259 if (!label.is_null() && ContainsLabel(labels, label)) { |
| 2261 ExpectSemicolon(CHECK_OK); | 2260 ExpectSemicolon(CHECK_OK); |
| 2262 return factory()->NewEmptyStatement(pos); | 2261 return factory()->NewEmptyStatement(pos); |
| 2263 } | 2262 } |
| 2264 BreakableStatement* target = NULL; | 2263 BreakableStatement* target = NULL; |
| 2265 target = LookupBreakTarget(label, CHECK_OK); | 2264 target = LookupBreakTarget(label, CHECK_OK); |
| 2266 if (target == NULL) { | 2265 if (target == NULL) { |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2476 Scope* catch_scope = NULL; | 2475 Scope* catch_scope = NULL; |
| 2477 Variable* catch_variable = NULL; | 2476 Variable* catch_variable = NULL; |
| 2478 Block* catch_block = NULL; | 2477 Block* catch_block = NULL; |
| 2479 Handle<String> name; | 2478 Handle<String> name; |
| 2480 if (tok == Token::CATCH) { | 2479 if (tok == Token::CATCH) { |
| 2481 Consume(Token::CATCH); | 2480 Consume(Token::CATCH); |
| 2482 | 2481 |
| 2483 Expect(Token::LPAREN, CHECK_OK); | 2482 Expect(Token::LPAREN, CHECK_OK); |
| 2484 catch_scope = NewScope(top_scope_, CATCH_SCOPE); | 2483 catch_scope = NewScope(top_scope_, CATCH_SCOPE); |
| 2485 catch_scope->set_start_position(scanner().location().beg_pos); | 2484 catch_scope->set_start_position(scanner().location().beg_pos); |
| 2486 name = ParseIdentifier(CHECK_OK); | 2485 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2487 | |
| 2488 if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) { | |
| 2489 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); | |
| 2490 *ok = false; | |
| 2491 return NULL; | |
| 2492 } | |
| 2493 | 2486 |
| 2494 Expect(Token::RPAREN, CHECK_OK); | 2487 Expect(Token::RPAREN, CHECK_OK); |
| 2495 | 2488 |
| 2496 if (peek() == Token::LBRACE) { | 2489 Target target(&this->target_stack_, &catch_collector); |
| 2497 Target target(&this->target_stack_, &catch_collector); | 2490 VariableMode mode = is_extended_mode() ? LET : VAR; |
| 2498 VariableMode mode = is_extended_mode() ? LET : VAR; | 2491 catch_variable = |
| 2499 catch_variable = | 2492 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); |
| 2500 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); | |
| 2501 | 2493 |
| 2502 BlockState block_state(this, catch_scope); | 2494 BlockState block_state(this, catch_scope); |
| 2503 catch_block = ParseBlock(NULL, CHECK_OK); | 2495 catch_block = ParseBlock(NULL, CHECK_OK); |
| 2504 } else { | 2496 |
| 2505 Expect(Token::LBRACE, CHECK_OK); | |
| 2506 } | |
| 2507 catch_scope->set_end_position(scanner().location().end_pos); | 2497 catch_scope->set_end_position(scanner().location().end_pos); |
| 2508 tok = peek(); | 2498 tok = peek(); |
| 2509 } | 2499 } |
| 2510 | 2500 |
| 2511 Block* finally_block = NULL; | 2501 Block* finally_block = NULL; |
| 2512 if (tok == Token::FINALLY || catch_block == NULL) { | 2502 ASSERT(tok == Token::FINALLY || catch_block != NULL); |
| 2503 if (tok == Token::FINALLY) { |
| 2513 Consume(Token::FINALLY); | 2504 Consume(Token::FINALLY); |
| 2514 finally_block = ParseBlock(NULL, CHECK_OK); | 2505 finally_block = ParseBlock(NULL, CHECK_OK); |
| 2515 } | 2506 } |
| 2516 | 2507 |
| 2517 // Simplify the AST nodes by converting: | 2508 // Simplify the AST nodes by converting: |
| 2518 // 'try B0 catch B1 finally B2' | 2509 // 'try B0 catch B1 finally B2' |
| 2519 // to: | 2510 // to: |
| 2520 // 'try { try B0 catch B1 } finally B2' | 2511 // 'try { try B0 catch B1 } finally B2' |
| 2521 | 2512 |
| 2522 if (catch_block != NULL && finally_block != NULL) { | 2513 if (catch_block != NULL && finally_block != NULL) { |
| (...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2930 // runtime. | 2921 // runtime. |
| 2931 // TODO(ES5): Should change parsing for spec conformance. | 2922 // TODO(ES5): Should change parsing for spec conformance. |
| 2932 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2923 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2933 Handle<String> message = | 2924 Handle<String> message = |
| 2934 isolate()->factory()->invalid_lhs_in_assignment_string(); | 2925 isolate()->factory()->invalid_lhs_in_assignment_string(); |
| 2935 expression = NewThrowReferenceError(message); | 2926 expression = NewThrowReferenceError(message); |
| 2936 } | 2927 } |
| 2937 | 2928 |
| 2938 if (!top_scope_->is_classic_mode()) { | 2929 if (!top_scope_->is_classic_mode()) { |
| 2939 // Assignment to eval or arguments is disallowed in strict mode. | 2930 // Assignment to eval or arguments is disallowed in strict mode. |
| 2940 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); | 2931 CheckStrictModeLValue(expression, CHECK_OK); |
| 2941 } | 2932 } |
| 2942 MarkAsLValue(expression); | 2933 MarkAsLValue(expression); |
| 2943 | 2934 |
| 2944 Token::Value op = Next(); // Get assignment operator. | 2935 Token::Value op = Next(); // Get assignment operator. |
| 2945 int pos = position(); | 2936 int pos = position(); |
| 2946 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2937 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2947 | 2938 |
| 2948 // TODO(1231235): We try to estimate the set of properties set by | 2939 // TODO(1231235): We try to estimate the set of properties set by |
| 2949 // constructors. We define a new property whenever there is an | 2940 // constructors. We define a new property whenever there is an |
| 2950 // assignment to a property of 'this'. We should probably only add | 2941 // assignment to a property of 'this'. We should probably only add |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3210 // error here but for compatibility with JSC we choose to report the | 3201 // error here but for compatibility with JSC we choose to report the |
| 3211 // error at runtime. | 3202 // error at runtime. |
| 3212 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3203 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3213 Handle<String> message = | 3204 Handle<String> message = |
| 3214 isolate()->factory()->invalid_lhs_in_prefix_op_string(); | 3205 isolate()->factory()->invalid_lhs_in_prefix_op_string(); |
| 3215 expression = NewThrowReferenceError(message); | 3206 expression = NewThrowReferenceError(message); |
| 3216 } | 3207 } |
| 3217 | 3208 |
| 3218 if (!top_scope_->is_classic_mode()) { | 3209 if (!top_scope_->is_classic_mode()) { |
| 3219 // Prefix expression operand in strict mode may not be eval or arguments. | 3210 // Prefix expression operand in strict mode may not be eval or arguments. |
| 3220 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 3211 CheckStrictModeLValue(expression, CHECK_OK); |
| 3221 } | 3212 } |
| 3222 MarkAsLValue(expression); | 3213 MarkAsLValue(expression); |
| 3223 | 3214 |
| 3224 return factory()->NewCountOperation(op, | 3215 return factory()->NewCountOperation(op, |
| 3225 true /* prefix */, | 3216 true /* prefix */, |
| 3226 expression, | 3217 expression, |
| 3227 position()); | 3218 position()); |
| 3228 | 3219 |
| 3229 } else { | 3220 } else { |
| 3230 return ParsePostfixExpression(ok); | 3221 return ParsePostfixExpression(ok); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3244 // error here but for compatibility with JSC we choose to report the | 3235 // error here but for compatibility with JSC we choose to report the |
| 3245 // error at runtime. | 3236 // error at runtime. |
| 3246 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3237 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3247 Handle<String> message = | 3238 Handle<String> message = |
| 3248 isolate()->factory()->invalid_lhs_in_postfix_op_string(); | 3239 isolate()->factory()->invalid_lhs_in_postfix_op_string(); |
| 3249 expression = NewThrowReferenceError(message); | 3240 expression = NewThrowReferenceError(message); |
| 3250 } | 3241 } |
| 3251 | 3242 |
| 3252 if (!top_scope_->is_classic_mode()) { | 3243 if (!top_scope_->is_classic_mode()) { |
| 3253 // Postfix expression operand in strict mode may not be eval or arguments. | 3244 // Postfix expression operand in strict mode may not be eval or arguments. |
| 3254 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 3245 CheckStrictModeLValue(expression, CHECK_OK); |
| 3255 } | 3246 } |
| 3256 MarkAsLValue(expression); | 3247 MarkAsLValue(expression); |
| 3257 | 3248 |
| 3258 Token::Value next = Next(); | 3249 Token::Value next = Next(); |
| 3259 expression = | 3250 expression = |
| 3260 factory()->NewCountOperation(next, | 3251 factory()->NewCountOperation(next, |
| 3261 false /* postfix */, | 3252 false /* postfix */, |
| 3262 expression, | 3253 expression, |
| 3263 position()); | 3254 position()); |
| 3264 } | 3255 } |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3388 | 3379 |
| 3389 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, | 3380 Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
| 3390 bool* ok) { | 3381 bool* ok) { |
| 3391 // MemberExpression :: | 3382 // MemberExpression :: |
| 3392 // (PrimaryExpression | FunctionLiteral) | 3383 // (PrimaryExpression | FunctionLiteral) |
| 3393 // ('[' Expression ']' | '.' Identifier | Arguments)* | 3384 // ('[' Expression ']' | '.' Identifier | Arguments)* |
| 3394 | 3385 |
| 3395 // Parse the initial primary or function expression. | 3386 // Parse the initial primary or function expression. |
| 3396 Expression* result = NULL; | 3387 Expression* result = NULL; |
| 3397 if (peek() == Token::FUNCTION) { | 3388 if (peek() == Token::FUNCTION) { |
| 3398 Expect(Token::FUNCTION, CHECK_OK); | 3389 Consume(Token::FUNCTION); |
| 3399 int function_token_position = position(); | 3390 int function_token_position = position(); |
| 3400 bool is_generator = allow_generators() && Check(Token::MUL); | 3391 bool is_generator = allow_generators() && Check(Token::MUL); |
| 3401 Handle<String> name; | 3392 Handle<String> name; |
| 3402 bool is_strict_reserved_name = false; | 3393 bool is_strict_reserved_name = false; |
| 3394 Scanner::Location function_name_location = Scanner::Location::invalid(); |
| 3403 if (peek_any_identifier()) { | 3395 if (peek_any_identifier()) { |
| 3404 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | 3396 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, |
| 3405 CHECK_OK); | 3397 CHECK_OK); |
| 3398 function_name_location = scanner().location(); |
| 3406 } | 3399 } |
| 3407 FunctionLiteral::FunctionType function_type = name.is_null() | 3400 FunctionLiteral::FunctionType function_type = name.is_null() |
| 3408 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 3401 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
| 3409 : FunctionLiteral::NAMED_EXPRESSION; | 3402 : FunctionLiteral::NAMED_EXPRESSION; |
| 3410 result = ParseFunctionLiteral(name, | 3403 result = ParseFunctionLiteral(name, |
| 3404 function_name_location, |
| 3411 is_strict_reserved_name, | 3405 is_strict_reserved_name, |
| 3412 is_generator, | 3406 is_generator, |
| 3413 function_token_position, | 3407 function_token_position, |
| 3414 function_type, | 3408 function_type, |
| 3415 CHECK_OK); | 3409 CHECK_OK); |
| 3416 } else { | 3410 } else { |
| 3417 result = ParsePrimaryExpression(CHECK_OK); | 3411 result = ParsePrimaryExpression(CHECK_OK); |
| 3418 } | 3412 } |
| 3419 | 3413 |
| 3420 while (true) { | 3414 while (true) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3466 // DebuggerStatement :: | 3460 // DebuggerStatement :: |
| 3467 // 'debugger' ';' | 3461 // 'debugger' ';' |
| 3468 | 3462 |
| 3469 int pos = peek_position(); | 3463 int pos = peek_position(); |
| 3470 Expect(Token::DEBUGGER, CHECK_OK); | 3464 Expect(Token::DEBUGGER, CHECK_OK); |
| 3471 ExpectSemicolon(CHECK_OK); | 3465 ExpectSemicolon(CHECK_OK); |
| 3472 return factory()->NewDebuggerStatement(pos); | 3466 return factory()->NewDebuggerStatement(pos); |
| 3473 } | 3467 } |
| 3474 | 3468 |
| 3475 | 3469 |
| 3476 void Parser::ReportUnexpectedToken(Token::Value token) { | |
| 3477 // We don't report stack overflows here, to avoid increasing the | |
| 3478 // stack depth even further. Instead we report it after parsing is | |
| 3479 // over, in ParseProgram/ParseJson. | |
| 3480 if (token == Token::ILLEGAL && stack_overflow()) return; | |
| 3481 // Four of the tokens are treated specially | |
| 3482 switch (token) { | |
| 3483 case Token::EOS: | |
| 3484 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); | |
| 3485 case Token::NUMBER: | |
| 3486 return ReportMessage("unexpected_token_number", | |
| 3487 Vector<const char*>::empty()); | |
| 3488 case Token::STRING: | |
| 3489 return ReportMessage("unexpected_token_string", | |
| 3490 Vector<const char*>::empty()); | |
| 3491 case Token::IDENTIFIER: | |
| 3492 return ReportMessage("unexpected_token_identifier", | |
| 3493 Vector<const char*>::empty()); | |
| 3494 case Token::FUTURE_RESERVED_WORD: | |
| 3495 return ReportMessage("unexpected_reserved", | |
| 3496 Vector<const char*>::empty()); | |
| 3497 case Token::YIELD: | |
| 3498 case Token::FUTURE_STRICT_RESERVED_WORD: | |
| 3499 return ReportMessage(top_scope_->is_classic_mode() ? | |
| 3500 "unexpected_token_identifier" : | |
| 3501 "unexpected_strict_reserved", | |
| 3502 Vector<const char*>::empty()); | |
| 3503 default: | |
| 3504 const char* name = Token::String(token); | |
| 3505 ASSERT(name != NULL); | |
| 3506 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); | |
| 3507 } | |
| 3508 } | |
| 3509 | |
| 3510 | |
| 3511 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { | 3470 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { |
| 3512 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); | 3471 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); |
| 3513 const char* element[1] = { name_string.get() }; | 3472 const char* element[1] = { name_string.get() }; |
| 3514 ReportMessage("invalid_preparser_data", | 3473 ReportMessage("invalid_preparser_data", |
| 3515 Vector<const char*>(element, 1)); | 3474 Vector<const char*>(element, 1)); |
| 3516 *ok = false; | 3475 *ok = false; |
| 3517 } | 3476 } |
| 3518 | 3477 |
| 3519 | 3478 |
| 3520 Expression* Parser::ParsePrimaryExpression(bool* ok) { | 3479 Expression* Parser::ParsePrimaryExpression(bool* ok) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3551 break; | 3510 break; |
| 3552 | 3511 |
| 3553 case Token::FALSE_LITERAL: | 3512 case Token::FALSE_LITERAL: |
| 3554 Consume(Token::FALSE_LITERAL); | 3513 Consume(Token::FALSE_LITERAL); |
| 3555 result = factory()->NewLiteral(isolate()->factory()->false_value(), pos); | 3514 result = factory()->NewLiteral(isolate()->factory()->false_value(), pos); |
| 3556 break; | 3515 break; |
| 3557 | 3516 |
| 3558 case Token::IDENTIFIER: | 3517 case Token::IDENTIFIER: |
| 3559 case Token::YIELD: | 3518 case Token::YIELD: |
| 3560 case Token::FUTURE_STRICT_RESERVED_WORD: { | 3519 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 3561 Handle<String> name = ParseIdentifier(CHECK_OK); | 3520 // Using eval or arguments in this context is OK even in strict mode. |
| 3521 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 3562 if (fni_ != NULL) fni_->PushVariableName(name); | 3522 if (fni_ != NULL) fni_->PushVariableName(name); |
| 3563 // The name may refer to a module instance object, so its type is unknown. | 3523 // The name may refer to a module instance object, so its type is unknown. |
| 3564 #ifdef DEBUG | 3524 #ifdef DEBUG |
| 3565 if (FLAG_print_interface_details) | 3525 if (FLAG_print_interface_details) |
| 3566 PrintF("# Variable %s ", name->ToAsciiArray()); | 3526 PrintF("# Variable %s ", name->ToAsciiArray()); |
| 3567 #endif | 3527 #endif |
| 3568 Interface* interface = Interface::NewUnknown(zone()); | 3528 Interface* interface = Interface::NewUnknown(zone()); |
| 3569 result = top_scope_->NewUnresolved(factory(), name, interface, pos); | 3529 result = top_scope_->NewUnresolved(factory(), name, interface, pos); |
| 3570 break; | 3530 break; |
| 3571 } | 3531 } |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3757 return NULL; | 3717 return NULL; |
| 3758 } | 3718 } |
| 3759 // Validate the property. | 3719 // Validate the property. |
| 3760 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; | 3720 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty; |
| 3761 checker.CheckProperty(next, type, CHECK_OK); | 3721 checker.CheckProperty(next, type, CHECK_OK); |
| 3762 Handle<String> name = is_keyword | 3722 Handle<String> name = is_keyword |
| 3763 ? isolate_->factory()->InternalizeUtf8String(Token::String(next)) | 3723 ? isolate_->factory()->InternalizeUtf8String(Token::String(next)) |
| 3764 : GetSymbol(); | 3724 : GetSymbol(); |
| 3765 FunctionLiteral* value = | 3725 FunctionLiteral* value = |
| 3766 ParseFunctionLiteral(name, | 3726 ParseFunctionLiteral(name, |
| 3727 scanner().location(), |
| 3767 false, // reserved words are allowed here | 3728 false, // reserved words are allowed here |
| 3768 false, // not a generator | 3729 false, // not a generator |
| 3769 RelocInfo::kNoPosition, | 3730 RelocInfo::kNoPosition, |
| 3770 FunctionLiteral::ANONYMOUS_EXPRESSION, | 3731 FunctionLiteral::ANONYMOUS_EXPRESSION, |
| 3771 CHECK_OK); | 3732 CHECK_OK); |
| 3772 // Allow any number of parameters for compatibilty with JSC. | 3733 // Allow any number of parameters for compatibilty with JSC. |
| 3773 // Specification only allows zero parameters for get and one for set. | 3734 // Specification only allows zero parameters for get and one for set. |
| 3774 ObjectLiteral::Property* property = | 3735 ObjectLiteral::Property* property = |
| 3775 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); | 3736 factory()->NewObjectLiteralProperty(is_getter, value, next_pos); |
| 3776 if (ObjectLiteral::IsBoilerplateProperty(property)) { | 3737 if (ObjectLiteral::IsBoilerplateProperty(property)) { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4003 int properties_; | 3964 int properties_; |
| 4004 LanguageMode mode_; | 3965 LanguageMode mode_; |
| 4005 // For error messages. | 3966 // For error messages. |
| 4006 const char* message_; | 3967 const char* message_; |
| 4007 const char* argument_opt_; | 3968 const char* argument_opt_; |
| 4008 }; | 3969 }; |
| 4009 | 3970 |
| 4010 | 3971 |
| 4011 FunctionLiteral* Parser::ParseFunctionLiteral( | 3972 FunctionLiteral* Parser::ParseFunctionLiteral( |
| 4012 Handle<String> function_name, | 3973 Handle<String> function_name, |
| 3974 Scanner::Location function_name_location, |
| 4013 bool name_is_strict_reserved, | 3975 bool name_is_strict_reserved, |
| 4014 bool is_generator, | 3976 bool is_generator, |
| 4015 int function_token_pos, | 3977 int function_token_pos, |
| 4016 FunctionLiteral::FunctionType function_type, | 3978 FunctionLiteral::FunctionType function_type, |
| 4017 bool* ok) { | 3979 bool* ok) { |
| 4018 // Function :: | 3980 // Function :: |
| 4019 // '(' FormalParameterList? ')' '{' FunctionBody '}' | 3981 // '(' FormalParameterList? ')' '{' FunctionBody '}' |
| 4020 | 3982 |
| 4021 int pos = function_token_pos == RelocInfo::kNoPosition | 3983 int pos = function_token_pos == RelocInfo::kNoPosition |
| 4022 ? peek_position() : function_token_pos; | 3984 ? peek_position() : function_token_pos; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4097 // FunctionState indicates that this function is a generator. | 4059 // FunctionState indicates that this function is a generator. |
| 4098 Variable* temp = top_scope_->DeclarationScope()->NewTemporary( | 4060 Variable* temp = top_scope_->DeclarationScope()->NewTemporary( |
| 4099 isolate()->factory()->dot_generator_object_string()); | 4061 isolate()->factory()->dot_generator_object_string()); |
| 4100 function_state.set_generator_object_variable(temp); | 4062 function_state.set_generator_object_variable(temp); |
| 4101 } | 4063 } |
| 4102 | 4064 |
| 4103 // FormalParameterList :: | 4065 // FormalParameterList :: |
| 4104 // '(' (Identifier)*[','] ')' | 4066 // '(' (Identifier)*[','] ')' |
| 4105 Expect(Token::LPAREN, CHECK_OK); | 4067 Expect(Token::LPAREN, CHECK_OK); |
| 4106 scope->set_start_position(scanner().location().beg_pos); | 4068 scope->set_start_position(scanner().location().beg_pos); |
| 4107 Scanner::Location name_loc = Scanner::Location::invalid(); | 4069 |
| 4108 Scanner::Location dupe_loc = Scanner::Location::invalid(); | 4070 // We don't yet know if the function will be strict, so we cannot yet |
| 4071 // produce errors for parameter names or duplicates. However, we remember |
| 4072 // the locations of these errors if they occur and produce the errors later. |
| 4073 Scanner::Location eval_args_error_log = Scanner::Location::invalid(); |
| 4074 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); |
| 4109 Scanner::Location reserved_loc = Scanner::Location::invalid(); | 4075 Scanner::Location reserved_loc = Scanner::Location::invalid(); |
| 4110 | 4076 |
| 4111 bool done = (peek() == Token::RPAREN); | 4077 bool done = (peek() == Token::RPAREN); |
| 4112 while (!done) { | 4078 while (!done) { |
| 4113 bool is_strict_reserved = false; | 4079 bool is_strict_reserved = false; |
| 4114 Handle<String> param_name = | 4080 Handle<String> param_name = |
| 4115 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | 4081 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); |
| 4116 | 4082 |
| 4117 // Store locations for possible future error reports. | 4083 // Store locations for possible future error reports. |
| 4118 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) { | 4084 if (!eval_args_error_log.IsValid() && IsEvalOrArguments(param_name)) { |
| 4119 name_loc = scanner().location(); | 4085 eval_args_error_log = scanner().location(); |
| 4120 } | |
| 4121 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { | |
| 4122 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; | |
| 4123 dupe_loc = scanner().location(); | |
| 4124 } | 4086 } |
| 4125 if (!reserved_loc.IsValid() && is_strict_reserved) { | 4087 if (!reserved_loc.IsValid() && is_strict_reserved) { |
| 4126 reserved_loc = scanner().location(); | 4088 reserved_loc = scanner().location(); |
| 4127 } | 4089 } |
| 4090 if (!dupe_error_loc.IsValid() && top_scope_->IsDeclared(param_name)) { |
| 4091 duplicate_parameters = FunctionLiteral::kHasDuplicateParameters; |
| 4092 dupe_error_loc = scanner().location(); |
| 4093 } |
| 4128 | 4094 |
| 4129 top_scope_->DeclareParameter(param_name, VAR); | 4095 top_scope_->DeclareParameter(param_name, VAR); |
| 4130 num_parameters++; | 4096 num_parameters++; |
| 4131 if (num_parameters > Code::kMaxArguments) { | 4097 if (num_parameters > Code::kMaxArguments) { |
| 4132 ReportMessageAt(scanner().location(), "too_many_parameters", | 4098 ReportMessageAt(scanner().location(), "too_many_parameters", |
| 4133 Vector<const char*>::empty()); | 4099 Vector<const char*>::empty()); |
| 4134 *ok = false; | 4100 *ok = false; |
| 4135 return NULL; | 4101 return NULL; |
| 4136 } | 4102 } |
| 4137 done = (peek() == Token::RPAREN); | 4103 done = (peek() == Token::RPAREN); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4285 } | 4251 } |
| 4286 | 4252 |
| 4287 materialized_literal_count = function_state.materialized_literal_count(); | 4253 materialized_literal_count = function_state.materialized_literal_count(); |
| 4288 expected_property_count = function_state.expected_property_count(); | 4254 expected_property_count = function_state.expected_property_count(); |
| 4289 handler_count = function_state.handler_count(); | 4255 handler_count = function_state.handler_count(); |
| 4290 | 4256 |
| 4291 Expect(Token::RBRACE, CHECK_OK); | 4257 Expect(Token::RBRACE, CHECK_OK); |
| 4292 scope->set_end_position(scanner().location().end_pos); | 4258 scope->set_end_position(scanner().location().end_pos); |
| 4293 } | 4259 } |
| 4294 | 4260 |
| 4295 // Validate strict mode. | 4261 // Validate strict mode. We can do this only after parsing the function, |
| 4262 // since the function can declare itself strict. |
| 4296 if (!top_scope_->is_classic_mode()) { | 4263 if (!top_scope_->is_classic_mode()) { |
| 4297 if (IsEvalOrArguments(function_name)) { | 4264 if (IsEvalOrArguments(function_name)) { |
| 4298 int start_pos = scope->start_position(); | 4265 ReportMessageAt(function_name_location, |
| 4299 int position = function_token_pos != RelocInfo::kNoPosition | 4266 "strict_eval_arguments", |
| 4300 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); | |
| 4301 Scanner::Location location = Scanner::Location(position, start_pos); | |
| 4302 ReportMessageAt(location, | |
| 4303 "strict_function_name", Vector<const char*>::empty()); | |
| 4304 *ok = false; | |
| 4305 return NULL; | |
| 4306 } | |
| 4307 if (name_loc.IsValid()) { | |
| 4308 ReportMessageAt(name_loc, "strict_param_name", | |
| 4309 Vector<const char*>::empty()); | |
| 4310 *ok = false; | |
| 4311 return NULL; | |
| 4312 } | |
| 4313 if (dupe_loc.IsValid()) { | |
| 4314 ReportMessageAt(dupe_loc, "strict_param_dupe", | |
| 4315 Vector<const char*>::empty()); | 4267 Vector<const char*>::empty()); |
| 4316 *ok = false; | 4268 *ok = false; |
| 4317 return NULL; | 4269 return NULL; |
| 4318 } | 4270 } |
| 4319 if (name_is_strict_reserved) { | 4271 if (name_is_strict_reserved) { |
| 4320 int start_pos = scope->start_position(); | 4272 ReportMessageAt(function_name_location, "unexpected_strict_reserved", |
| 4321 int position = function_token_pos != RelocInfo::kNoPosition | 4273 Vector<const char*>::empty()); |
| 4322 ? function_token_pos : (start_pos > 0 ? start_pos - 1 : start_pos); | 4274 *ok = false; |
| 4323 Scanner::Location location = Scanner::Location(position, start_pos); | 4275 return NULL; |
| 4324 ReportMessageAt(location, "strict_reserved_word", | 4276 } |
| 4277 if (eval_args_error_log.IsValid()) { |
| 4278 ReportMessageAt(eval_args_error_log, "strict_eval_arguments", |
| 4279 Vector<const char*>::empty()); |
| 4280 *ok = false; |
| 4281 return NULL; |
| 4282 } |
| 4283 if (dupe_error_loc.IsValid()) { |
| 4284 ReportMessageAt(dupe_error_loc, "strict_param_dupe", |
| 4325 Vector<const char*>::empty()); | 4285 Vector<const char*>::empty()); |
| 4326 *ok = false; | 4286 *ok = false; |
| 4327 return NULL; | 4287 return NULL; |
| 4328 } | 4288 } |
| 4329 if (reserved_loc.IsValid()) { | 4289 if (reserved_loc.IsValid()) { |
| 4330 ReportMessageAt(reserved_loc, "strict_reserved_word", | 4290 ReportMessageAt(reserved_loc, "unexpected_strict_reserved", |
| 4331 Vector<const char*>::empty()); | 4291 Vector<const char*>::empty()); |
| 4332 *ok = false; | 4292 *ok = false; |
| 4333 return NULL; | 4293 return NULL; |
| 4334 } | 4294 } |
| 4335 CheckOctalLiteral(scope->start_position(), | 4295 CheckOctalLiteral(scope->start_position(), |
| 4336 scope->end_position(), | 4296 scope->end_position(), |
| 4337 CHECK_OK); | 4297 CHECK_OK); |
| 4338 } | 4298 } |
| 4339 ast_properties = *factory()->visitor()->ast_properties(); | 4299 ast_properties = *factory()->visitor()->ast_properties(); |
| 4340 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); | 4300 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4391 return result; | 4351 return result; |
| 4392 } | 4352 } |
| 4393 | 4353 |
| 4394 | 4354 |
| 4395 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4355 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 4396 // CallRuntime :: | 4356 // CallRuntime :: |
| 4397 // '%' Identifier Arguments | 4357 // '%' Identifier Arguments |
| 4398 | 4358 |
| 4399 int pos = peek_position(); | 4359 int pos = peek_position(); |
| 4400 Expect(Token::MOD, CHECK_OK); | 4360 Expect(Token::MOD, CHECK_OK); |
| 4401 Handle<String> name = ParseIdentifier(CHECK_OK); | 4361 // Allow "eval" or "arguments" for backward compatibility. |
| 4362 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 4402 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 4363 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 4403 | 4364 |
| 4404 if (extension_ != NULL) { | 4365 if (extension_ != NULL) { |
| 4405 // The extension structures are only accessible while parsing the | 4366 // The extension structures are only accessible while parsing the |
| 4406 // very first time not when reparsing because of lazy compilation. | 4367 // very first time not when reparsing because of lazy compilation. |
| 4407 top_scope_->DeclarationScope()->ForceEagerCompilation(); | 4368 top_scope_->DeclarationScope()->ForceEagerCompilation(); |
| 4408 } | 4369 } |
| 4409 | 4370 |
| 4410 const Runtime::Function* function = Runtime::FunctionForName(name); | 4371 const Runtime::Function* function = Runtime::FunctionForName(name); |
| 4411 | 4372 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4485 void ParserBase::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { | 4446 void ParserBase::ExpectContextualKeyword(Vector<const char> keyword, bool* ok) { |
| 4486 Expect(Token::IDENTIFIER, ok); | 4447 Expect(Token::IDENTIFIER, ok); |
| 4487 if (!*ok) return; | 4448 if (!*ok) return; |
| 4488 if (!scanner()->is_literal_contextual_keyword(keyword)) { | 4449 if (!scanner()->is_literal_contextual_keyword(keyword)) { |
| 4489 ReportUnexpectedToken(scanner()->current_token()); | 4450 ReportUnexpectedToken(scanner()->current_token()); |
| 4490 *ok = false; | 4451 *ok = false; |
| 4491 } | 4452 } |
| 4492 } | 4453 } |
| 4493 | 4454 |
| 4494 | 4455 |
| 4456 void ParserBase::ReportUnexpectedToken(Token::Value token) { |
| 4457 // We don't report stack overflows here, to avoid increasing the |
| 4458 // stack depth even further. Instead we report it after parsing is |
| 4459 // over, in ParseProgram. |
| 4460 if (token == Token::ILLEGAL && stack_overflow()) { |
| 4461 return; |
| 4462 } |
| 4463 Scanner::Location source_location = scanner()->location(); |
| 4464 |
| 4465 // Four of the tokens are treated specially |
| 4466 switch (token) { |
| 4467 case Token::EOS: |
| 4468 return ReportMessageAt(source_location, "unexpected_eos"); |
| 4469 case Token::NUMBER: |
| 4470 return ReportMessageAt(source_location, "unexpected_token_number"); |
| 4471 case Token::STRING: |
| 4472 return ReportMessageAt(source_location, "unexpected_token_string"); |
| 4473 case Token::IDENTIFIER: |
| 4474 return ReportMessageAt(source_location, |
| 4475 "unexpected_token_identifier"); |
| 4476 case Token::FUTURE_RESERVED_WORD: |
| 4477 return ReportMessageAt(source_location, "unexpected_reserved"); |
| 4478 case Token::YIELD: |
| 4479 case Token::FUTURE_STRICT_RESERVED_WORD: |
| 4480 return ReportMessageAt(source_location, |
| 4481 is_classic_mode() ? "unexpected_token_identifier" |
| 4482 : "unexpected_strict_reserved"); |
| 4483 default: |
| 4484 const char* name = Token::String(token); |
| 4485 ASSERT(name != NULL); |
| 4486 ReportMessageAt( |
| 4487 source_location, "unexpected_token", Vector<const char*>(&name, 1)); |
| 4488 } |
| 4489 } |
| 4490 |
| 4491 |
| 4495 Literal* Parser::GetLiteralUndefined(int position) { | 4492 Literal* Parser::GetLiteralUndefined(int position) { |
| 4496 return factory()->NewLiteral( | 4493 return factory()->NewLiteral( |
| 4497 isolate()->factory()->undefined_value(), position); | 4494 isolate()->factory()->undefined_value(), position); |
| 4498 } | 4495 } |
| 4499 | 4496 |
| 4500 | 4497 |
| 4501 Literal* Parser::GetLiteralTheHole(int position) { | 4498 Literal* Parser::GetLiteralTheHole(int position) { |
| 4502 return factory()->NewLiteral( | 4499 return factory()->NewLiteral( |
| 4503 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); | 4500 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); |
| 4504 } | 4501 } |
| 4505 | 4502 |
| 4506 | 4503 |
| 4507 // Parses an identifier that is valid for the current scope, in particular it | 4504 // Parses an identifier that is valid for the current scope, in particular it |
| 4508 // fails on strict mode future reserved keywords in a strict scope. | 4505 // fails on strict mode future reserved keywords in a strict scope. If |
| 4509 Handle<String> Parser::ParseIdentifier(bool* ok) { | 4506 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
| 4507 // "arguments" as identifier even in strict mode (this is needed in cases like |
| 4508 // "var foo = eval;"). |
| 4509 Handle<String> Parser::ParseIdentifier( |
| 4510 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, |
| 4511 bool* ok) { |
| 4510 Token::Value next = Next(); | 4512 Token::Value next = Next(); |
| 4511 if (next == Token::IDENTIFIER || | 4513 if (next == Token::IDENTIFIER) { |
| 4512 (top_scope_->is_classic_mode() && | 4514 Handle<String> name = GetSymbol(); |
| 4513 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 4515 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && |
| 4514 (next == Token::YIELD && !is_generator())))) { | 4516 !top_scope_->is_classic_mode() && IsEvalOrArguments(name)) { |
| 4517 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); |
| 4518 *ok = false; |
| 4519 } |
| 4520 return name; |
| 4521 } else if (top_scope_->is_classic_mode() && |
| 4522 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 4523 (next == Token::YIELD && !is_generator()))) { |
| 4515 return GetSymbol(); | 4524 return GetSymbol(); |
| 4516 } else { | 4525 } else { |
| 4517 ReportUnexpectedToken(next); | 4526 ReportUnexpectedToken(next); |
| 4518 *ok = false; | 4527 *ok = false; |
| 4519 return Handle<String>(); | 4528 return Handle<String>(); |
| 4520 } | 4529 } |
| 4521 } | 4530 } |
| 4522 | 4531 |
| 4523 | 4532 |
| 4524 // Parses and identifier or a strict mode future reserved word, and indicate | 4533 // Parses and identifier or a strict mode future reserved word, and indicate |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4559 ? expression->AsVariableProxy() | 4568 ? expression->AsVariableProxy() |
| 4560 : NULL; | 4569 : NULL; |
| 4561 | 4570 |
| 4562 if (proxy != NULL) proxy->MarkAsLValue(); | 4571 if (proxy != NULL) proxy->MarkAsLValue(); |
| 4563 } | 4572 } |
| 4564 | 4573 |
| 4565 | 4574 |
| 4566 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 4575 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
| 4567 // in strict mode. | 4576 // in strict mode. |
| 4568 void Parser::CheckStrictModeLValue(Expression* expression, | 4577 void Parser::CheckStrictModeLValue(Expression* expression, |
| 4569 const char* error, | |
| 4570 bool* ok) { | 4578 bool* ok) { |
| 4571 ASSERT(!top_scope_->is_classic_mode()); | 4579 ASSERT(!top_scope_->is_classic_mode()); |
| 4572 VariableProxy* lhs = expression != NULL | 4580 VariableProxy* lhs = expression != NULL |
| 4573 ? expression->AsVariableProxy() | 4581 ? expression->AsVariableProxy() |
| 4574 : NULL; | 4582 : NULL; |
| 4575 | 4583 |
| 4576 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 4584 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 4577 ReportMessage(error, Vector<const char*>::empty()); | 4585 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); |
| 4578 *ok = false; | 4586 *ok = false; |
| 4579 } | 4587 } |
| 4580 } | 4588 } |
| 4581 | 4589 |
| 4582 | 4590 |
| 4583 // Checks whether an octal literal was last seen between beg_pos and end_pos. | 4591 // Checks whether an octal literal was last seen between beg_pos and end_pos. |
| 4584 // If so, reports an error. Only called for strict mode. | 4592 // If so, reports an error. Only called for strict mode. |
| 4585 void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 4593 void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 4586 Scanner::Location octal = scanner()->octal_position(); | 4594 Scanner::Location octal = scanner()->octal_position(); |
| 4587 if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { | 4595 if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { |
| (...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5684 ASSERT(info()->isolate()->has_pending_exception()); | 5692 ASSERT(info()->isolate()->has_pending_exception()); |
| 5685 } else { | 5693 } else { |
| 5686 result = ParseProgram(); | 5694 result = ParseProgram(); |
| 5687 } | 5695 } |
| 5688 } | 5696 } |
| 5689 info()->SetFunction(result); | 5697 info()->SetFunction(result); |
| 5690 return (result != NULL); | 5698 return (result != NULL); |
| 5691 } | 5699 } |
| 5692 | 5700 |
| 5693 } } // namespace v8::internal | 5701 } } // namespace v8::internal |
| OLD | NEW |