| 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 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 976 } | 976 } |
| 977 } | 977 } |
| 978 } | 978 } |
| 979 | 979 |
| 980 | 980 |
| 981 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { | 981 Statement* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) { |
| 982 // ModuleDeclaration: | 982 // ModuleDeclaration: |
| 983 // 'module' Identifier Module | 983 // 'module' Identifier Module |
| 984 | 984 |
| 985 int pos = peek_position(); | 985 int pos = peek_position(); |
| 986 Handle<String> name = ParseIdentifier(CHECK_OK); | 986 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 987 | 987 |
| 988 #ifdef DEBUG | 988 #ifdef DEBUG |
| 989 if (FLAG_print_interface_details) | 989 if (FLAG_print_interface_details) |
| 990 PrintF("# Module %s...\n", name->ToAsciiArray()); | 990 PrintF("# Module %s...\n", name->ToAsciiArray()); |
| 991 #endif | 991 #endif |
| 992 | 992 |
| 993 Module* module = ParseModule(CHECK_OK); | 993 Module* module = ParseModule(CHECK_OK); |
| 994 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); | 994 VariableProxy* proxy = NewUnresolved(name, MODULE, module->interface()); |
| 995 Declaration* declaration = | 995 Declaration* declaration = |
| 996 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... |
| 1129 | 1129 |
| 1130 return result; | 1130 return result; |
| 1131 } | 1131 } |
| 1132 | 1132 |
| 1133 | 1133 |
| 1134 Module* Parser::ParseModuleVariable(bool* ok) { | 1134 Module* Parser::ParseModuleVariable(bool* ok) { |
| 1135 // ModulePath: | 1135 // ModulePath: |
| 1136 // Identifier | 1136 // Identifier |
| 1137 | 1137 |
| 1138 int pos = peek_position(); | 1138 int pos = peek_position(); |
| 1139 Handle<String> name = ParseIdentifier(CHECK_OK); | 1139 Handle<String> name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1140 #ifdef DEBUG | 1140 #ifdef DEBUG |
| 1141 if (FLAG_print_interface_details) | 1141 if (FLAG_print_interface_details) |
| 1142 PrintF("# Module variable %s ", name->ToAsciiArray()); | 1142 PrintF("# Module variable %s ", name->ToAsciiArray()); |
| 1143 #endif | 1143 #endif |
| 1144 VariableProxy* proxy = top_scope_->NewUnresolved( | 1144 VariableProxy* proxy = top_scope_->NewUnresolved( |
| 1145 factory(), name, Interface::NewModule(zone()), | 1145 factory(), name, Interface::NewModule(zone()), |
| 1146 scanner().location().beg_pos); | 1146 scanner().location().beg_pos); |
| 1147 | 1147 |
| 1148 return factory()->NewModuleVariable(proxy, pos); | 1148 return factory()->NewModuleVariable(proxy, pos); |
| 1149 } | 1149 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1254 // | 1254 // |
| 1255 // TODO(ES6): implement structuring ExportSpecifiers | 1255 // TODO(ES6): implement structuring ExportSpecifiers |
| 1256 | 1256 |
| 1257 Expect(Token::EXPORT, CHECK_OK); | 1257 Expect(Token::EXPORT, CHECK_OK); |
| 1258 | 1258 |
| 1259 Statement* result = NULL; | 1259 Statement* result = NULL; |
| 1260 ZoneStringList names(1, zone()); | 1260 ZoneStringList names(1, zone()); |
| 1261 switch (peek()) { | 1261 switch (peek()) { |
| 1262 case Token::IDENTIFIER: { | 1262 case Token::IDENTIFIER: { |
| 1263 int pos = position(); | 1263 int pos = position(); |
| 1264 Handle<String> name = ParseIdentifier(CHECK_OK); | 1264 Handle<String> name = |
| 1265 ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1265 // Handle 'module' as a context-sensitive keyword. | 1266 // Handle 'module' as a context-sensitive keyword. |
| 1266 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { | 1267 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("module"))) { |
| 1267 names.Add(name, zone()); | 1268 names.Add(name, zone()); |
| 1268 while (peek() == Token::COMMA) { | 1269 while (peek() == Token::COMMA) { |
| 1269 Consume(Token::COMMA); | 1270 Consume(Token::COMMA); |
| 1270 name = ParseIdentifier(CHECK_OK); | 1271 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1271 names.Add(name, zone()); | 1272 names.Add(name, zone()); |
| 1272 } | 1273 } |
| 1273 ExpectSemicolon(CHECK_OK); | 1274 ExpectSemicolon(CHECK_OK); |
| 1274 result = factory()->NewEmptyStatement(pos); | 1275 result = factory()->NewEmptyStatement(pos); |
| 1275 } else { | 1276 } else { |
| 1276 result = ParseModuleDeclaration(&names, CHECK_OK); | 1277 result = ParseModuleDeclaration(&names, CHECK_OK); |
| 1277 } | 1278 } |
| 1278 break; | 1279 break; |
| 1279 } | 1280 } |
| 1280 | 1281 |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1625 } | 1626 } |
| 1626 | 1627 |
| 1627 | 1628 |
| 1628 // Language extension which is only enabled for source files loaded | 1629 // Language extension which is only enabled for source files loaded |
| 1629 // through the API's extension mechanism. A native function | 1630 // through the API's extension mechanism. A native function |
| 1630 // declaration is resolved by looking up the function through a | 1631 // declaration is resolved by looking up the function through a |
| 1631 // callback provided by the extension. | 1632 // callback provided by the extension. |
| 1632 Statement* Parser::ParseNativeDeclaration(bool* ok) { | 1633 Statement* Parser::ParseNativeDeclaration(bool* ok) { |
| 1633 int pos = peek_position(); | 1634 int pos = peek_position(); |
| 1634 Expect(Token::FUNCTION, CHECK_OK); | 1635 Expect(Token::FUNCTION, CHECK_OK); |
| 1635 Handle<String> name = ParseIdentifier(CHECK_OK); | 1636 // Allow "eval" or "arguments" for backward compatibility. |
| 1637 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1636 Expect(Token::LPAREN, CHECK_OK); | 1638 Expect(Token::LPAREN, CHECK_OK); |
| 1637 bool done = (peek() == Token::RPAREN); | 1639 bool done = (peek() == Token::RPAREN); |
| 1638 while (!done) { | 1640 while (!done) { |
| 1639 ParseIdentifier(CHECK_OK); | 1641 ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 1640 done = (peek() == Token::RPAREN); | 1642 done = (peek() == Token::RPAREN); |
| 1641 if (!done) { | 1643 if (!done) { |
| 1642 Expect(Token::COMMA, CHECK_OK); | 1644 Expect(Token::COMMA, CHECK_OK); |
| 1643 } | 1645 } |
| 1644 } | 1646 } |
| 1645 Expect(Token::RPAREN, CHECK_OK); | 1647 Expect(Token::RPAREN, CHECK_OK); |
| 1646 Expect(Token::SEMICOLON, CHECK_OK); | 1648 Expect(Token::SEMICOLON, CHECK_OK); |
| 1647 | 1649 |
| 1648 // Make sure that the function containing the native declaration | 1650 // Make sure that the function containing the native declaration |
| 1649 // isn't lazily compiled. The extension structures are only | 1651 // isn't lazily compiled. The extension structures are only |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1893 // | 1895 // |
| 1894 // Create new block with one expected declaration. | 1896 // Create new block with one expected declaration. |
| 1895 Block* block = factory()->NewBlock(NULL, 1, true, pos); | 1897 Block* block = factory()->NewBlock(NULL, 1, true, pos); |
| 1896 int nvars = 0; // the number of variables declared | 1898 int nvars = 0; // the number of variables declared |
| 1897 Handle<String> name; | 1899 Handle<String> name; |
| 1898 do { | 1900 do { |
| 1899 if (fni_ != NULL) fni_->Enter(); | 1901 if (fni_ != NULL) fni_->Enter(); |
| 1900 | 1902 |
| 1901 // Parse variable name. | 1903 // Parse variable name. |
| 1902 if (nvars > 0) Consume(Token::COMMA); | 1904 if (nvars > 0) Consume(Token::COMMA); |
| 1903 name = ParseIdentifier(CHECK_OK); | 1905 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 1904 if (fni_ != NULL) fni_->PushVariableName(name); | 1906 if (fni_ != NULL) fni_->PushVariableName(name); |
| 1905 | 1907 |
| 1906 // Strict mode variables may not be named eval or arguments | |
| 1907 if (!declaration_scope->is_classic_mode() && IsEvalOrArguments(name)) { | |
| 1908 ReportMessage("strict_var_name", Vector<const char*>::empty()); | |
| 1909 *ok = false; | |
| 1910 return NULL; | |
| 1911 } | |
| 1912 | |
| 1913 // Declare variable. | 1908 // Declare variable. |
| 1914 // 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 |
| 1915 // assignment for variables and constants because the value must be assigned | 1910 // assignment for variables and constants because the value must be assigned |
| 1916 // 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 |
| 1917 // is declared (and set to 'undefined') upon entering the function within | 1912 // is declared (and set to 'undefined') upon entering the function within |
| 1918 // which the variable or constant is declared. Only function variables have | 1913 // which the variable or constant is declared. Only function variables have |
| 1919 // an initial value in the declaration (because they are initialized upon | 1914 // an initial value in the declaration (because they are initialized upon |
| 1920 // entering the function). | 1915 // entering the function). |
| 1921 // | 1916 // |
| 1922 // 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... |
| 2217 Statement* Parser::ParseContinueStatement(bool* ok) { | 2212 Statement* Parser::ParseContinueStatement(bool* ok) { |
| 2218 // ContinueStatement :: | 2213 // ContinueStatement :: |
| 2219 // 'continue' Identifier? ';' | 2214 // 'continue' Identifier? ';' |
| 2220 | 2215 |
| 2221 int pos = peek_position(); | 2216 int pos = peek_position(); |
| 2222 Expect(Token::CONTINUE, CHECK_OK); | 2217 Expect(Token::CONTINUE, CHECK_OK); |
| 2223 Handle<String> label = Handle<String>::null(); | 2218 Handle<String> label = Handle<String>::null(); |
| 2224 Token::Value tok = peek(); | 2219 Token::Value tok = peek(); |
| 2225 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 2220 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
| 2226 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2221 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2227 label = ParseIdentifier(CHECK_OK); | 2222 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2223 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2228 } | 2224 } |
| 2229 IterationStatement* target = NULL; | 2225 IterationStatement* target = NULL; |
| 2230 target = LookupContinueTarget(label, CHECK_OK); | 2226 target = LookupContinueTarget(label, CHECK_OK); |
| 2231 if (target == NULL) { | 2227 if (target == NULL) { |
| 2232 // Illegal continue statement. | 2228 // Illegal continue statement. |
| 2233 const char* message = "illegal_continue"; | 2229 const char* message = "illegal_continue"; |
| 2234 Vector<Handle<String> > args; | 2230 Vector<Handle<String> > args; |
| 2235 if (!label.is_null()) { | 2231 if (!label.is_null()) { |
| 2236 message = "unknown_label"; | 2232 message = "unknown_label"; |
| 2237 args = Vector<Handle<String> >(&label, 1); | 2233 args = Vector<Handle<String> >(&label, 1); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2248 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { | 2244 Statement* Parser::ParseBreakStatement(ZoneStringList* labels, bool* ok) { |
| 2249 // BreakStatement :: | 2245 // BreakStatement :: |
| 2250 // 'break' Identifier? ';' | 2246 // 'break' Identifier? ';' |
| 2251 | 2247 |
| 2252 int pos = peek_position(); | 2248 int pos = peek_position(); |
| 2253 Expect(Token::BREAK, CHECK_OK); | 2249 Expect(Token::BREAK, CHECK_OK); |
| 2254 Handle<String> label; | 2250 Handle<String> label; |
| 2255 Token::Value tok = peek(); | 2251 Token::Value tok = peek(); |
| 2256 if (!scanner().HasAnyLineTerminatorBeforeNext() && | 2252 if (!scanner().HasAnyLineTerminatorBeforeNext() && |
| 2257 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { | 2253 tok != Token::SEMICOLON && tok != Token::RBRACE && tok != Token::EOS) { |
| 2258 label = ParseIdentifier(CHECK_OK); | 2254 // ECMA allows "eval" or "arguments" as labels even in strict mode. |
| 2255 label = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 2259 } | 2256 } |
| 2260 // Parse labeled break statements that target themselves into | 2257 // Parse labeled break statements that target themselves into |
| 2261 // empty statements, e.g. 'l1: l2: l3: break l2;' | 2258 // empty statements, e.g. 'l1: l2: l3: break l2;' |
| 2262 if (!label.is_null() && ContainsLabel(labels, label)) { | 2259 if (!label.is_null() && ContainsLabel(labels, label)) { |
| 2263 ExpectSemicolon(CHECK_OK); | 2260 ExpectSemicolon(CHECK_OK); |
| 2264 return factory()->NewEmptyStatement(pos); | 2261 return factory()->NewEmptyStatement(pos); |
| 2265 } | 2262 } |
| 2266 BreakableStatement* target = NULL; | 2263 BreakableStatement* target = NULL; |
| 2267 target = LookupBreakTarget(label, CHECK_OK); | 2264 target = LookupBreakTarget(label, CHECK_OK); |
| 2268 if (target == NULL) { | 2265 if (target == NULL) { |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2478 Scope* catch_scope = NULL; | 2475 Scope* catch_scope = NULL; |
| 2479 Variable* catch_variable = NULL; | 2476 Variable* catch_variable = NULL; |
| 2480 Block* catch_block = NULL; | 2477 Block* catch_block = NULL; |
| 2481 Handle<String> name; | 2478 Handle<String> name; |
| 2482 if (tok == Token::CATCH) { | 2479 if (tok == Token::CATCH) { |
| 2483 Consume(Token::CATCH); | 2480 Consume(Token::CATCH); |
| 2484 | 2481 |
| 2485 Expect(Token::LPAREN, CHECK_OK); | 2482 Expect(Token::LPAREN, CHECK_OK); |
| 2486 catch_scope = NewScope(top_scope_, CATCH_SCOPE); | 2483 catch_scope = NewScope(top_scope_, CATCH_SCOPE); |
| 2487 catch_scope->set_start_position(scanner().location().beg_pos); | 2484 catch_scope->set_start_position(scanner().location().beg_pos); |
| 2488 name = ParseIdentifier(CHECK_OK); | 2485 name = ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK); |
| 2489 | |
| 2490 if (!top_scope_->is_classic_mode() && IsEvalOrArguments(name)) { | |
| 2491 ReportMessage("strict_catch_variable", Vector<const char*>::empty()); | |
| 2492 *ok = false; | |
| 2493 return NULL; | |
| 2494 } | |
| 2495 | 2486 |
| 2496 Expect(Token::RPAREN, CHECK_OK); | 2487 Expect(Token::RPAREN, CHECK_OK); |
| 2497 | 2488 |
| 2498 if (peek() == Token::LBRACE) { | 2489 if (peek() == Token::LBRACE) { |
| 2499 Target target(&this->target_stack_, &catch_collector); | 2490 Target target(&this->target_stack_, &catch_collector); |
| 2500 VariableMode mode = is_extended_mode() ? LET : VAR; | 2491 VariableMode mode = is_extended_mode() ? LET : VAR; |
| 2501 catch_variable = | 2492 catch_variable = |
| 2502 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); | 2493 catch_scope->DeclareLocal(name, mode, kCreatedInitialized); |
| 2503 | 2494 |
| 2504 BlockState block_state(this, catch_scope); | 2495 BlockState block_state(this, catch_scope); |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2932 // runtime. | 2923 // runtime. |
| 2933 // TODO(ES5): Should change parsing for spec conformance. | 2924 // TODO(ES5): Should change parsing for spec conformance. |
| 2934 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 2925 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 2935 Handle<String> message = | 2926 Handle<String> message = |
| 2936 isolate()->factory()->invalid_lhs_in_assignment_string(); | 2927 isolate()->factory()->invalid_lhs_in_assignment_string(); |
| 2937 expression = NewThrowReferenceError(message); | 2928 expression = NewThrowReferenceError(message); |
| 2938 } | 2929 } |
| 2939 | 2930 |
| 2940 if (!top_scope_->is_classic_mode()) { | 2931 if (!top_scope_->is_classic_mode()) { |
| 2941 // Assignment to eval or arguments is disallowed in strict mode. | 2932 // Assignment to eval or arguments is disallowed in strict mode. |
| 2942 CheckStrictModeLValue(expression, "strict_lhs_assignment", CHECK_OK); | 2933 CheckStrictModeLValue(expression, CHECK_OK); |
| 2943 } | 2934 } |
| 2944 MarkAsLValue(expression); | 2935 MarkAsLValue(expression); |
| 2945 | 2936 |
| 2946 Token::Value op = Next(); // Get assignment operator. | 2937 Token::Value op = Next(); // Get assignment operator. |
| 2947 int pos = position(); | 2938 int pos = position(); |
| 2948 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | 2939 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); |
| 2949 | 2940 |
| 2950 // TODO(1231235): We try to estimate the set of properties set by | 2941 // TODO(1231235): We try to estimate the set of properties set by |
| 2951 // constructors. We define a new property whenever there is an | 2942 // constructors. We define a new property whenever there is an |
| 2952 // assignment to a property of 'this'. We should probably only add | 2943 // assignment to a property of 'this'. We should probably only add |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3212 // error here but for compatibility with JSC we choose to report the | 3203 // error here but for compatibility with JSC we choose to report the |
| 3213 // error at runtime. | 3204 // error at runtime. |
| 3214 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3205 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3215 Handle<String> message = | 3206 Handle<String> message = |
| 3216 isolate()->factory()->invalid_lhs_in_prefix_op_string(); | 3207 isolate()->factory()->invalid_lhs_in_prefix_op_string(); |
| 3217 expression = NewThrowReferenceError(message); | 3208 expression = NewThrowReferenceError(message); |
| 3218 } | 3209 } |
| 3219 | 3210 |
| 3220 if (!top_scope_->is_classic_mode()) { | 3211 if (!top_scope_->is_classic_mode()) { |
| 3221 // Prefix expression operand in strict mode may not be eval or arguments. | 3212 // Prefix expression operand in strict mode may not be eval or arguments. |
| 3222 CheckStrictModeLValue(expression, "strict_lhs_prefix", CHECK_OK); | 3213 CheckStrictModeLValue(expression, CHECK_OK); |
| 3223 } | 3214 } |
| 3224 MarkAsLValue(expression); | 3215 MarkAsLValue(expression); |
| 3225 | 3216 |
| 3226 return factory()->NewCountOperation(op, | 3217 return factory()->NewCountOperation(op, |
| 3227 true /* prefix */, | 3218 true /* prefix */, |
| 3228 expression, | 3219 expression, |
| 3229 position()); | 3220 position()); |
| 3230 | 3221 |
| 3231 } else { | 3222 } else { |
| 3232 return ParsePostfixExpression(ok); | 3223 return ParsePostfixExpression(ok); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3246 // error here but for compatibility with JSC we choose to report the | 3237 // error here but for compatibility with JSC we choose to report the |
| 3247 // error at runtime. | 3238 // error at runtime. |
| 3248 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3239 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3249 Handle<String> message = | 3240 Handle<String> message = |
| 3250 isolate()->factory()->invalid_lhs_in_postfix_op_string(); | 3241 isolate()->factory()->invalid_lhs_in_postfix_op_string(); |
| 3251 expression = NewThrowReferenceError(message); | 3242 expression = NewThrowReferenceError(message); |
| 3252 } | 3243 } |
| 3253 | 3244 |
| 3254 if (!top_scope_->is_classic_mode()) { | 3245 if (!top_scope_->is_classic_mode()) { |
| 3255 // Postfix expression operand in strict mode may not be eval or arguments. | 3246 // Postfix expression operand in strict mode may not be eval or arguments. |
| 3256 CheckStrictModeLValue(expression, "strict_lhs_postfix", CHECK_OK); | 3247 CheckStrictModeLValue(expression, CHECK_OK); |
| 3257 } | 3248 } |
| 3258 MarkAsLValue(expression); | 3249 MarkAsLValue(expression); |
| 3259 | 3250 |
| 3260 Token::Value next = Next(); | 3251 Token::Value next = Next(); |
| 3261 expression = | 3252 expression = |
| 3262 factory()->NewCountOperation(next, | 3253 factory()->NewCountOperation(next, |
| 3263 false /* postfix */, | 3254 false /* postfix */, |
| 3264 expression, | 3255 expression, |
| 3265 position()); | 3256 position()); |
| 3266 } | 3257 } |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3556 break; | 3547 break; |
| 3557 | 3548 |
| 3558 case Token::FALSE_LITERAL: | 3549 case Token::FALSE_LITERAL: |
| 3559 Consume(Token::FALSE_LITERAL); | 3550 Consume(Token::FALSE_LITERAL); |
| 3560 result = factory()->NewLiteral(isolate()->factory()->false_value(), pos); | 3551 result = factory()->NewLiteral(isolate()->factory()->false_value(), pos); |
| 3561 break; | 3552 break; |
| 3562 | 3553 |
| 3563 case Token::IDENTIFIER: | 3554 case Token::IDENTIFIER: |
| 3564 case Token::YIELD: | 3555 case Token::YIELD: |
| 3565 case Token::FUTURE_STRICT_RESERVED_WORD: { | 3556 case Token::FUTURE_STRICT_RESERVED_WORD: { |
| 3566 Handle<String> name = ParseIdentifier(CHECK_OK); | 3557 // Using eval or arguments in this context is OK even in strict mode. |
| 3558 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 3567 if (fni_ != NULL) fni_->PushVariableName(name); | 3559 if (fni_ != NULL) fni_->PushVariableName(name); |
| 3568 // The name may refer to a module instance object, so its type is unknown. | 3560 // The name may refer to a module instance object, so its type is unknown. |
| 3569 #ifdef DEBUG | 3561 #ifdef DEBUG |
| 3570 if (FLAG_print_interface_details) | 3562 if (FLAG_print_interface_details) |
| 3571 PrintF("# Variable %s ", name->ToAsciiArray()); | 3563 PrintF("# Variable %s ", name->ToAsciiArray()); |
| 3572 #endif | 3564 #endif |
| 3573 Interface* interface = Interface::NewUnknown(zone()); | 3565 Interface* interface = Interface::NewUnknown(zone()); |
| 3574 result = top_scope_->NewUnresolved(factory(), name, interface, pos); | 3566 result = top_scope_->NewUnresolved(factory(), name, interface, pos); |
| 3575 break; | 3567 break; |
| 3576 } | 3568 } |
| (...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4296 handler_count = function_state.handler_count(); | 4288 handler_count = function_state.handler_count(); |
| 4297 | 4289 |
| 4298 Expect(Token::RBRACE, CHECK_OK); | 4290 Expect(Token::RBRACE, CHECK_OK); |
| 4299 scope->set_end_position(scanner().location().end_pos); | 4291 scope->set_end_position(scanner().location().end_pos); |
| 4300 } | 4292 } |
| 4301 | 4293 |
| 4302 // Validate strict mode. | 4294 // Validate strict mode. |
| 4303 if (!top_scope_->is_classic_mode()) { | 4295 if (!top_scope_->is_classic_mode()) { |
| 4304 if (IsEvalOrArguments(function_name)) { | 4296 if (IsEvalOrArguments(function_name)) { |
| 4305 ReportMessageAt(function_name_location, | 4297 ReportMessageAt(function_name_location, |
| 4306 "strict_function_name", | 4298 "strict_eval_arguments", |
| 4307 Vector<const char*>::empty()); | 4299 Vector<const char*>::empty()); |
| 4308 *ok = false; | 4300 *ok = false; |
| 4309 return NULL; | 4301 return NULL; |
| 4310 } | 4302 } |
| 4311 if (name_loc.IsValid()) { | 4303 if (name_loc.IsValid()) { |
| 4312 ReportMessageAt(name_loc, "strict_param_name", | 4304 ReportMessageAt(name_loc, "strict_eval_arguments", |
| 4313 Vector<const char*>::empty()); | 4305 Vector<const char*>::empty()); |
| 4314 *ok = false; | 4306 *ok = false; |
| 4315 return NULL; | 4307 return NULL; |
| 4316 } | 4308 } |
| 4317 if (dupe_loc.IsValid()) { | 4309 if (dupe_loc.IsValid()) { |
| 4318 ReportMessageAt(dupe_loc, "strict_param_dupe", | 4310 ReportMessageAt(dupe_loc, "strict_param_dupe", |
| 4319 Vector<const char*>::empty()); | 4311 Vector<const char*>::empty()); |
| 4320 *ok = false; | 4312 *ok = false; |
| 4321 return NULL; | 4313 return NULL; |
| 4322 } | 4314 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4391 return result; | 4383 return result; |
| 4392 } | 4384 } |
| 4393 | 4385 |
| 4394 | 4386 |
| 4395 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4387 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 4396 // CallRuntime :: | 4388 // CallRuntime :: |
| 4397 // '%' Identifier Arguments | 4389 // '%' Identifier Arguments |
| 4398 | 4390 |
| 4399 int pos = peek_position(); | 4391 int pos = peek_position(); |
| 4400 Expect(Token::MOD, CHECK_OK); | 4392 Expect(Token::MOD, CHECK_OK); |
| 4401 Handle<String> name = ParseIdentifier(CHECK_OK); | 4393 // Allow "eval" or "arguments" for backward compatibility. |
| 4394 Handle<String> name = ParseIdentifier(kAllowEvalOrArguments, CHECK_OK); |
| 4402 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 4395 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 4403 | 4396 |
| 4404 if (extension_ != NULL) { | 4397 if (extension_ != NULL) { |
| 4405 // The extension structures are only accessible while parsing the | 4398 // The extension structures are only accessible while parsing the |
| 4406 // very first time not when reparsing because of lazy compilation. | 4399 // very first time not when reparsing because of lazy compilation. |
| 4407 top_scope_->DeclarationScope()->ForceEagerCompilation(); | 4400 top_scope_->DeclarationScope()->ForceEagerCompilation(); |
| 4408 } | 4401 } |
| 4409 | 4402 |
| 4410 const Runtime::Function* function = Runtime::FunctionForName(name); | 4403 const Runtime::Function* function = Runtime::FunctionForName(name); |
| 4411 | 4404 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4498 } | 4491 } |
| 4499 | 4492 |
| 4500 | 4493 |
| 4501 Literal* Parser::GetLiteralTheHole(int position) { | 4494 Literal* Parser::GetLiteralTheHole(int position) { |
| 4502 return factory()->NewLiteral( | 4495 return factory()->NewLiteral( |
| 4503 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); | 4496 isolate()->factory()->the_hole_value(), RelocInfo::kNoPosition); |
| 4504 } | 4497 } |
| 4505 | 4498 |
| 4506 | 4499 |
| 4507 // Parses an identifier that is valid for the current scope, in particular it | 4500 // 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. | 4501 // fails on strict mode future reserved keywords in a strict scope. If |
| 4509 Handle<String> Parser::ParseIdentifier(bool* ok) { | 4502 // allow_eval_or_arguments is kAllowEvalOrArguments, we allow "eval" or |
| 4503 // "arguments" as identifier even in strict mode (this is needed in cases like |
| 4504 // "var foo = eval;"). |
| 4505 Handle<String> Parser::ParseIdentifier( |
| 4506 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, |
| 4507 bool* ok) { |
| 4510 Token::Value next = Next(); | 4508 Token::Value next = Next(); |
| 4511 if (next == Token::IDENTIFIER || | 4509 if (next == Token::IDENTIFIER) { |
| 4512 (top_scope_->is_classic_mode() && | 4510 Handle<String> name = GetSymbol(); |
| 4513 (next == Token::FUTURE_STRICT_RESERVED_WORD || | 4511 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && |
| 4514 (next == Token::YIELD && !is_generator())))) { | 4512 !top_scope_->is_classic_mode() && IsEvalOrArguments(name)) { |
| 4513 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); |
| 4514 *ok = false; |
| 4515 } |
| 4516 return name; |
| 4517 } else if (top_scope_->is_classic_mode() && |
| 4518 (next == Token::FUTURE_STRICT_RESERVED_WORD || |
| 4519 (next == Token::YIELD && !is_generator()))) { |
| 4515 return GetSymbol(); | 4520 return GetSymbol(); |
| 4516 } else { | 4521 } else { |
| 4517 ReportUnexpectedToken(next); | 4522 ReportUnexpectedToken(next); |
| 4518 *ok = false; | 4523 *ok = false; |
| 4519 return Handle<String>(); | 4524 return Handle<String>(); |
| 4520 } | 4525 } |
| 4521 } | 4526 } |
| 4522 | 4527 |
| 4523 | 4528 |
| 4524 // Parses and identifier or a strict mode future reserved word, and indicate | 4529 // 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() | 4564 ? expression->AsVariableProxy() |
| 4560 : NULL; | 4565 : NULL; |
| 4561 | 4566 |
| 4562 if (proxy != NULL) proxy->MarkAsLValue(); | 4567 if (proxy != NULL) proxy->MarkAsLValue(); |
| 4563 } | 4568 } |
| 4564 | 4569 |
| 4565 | 4570 |
| 4566 // Checks LHS expression for assignment and prefix/postfix increment/decrement | 4571 // Checks LHS expression for assignment and prefix/postfix increment/decrement |
| 4567 // in strict mode. | 4572 // in strict mode. |
| 4568 void Parser::CheckStrictModeLValue(Expression* expression, | 4573 void Parser::CheckStrictModeLValue(Expression* expression, |
| 4569 const char* error, | |
| 4570 bool* ok) { | 4574 bool* ok) { |
| 4571 ASSERT(!top_scope_->is_classic_mode()); | 4575 ASSERT(!top_scope_->is_classic_mode()); |
| 4572 VariableProxy* lhs = expression != NULL | 4576 VariableProxy* lhs = expression != NULL |
| 4573 ? expression->AsVariableProxy() | 4577 ? expression->AsVariableProxy() |
| 4574 : NULL; | 4578 : NULL; |
| 4575 | 4579 |
| 4576 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 4580 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 4577 ReportMessage(error, Vector<const char*>::empty()); | 4581 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); |
| 4578 *ok = false; | 4582 *ok = false; |
| 4579 } | 4583 } |
| 4580 } | 4584 } |
| 4581 | 4585 |
| 4582 | 4586 |
| 4583 // Checks whether an octal literal was last seen between beg_pos and end_pos. | 4587 // 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. | 4588 // If so, reports an error. Only called for strict mode. |
| 4585 void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { | 4589 void ParserBase::CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { |
| 4586 Scanner::Location octal = scanner()->octal_position(); | 4590 Scanner::Location octal = scanner()->octal_position(); |
| 4587 if (octal.IsValid() && beg_pos <= octal.beg_pos && octal.end_pos <= end_pos) { | 4591 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()); | 5688 ASSERT(info()->isolate()->has_pending_exception()); |
| 5685 } else { | 5689 } else { |
| 5686 result = ParseProgram(); | 5690 result = ParseProgram(); |
| 5687 } | 5691 } |
| 5688 } | 5692 } |
| 5689 info()->SetFunction(result); | 5693 info()->SetFunction(result); |
| 5690 return (result != NULL); | 5694 return (result != NULL); |
| 5691 } | 5695 } |
| 5692 | 5696 |
| 5693 } } // namespace v8::internal | 5697 } } // namespace v8::internal |
| OLD | NEW |