Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Side by Side Diff: src/parser.cc

Issue 152813005: Make strict more error messages about "eval" and "arguments" less specific. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Code review (ulan@) Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698