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

Side by Side Diff: src/parser.cc

Issue 6246064: Issue 117 - strict mode and future reserved words (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 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') | src/preparser.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 Handle<String> no_name = Factory::empty_symbol(); 743 Handle<String> no_name = Factory::empty_symbol();
744 Scope* scope = 744 Scope* scope =
745 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with()); 745 NewScope(top_scope_, Scope::GLOBAL_SCOPE, inside_with());
746 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_, 746 LexicalScope lexical_scope(&this->top_scope_, &this->with_nesting_level_,
747 scope); 747 scope);
748 TemporaryScope temp_scope(&this->temp_scope_); 748 TemporaryScope temp_scope(&this->temp_scope_);
749 749
750 FunctionLiteralType type = 750 FunctionLiteralType type =
751 info->is_expression() ? EXPRESSION : DECLARATION; 751 info->is_expression() ? EXPRESSION : DECLARATION;
752 bool ok = true; 752 bool ok = true;
753 result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok); 753 result = ParseFunctionLiteral(name, false, // strict mode identifier already checked???
Lasse Reichstein 2011/02/03 11:42:48 The SharedFunctionInfo should (eventually) contain
Peter Hallam 2011/02/04 18:32:41 If I understand correctly, we can only get here af
Lasse Reichstein 2011/02/07 08:05:36 True. Maybe at some point add an ASSERT that the n
754 RelocInfo::kNoPosition, type, &ok);
754 // Make sure the results agree. 755 // Make sure the results agree.
755 ASSERT(ok == (result != NULL)); 756 ASSERT(ok == (result != NULL));
756 // The only errors should be stack overflows. 757 // The only errors should be stack overflows.
757 ASSERT(ok || stack_overflow_); 758 ASSERT(ok || stack_overflow_);
758 } 759 }
759 760
760 // Make sure the target stack is empty. 761 // Make sure the target stack is empty.
761 ASSERT(target_stack_ == NULL); 762 ASSERT(target_stack_ == NULL);
762 763
763 // If there was a stack overflow we have to get rid of AST and it is 764 // If there was a stack overflow we have to get rid of AST and it is
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
1432 return new ExpressionStatement( 1433 return new ExpressionStatement(
1433 new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); 1434 new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
1434 } 1435 }
1435 1436
1436 1437
1437 Statement* Parser::ParseFunctionDeclaration(bool* ok) { 1438 Statement* Parser::ParseFunctionDeclaration(bool* ok) {
1438 // FunctionDeclaration :: 1439 // FunctionDeclaration ::
1439 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 1440 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1440 Expect(Token::FUNCTION, CHECK_OK); 1441 Expect(Token::FUNCTION, CHECK_OK);
1441 int function_token_position = scanner().location().beg_pos; 1442 int function_token_position = scanner().location().beg_pos;
1442 Handle<String> name = ParseIdentifier(CHECK_OK); 1443 bool is_reserved = false;
1444 Handle<String> name = ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
1443 FunctionLiteral* fun = ParseFunctionLiteral(name, 1445 FunctionLiteral* fun = ParseFunctionLiteral(name,
1446 is_reserved,
1444 function_token_position, 1447 function_token_position,
1445 DECLARATION, 1448 DECLARATION,
1446 CHECK_OK); 1449 CHECK_OK);
1447 // Even if we're not at the top-level of the global or a function 1450 // Even if we're not at the top-level of the global or a function
1448 // scope, we treat is as such and introduce the function with it's 1451 // scope, we treat is as such and introduce the function with it's
1449 // initial value upon entering the corresponding scope. 1452 // initial value upon entering the corresponding scope.
1450 Declare(name, Variable::VAR, fun, true, CHECK_OK); 1453 Declare(name, Variable::VAR, fun, true, CHECK_OK);
1451 return EmptyStatement(); 1454 return EmptyStatement();
1452 } 1455 }
1453 1456
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1692 1695
1693 return false; 1696 return false;
1694 } 1697 }
1695 1698
1696 1699
1697 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, 1700 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
1698 bool* ok) { 1701 bool* ok) {
1699 // ExpressionStatement | LabelledStatement :: 1702 // ExpressionStatement | LabelledStatement ::
1700 // Expression ';' 1703 // Expression ';'
1701 // Identifier ':' Statement 1704 // Identifier ':' Statement
1702 bool starts_with_idenfifier = (peek() == Token::IDENTIFIER); 1705 bool starts_with_idenfifier = peek_any_identifier();
1703 Expression* expr = ParseExpression(true, CHECK_OK); 1706 Expression* expr = ParseExpression(true, CHECK_OK);
1704 if (peek() == Token::COLON && starts_with_idenfifier && expr && 1707 if (peek() == Token::COLON && starts_with_idenfifier && expr &&
1705 expr->AsVariableProxy() != NULL && 1708 expr->AsVariableProxy() != NULL &&
1706 !expr->AsVariableProxy()->is_this()) { 1709 !expr->AsVariableProxy()->is_this()) {
1707 // Expression is a single identifier, and not, e.g., a parenthesized 1710 // Expression is a single identifier, and not, e.g., a parenthesized
1708 // identifier. 1711 // identifier.
1709 VariableProxy* var = expr->AsVariableProxy(); 1712 VariableProxy* var = expr->AsVariableProxy();
1710 Handle<String> label = var->name(); 1713 Handle<String> label = var->name();
1711 // TODO(1240780): We don't check for redeclaration of labels 1714 // TODO(1240780): We don't check for redeclaration of labels
1712 // during preparsing since keeping track of the set of active 1715 // during preparsing since keeping track of the set of active
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after
2681 // MemberExpression :: 2684 // MemberExpression ::
2682 // (PrimaryExpression | FunctionLiteral) 2685 // (PrimaryExpression | FunctionLiteral)
2683 // ('[' Expression ']' | '.' Identifier | Arguments)* 2686 // ('[' Expression ']' | '.' Identifier | Arguments)*
2684 2687
2685 // Parse the initial primary or function expression. 2688 // Parse the initial primary or function expression.
2686 Expression* result = NULL; 2689 Expression* result = NULL;
2687 if (peek() == Token::FUNCTION) { 2690 if (peek() == Token::FUNCTION) {
2688 Expect(Token::FUNCTION, CHECK_OK); 2691 Expect(Token::FUNCTION, CHECK_OK);
2689 int function_token_position = scanner().location().beg_pos; 2692 int function_token_position = scanner().location().beg_pos;
2690 Handle<String> name; 2693 Handle<String> name;
2691 if (peek() == Token::IDENTIFIER) name = ParseIdentifier(CHECK_OK); 2694 bool is_reserved_name = false;
2692 result = ParseFunctionLiteral(name, function_token_position, 2695 if (peek_any_identifier()) {
2693 NESTED, CHECK_OK); 2696 name = ParseIdentifierOrReservedWord(&is_reserved_name, CHECK_OK);
2697 }
2698 result = ParseFunctionLiteral(name, is_reserved_name,
2699 function_token_position, NESTED, CHECK_OK);
2694 } else { 2700 } else {
2695 result = ParsePrimaryExpression(CHECK_OK); 2701 result = ParsePrimaryExpression(CHECK_OK);
2696 } 2702 }
2697 2703
2698 while (true) { 2704 while (true) {
2699 switch (peek()) { 2705 switch (peek()) {
2700 case Token::LBRACK: { 2706 case Token::LBRACK: {
2701 Consume(Token::LBRACK); 2707 Consume(Token::LBRACK);
2702 int pos = scanner().location().beg_pos; 2708 int pos = scanner().location().beg_pos;
2703 Expression* index = ParseExpression(true, CHECK_OK); 2709 Expression* index = ParseExpression(true, CHECK_OK);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2752 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); 2758 return ReportMessage("unexpected_eos", Vector<const char*>::empty());
2753 case Token::NUMBER: 2759 case Token::NUMBER:
2754 return ReportMessage("unexpected_token_number", 2760 return ReportMessage("unexpected_token_number",
2755 Vector<const char*>::empty()); 2761 Vector<const char*>::empty());
2756 case Token::STRING: 2762 case Token::STRING:
2757 return ReportMessage("unexpected_token_string", 2763 return ReportMessage("unexpected_token_string",
2758 Vector<const char*>::empty()); 2764 Vector<const char*>::empty());
2759 case Token::IDENTIFIER: 2765 case Token::IDENTIFIER:
2760 return ReportMessage("unexpected_token_identifier", 2766 return ReportMessage("unexpected_token_identifier",
2761 Vector<const char*>::empty()); 2767 Vector<const char*>::empty());
2768 case Token::IDENTIFIER_OR_FUTURE_RESERVED_WORD:
2769 return ReportMessage(temp_scope_->StrictMode() ?
2770 "unexpected_strict_reserved" :
2771 "unexpected_token_identifier",
2772 Vector<const char*>::empty());
2762 default: 2773 default:
2763 const char* name = Token::String(token); 2774 const char* name = Token::String(token);
2764 ASSERT(name != NULL); 2775 ASSERT(name != NULL);
2765 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); 2776 ReportMessage("unexpected_token", Vector<const char*>(&name, 1));
2766 } 2777 }
2767 } 2778 }
2768 2779
2769 2780
2770 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { 2781 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
2771 SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS); 2782 SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2807 case Token::TRUE_LITERAL: 2818 case Token::TRUE_LITERAL:
2808 Consume(Token::TRUE_LITERAL); 2819 Consume(Token::TRUE_LITERAL);
2809 result = new Literal(Factory::true_value()); 2820 result = new Literal(Factory::true_value());
2810 break; 2821 break;
2811 2822
2812 case Token::FALSE_LITERAL: 2823 case Token::FALSE_LITERAL:
2813 Consume(Token::FALSE_LITERAL); 2824 Consume(Token::FALSE_LITERAL);
2814 result = new Literal(Factory::false_value()); 2825 result = new Literal(Factory::false_value());
2815 break; 2826 break;
2816 2827
2817 case Token::IDENTIFIER: { 2828 case Token::IDENTIFIER:
2829 case Token::IDENTIFIER_OR_FUTURE_RESERVED_WORD: {
Lasse Reichstein 2011/02/03 11:42:48 This seems odd, since both tokens seem to be able
Peter Hallam 2011/02/04 18:32:41 Done.
2818 Handle<String> name = ParseIdentifier(CHECK_OK); 2830 Handle<String> name = ParseIdentifier(CHECK_OK);
2819 if (fni_ != NULL) fni_->PushVariableName(name); 2831 if (fni_ != NULL) fni_->PushVariableName(name);
2820 result = top_scope_->NewUnresolved(name, inside_with()); 2832 result = top_scope_->NewUnresolved(name, inside_with());
2821 break; 2833 break;
2822 } 2834 }
2823 2835
2824 case Token::NUMBER: { 2836 case Token::NUMBER: {
2825 Consume(Token::NUMBER); 2837 Consume(Token::NUMBER);
2826 ASSERT(scanner().is_literal_ascii()); 2838 ASSERT(scanner().is_literal_ascii());
2827 double value = StringToDouble(scanner().literal_ascii_string(), 2839 double value = StringToDouble(scanner().literal_ascii_string(),
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
3215 3227
3216 3228
3217 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, 3229 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
3218 bool* ok) { 3230 bool* ok) {
3219 // Special handling of getter and setter syntax: 3231 // Special handling of getter and setter syntax:
3220 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 3232 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
3221 // We have already read the "get" or "set" keyword. 3233 // We have already read the "get" or "set" keyword.
3222 Token::Value next = Next(); 3234 Token::Value next = Next();
3223 bool is_keyword = Token::IsKeyword(next); 3235 bool is_keyword = Token::IsKeyword(next);
3224 if (next == Token::IDENTIFIER || next == Token::NUMBER || 3236 if (next == Token::IDENTIFIER || next == Token::NUMBER ||
3237 next == Token::IDENTIFIER_OR_FUTURE_RESERVED_WORD ||
3225 next == Token::STRING || is_keyword) { 3238 next == Token::STRING || is_keyword) {
3226 Handle<String> name; 3239 Handle<String> name;
3227 if (is_keyword) { 3240 if (is_keyword) {
3228 name = Factory::LookupAsciiSymbol(Token::String(next)); 3241 name = Factory::LookupAsciiSymbol(Token::String(next));
3229 } else { 3242 } else {
3230 name = GetSymbol(CHECK_OK); 3243 name = GetSymbol(CHECK_OK);
3231 } 3244 }
3232 FunctionLiteral* value = 3245 FunctionLiteral* value =
3233 ParseFunctionLiteral(name, 3246 ParseFunctionLiteral(name,
3247 false, // reserved words are allowed here
3234 RelocInfo::kNoPosition, 3248 RelocInfo::kNoPosition,
3235 DECLARATION, 3249 DECLARATION,
3236 CHECK_OK); 3250 CHECK_OK);
3237 // Allow any number of parameters for compatiabilty with JSC. 3251 // Allow any number of parameters for compatiabilty with JSC.
3238 // Specification only allows zero parameters for get and one for set. 3252 // Specification only allows zero parameters for get and one for set.
3239 ObjectLiteral::Property* property = 3253 ObjectLiteral::Property* property =
3240 new ObjectLiteral::Property(is_getter, value); 3254 new ObjectLiteral::Property(is_getter, value);
3241 return property; 3255 return property;
3242 } else { 3256 } else {
3243 ReportUnexpectedToken(next); 3257 ReportUnexpectedToken(next);
(...skipping 22 matching lines...) Expand all
3266 while (peek() != Token::RBRACE) { 3280 while (peek() != Token::RBRACE) {
3267 if (fni_ != NULL) fni_->Enter(); 3281 if (fni_ != NULL) fni_->Enter();
3268 3282
3269 Literal* key = NULL; 3283 Literal* key = NULL;
3270 Token::Value next = peek(); 3284 Token::Value next = peek();
3271 3285
3272 // Location of the property name token 3286 // Location of the property name token
3273 Scanner::Location loc = scanner().peek_location(); 3287 Scanner::Location loc = scanner().peek_location();
3274 3288
3275 switch (next) { 3289 switch (next) {
3290 case Token::IDENTIFIER_OR_FUTURE_RESERVED_WORD:
3276 case Token::IDENTIFIER: { 3291 case Token::IDENTIFIER: {
3277 bool is_getter = false; 3292 bool is_getter = false;
3278 bool is_setter = false; 3293 bool is_setter = false;
3279 Handle<String> id = 3294 Handle<String> id =
3280 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 3295 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
3281 if (fni_ != NULL) fni_->PushLiteralName(id); 3296 if (fni_ != NULL) fni_->PushLiteralName(id);
3282 3297
3283 if ((is_getter || is_setter) && peek() != Token::COLON) { 3298 if ((is_getter || is_setter) && peek() != Token::COLON) {
3284 // Update loc to point to the identifier 3299 // Update loc to point to the identifier
3285 loc = scanner().peek_location(); 3300 loc = scanner().peek_location();
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
3414 result->Add(argument); 3429 result->Add(argument);
3415 done = (peek() == Token::RPAREN); 3430 done = (peek() == Token::RPAREN);
3416 if (!done) Expect(Token::COMMA, CHECK_OK); 3431 if (!done) Expect(Token::COMMA, CHECK_OK);
3417 } 3432 }
3418 Expect(Token::RPAREN, CHECK_OK); 3433 Expect(Token::RPAREN, CHECK_OK);
3419 return result; 3434 return result;
3420 } 3435 }
3421 3436
3422 3437
3423 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, 3438 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
3439 bool name_is_reserved,
3424 int function_token_position, 3440 int function_token_position,
3425 FunctionLiteralType type, 3441 FunctionLiteralType type,
3426 bool* ok) { 3442 bool* ok) {
3427 // Function :: 3443 // Function ::
3428 // '(' FormalParameterList? ')' '{' FunctionBody '}' 3444 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3429 bool is_named = !var_name.is_null(); 3445 bool is_named = !var_name.is_null();
3430 3446
3431 // The name associated with this function. If it's a function expression, 3447 // The name associated with this function. If it's a function expression,
3432 // this is the actual function name, otherwise this is the name of the 3448 // this is the actual function name, otherwise this is the name of the
3433 // variable declared and initialized with the function (expression). In 3449 // variable declared and initialized with the function (expression). In
(...skipping 13 matching lines...) Expand all
3447 scope); 3463 scope);
3448 TemporaryScope temp_scope(&this->temp_scope_); 3464 TemporaryScope temp_scope(&this->temp_scope_);
3449 top_scope_->SetScopeName(name); 3465 top_scope_->SetScopeName(name);
3450 3466
3451 // FormalParameterList :: 3467 // FormalParameterList ::
3452 // '(' (Identifier)*[','] ')' 3468 // '(' (Identifier)*[','] ')'
3453 Expect(Token::LPAREN, CHECK_OK); 3469 Expect(Token::LPAREN, CHECK_OK);
3454 int start_pos = scanner().location().beg_pos; 3470 int start_pos = scanner().location().beg_pos;
3455 Scanner::Location name_loc = Scanner::NoLocation(); 3471 Scanner::Location name_loc = Scanner::NoLocation();
3456 Scanner::Location dupe_loc = Scanner::NoLocation(); 3472 Scanner::Location dupe_loc = Scanner::NoLocation();
3473 Scanner::Location reserved_loc = Scanner::NoLocation();
3457 3474
3458 bool done = (peek() == Token::RPAREN); 3475 bool done = (peek() == Token::RPAREN);
3459 while (!done) { 3476 while (!done) {
3460 Handle<String> param_name = ParseIdentifier(CHECK_OK); 3477 bool is_reserved = false;
3478 Handle<String> param_name =
3479 ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
3461 3480
3462 // Store locations for possible future error reports. 3481 // Store locations for possible future error reports.
3463 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) { 3482 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
3464 name_loc = scanner().location(); 3483 name_loc = scanner().location();
3465 } 3484 }
3466 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { 3485 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
3467 dupe_loc = scanner().location(); 3486 dupe_loc = scanner().location();
3468 } 3487 }
3488 if (!reserved_loc.IsValid() && is_reserved) {
3489 reserved_loc = scanner().location();
3490 }
3469 3491
3470 Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR); 3492 Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR);
3471 top_scope_->AddParameter(parameter); 3493 top_scope_->AddParameter(parameter);
3472 num_parameters++; 3494 num_parameters++;
3473 done = (peek() == Token::RPAREN); 3495 done = (peek() == Token::RPAREN);
3474 if (!done) Expect(Token::COMMA, CHECK_OK); 3496 if (!done) Expect(Token::COMMA, CHECK_OK);
3475 } 3497 }
3476 Expect(Token::RPAREN, CHECK_OK); 3498 Expect(Token::RPAREN, CHECK_OK);
3477 3499
3478 Expect(Token::LBRACE, CHECK_OK); 3500 Expect(Token::LBRACE, CHECK_OK);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
3539 Expect(Token::RBRACE, CHECK_OK); 3561 Expect(Token::RBRACE, CHECK_OK);
3540 end_pos = scanner().location().end_pos; 3562 end_pos = scanner().location().end_pos;
3541 } 3563 }
3542 3564
3543 // Validate strict mode. 3565 // Validate strict mode.
3544 if (temp_scope_->StrictMode()) { 3566 if (temp_scope_->StrictMode()) {
3545 if (IsEvalOrArguments(name)) { 3567 if (IsEvalOrArguments(name)) {
3546 int position = function_token_position != RelocInfo::kNoPosition 3568 int position = function_token_position != RelocInfo::kNoPosition
3547 ? function_token_position 3569 ? function_token_position
3548 : (start_pos > 0 ? start_pos - 1 : start_pos); 3570 : (start_pos > 0 ? start_pos - 1 : start_pos);
3549 ReportMessageAt(Scanner::Location(position, start_pos), 3571 Scanner::Location location = Scanner::Location(position, start_pos);
3572 ReportMessageAt(location,
3550 "strict_function_name", Vector<const char*>::empty()); 3573 "strict_function_name", Vector<const char*>::empty());
3551 *ok = false; 3574 *ok = false;
3552 return NULL; 3575 return NULL;
3553 } 3576 }
3554 if (name_loc.IsValid()) { 3577 if (name_loc.IsValid()) {
3555 ReportMessageAt(name_loc, "strict_param_name", 3578 ReportMessageAt(name_loc, "strict_param_name",
3556 Vector<const char*>::empty()); 3579 Vector<const char*>::empty());
3557 *ok = false; 3580 *ok = false;
3558 return NULL; 3581 return NULL;
3559 } 3582 }
3560 if (dupe_loc.IsValid()) { 3583 if (dupe_loc.IsValid()) {
3561 ReportMessageAt(dupe_loc, "strict_param_dupe", 3584 ReportMessageAt(dupe_loc, "strict_param_dupe",
3562 Vector<const char*>::empty()); 3585 Vector<const char*>::empty());
3563 *ok = false; 3586 *ok = false;
3564 return NULL; 3587 return NULL;
3565 } 3588 }
3589 if (name_is_reserved) {
3590 int position = function_token_position != RelocInfo::kNoPosition
3591 ? function_token_position
3592 : (start_pos > 0 ? start_pos - 1 : start_pos);
3593 Scanner::Location location = Scanner::Location(position, start_pos);
3594 ReportMessageAt(location, "strict_reserved_word",
3595 Vector<const char*>::empty());
3596 *ok = false;
3597 return NULL;
3598 }
3599 if (reserved_loc.IsValid()) {
3600 ReportMessageAt(reserved_loc, "strict_reserved_word",
3601 Vector<const char*>::empty());
3602 *ok = false;
3603 return NULL;
3604 }
3566 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); 3605 CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
3567 } 3606 }
3568 3607
3569 FunctionLiteral* function_literal = 3608 FunctionLiteral* function_literal =
3570 new FunctionLiteral(name, 3609 new FunctionLiteral(name,
3571 top_scope_, 3610 top_scope_,
3572 body, 3611 body,
3573 materialized_literal_count, 3612 materialized_literal_count,
3574 expected_property_count, 3613 expected_property_count,
3575 only_simple_this_property_assignments, 3614 only_simple_this_property_assignments,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
3627 ReportMessage("illegal_access", Vector<const char*>::empty()); 3666 ReportMessage("illegal_access", Vector<const char*>::empty());
3628 *ok = false; 3667 *ok = false;
3629 return NULL; 3668 return NULL;
3630 } 3669 }
3631 3670
3632 // We have a valid intrinsics call or a call to a builtin. 3671 // We have a valid intrinsics call or a call to a builtin.
3633 return new CallRuntime(name, function, args); 3672 return new CallRuntime(name, function, args);
3634 } 3673 }
3635 3674
3636 3675
3676 bool Parser::peek_any_identifier() {
3677 Token::Value next = peek();
3678 return next == Token::IDENTIFIER ||
3679 next == Token::IDENTIFIER_OR_FUTURE_RESERVED_WORD;
3680 }
3681
3682
3637 void Parser::Consume(Token::Value token) { 3683 void Parser::Consume(Token::Value token) {
3638 Token::Value next = Next(); 3684 Token::Value next = Next();
3639 USE(next); 3685 USE(next);
3640 USE(token); 3686 USE(token);
3641 ASSERT(next == token); 3687 ASSERT(next == token);
3642 } 3688 }
3643 3689
3644 3690
3645 void Parser::Expect(Token::Value token, bool* ok) { 3691 void Parser::Expect(Token::Value token, bool* ok) {
3646 Token::Value next = Next(); 3692 Token::Value next = Next();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3686 return new Literal(Factory::the_hole_value()); 3732 return new Literal(Factory::the_hole_value());
3687 } 3733 }
3688 3734
3689 3735
3690 Literal* Parser::GetLiteralNumber(double value) { 3736 Literal* Parser::GetLiteralNumber(double value) {
3691 return NewNumberLiteral(value); 3737 return NewNumberLiteral(value);
3692 } 3738 }
3693 3739
3694 3740
3695 Handle<String> Parser::ParseIdentifier(bool* ok) { 3741 Handle<String> Parser::ParseIdentifier(bool* ok) {
3696 Expect(Token::IDENTIFIER, ok); 3742 bool is_reserved;
3743 return ParseIdentifierOrReservedWord(&is_reserved, ok);
3744 }
3745
3746
3747 Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved,
3748 bool* ok) {
3749 *is_reserved = false;
3750 if (temp_scope_->StrictMode()) {
3751 Expect(Token::IDENTIFIER, ok);
3752 } else {
3753 if (!Check(Token::IDENTIFIER)) {
3754 Expect(Token::IDENTIFIER_OR_FUTURE_RESERVED_WORD, ok);
3755 *is_reserved = true;
3756 }
3757 }
3697 if (!*ok) return Handle<String>(); 3758 if (!*ok) return Handle<String>();
3698 return GetSymbol(ok); 3759 return GetSymbol(ok);
3699 } 3760 }
3700 3761
3701 3762
3702 Handle<String> Parser::ParseIdentifierName(bool* ok) { 3763 Handle<String> Parser::ParseIdentifierName(bool* ok) {
3703 Token::Value next = Next(); 3764 Token::Value next = Next();
3704 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) { 3765 if (next != Token::IDENTIFIER &&
3766 next != Token::IDENTIFIER_OR_FUTURE_RESERVED_WORD &&
3767 !Token::IsKeyword(next)) {
Lasse Reichstein 2011/02/03 11:42:48 Maybe future reserved words should be considered k
3705 ReportUnexpectedToken(next); 3768 ReportUnexpectedToken(next);
3706 *ok = false; 3769 *ok = false;
3707 return Handle<String>(); 3770 return Handle<String>();
3708 } 3771 }
3709 return GetSymbol(ok); 3772 return GetSymbol(ok);
3710 } 3773 }
3711 3774
3712 3775
3713 // Checks LHS expression for assignment and prefix/postfix increment/decrement 3776 // Checks LHS expression for assignment and prefix/postfix increment/decrement
3714 // in strict mode. 3777 // in strict mode.
(...skipping 19 matching lines...) Expand all
3734 if (beg_pos <= octal && octal <= end_pos) { 3797 if (beg_pos <= octal && octal <= end_pos) {
3735 ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal", 3798 ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal",
3736 Vector<const char*>::empty()); 3799 Vector<const char*>::empty());
3737 scanner().clear_octal_position(); 3800 scanner().clear_octal_position();
3738 *ok = false; 3801 *ok = false;
3739 } 3802 }
3740 } 3803 }
3741 3804
3742 3805
3743 // This function reads an identifier and determines whether or not it 3806 // This function reads an identifier and determines whether or not it
3744 // is 'get' or 'set'. The reason for not using ParseIdentifier and 3807 // is 'get' or 'set'. The reason for not checking the result of
3745 // checking on the output is that this involves heap allocation which 3808 // ParseIdentifier is that this involves heap allocation which
3746 // we can't do during preparsing. 3809 // we can't do during preparsing.
Lasse Reichstein 2011/02/03 11:42:48 This code isn't used for preparsing any more, so t
Peter Hallam 2011/02/04 18:32:41 Done.
3747 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, 3810 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get,
3748 bool* is_set, 3811 bool* is_set,
3749 bool* ok) { 3812 bool* ok) {
3750 Expect(Token::IDENTIFIER, ok); 3813 Handle<String> result = ParseIdentifier(ok);
3751 if (!*ok) return Handle<String>(); 3814 if (!*ok) return Handle<String>();
3752 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { 3815 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
3753 const char* token = scanner().literal_ascii_string().start(); 3816 const char* token = scanner().literal_ascii_string().start();
3754 *is_get = strncmp(token, "get", 3) == 0; 3817 *is_get = strncmp(token, "get", 3) == 0;
3755 *is_set = !*is_get && strncmp(token, "set", 3) == 0; 3818 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
3756 } 3819 }
3757 return GetSymbol(ok); 3820 return result;
3758 } 3821 }
3759 3822
3760 3823
3761 // ---------------------------------------------------------------------------- 3824 // ----------------------------------------------------------------------------
3762 // Parser support 3825 // Parser support
3763 3826
3764 3827
3765 bool Parser::TargetStackContainsLabel(Handle<String> label) { 3828 bool Parser::TargetStackContainsLabel(Handle<String> label) {
3766 for (Target* t = target_stack_; t != NULL; t = t->previous()) { 3829 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3767 BreakableStatement* stat = t->node()->AsBreakableStatement(); 3830 BreakableStatement* stat = t->node()->AsBreakableStatement();
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
3889 case Token::EOS: 3952 case Token::EOS:
3890 message = "unexpected_eos"; 3953 message = "unexpected_eos";
3891 break; 3954 break;
3892 case Token::NUMBER: 3955 case Token::NUMBER:
3893 message = "unexpected_token_number"; 3956 message = "unexpected_token_number";
3894 break; 3957 break;
3895 case Token::STRING: 3958 case Token::STRING:
3896 message = "unexpected_token_string"; 3959 message = "unexpected_token_string";
3897 break; 3960 break;
3898 case Token::IDENTIFIER: 3961 case Token::IDENTIFIER:
3962 case Token::IDENTIFIER_OR_FUTURE_RESERVED_WORD:
3899 message = "unexpected_token_identifier"; 3963 message = "unexpected_token_identifier";
3900 break; 3964 break;
3901 default: 3965 default:
3902 message = "unexpected_token"; 3966 message = "unexpected_token";
3903 name_opt = Token::String(token); 3967 name_opt = Token::String(token);
3904 ASSERT(name_opt != NULL); 3968 ASSERT(name_opt != NULL);
3905 break; 3969 break;
3906 } 3970 }
3907 3971
3908 Scanner::Location source_location = scanner_.location(); 3972 Scanner::Location source_location = scanner_.location();
(...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after
5027 Handle<String> source = Handle<String>(String::cast(script->source())); 5091 Handle<String> source = Handle<String>(String::cast(script->source()));
5028 result = parser.ParseProgram(source, info->is_global()); 5092 result = parser.ParseProgram(source, info->is_global());
5029 } 5093 }
5030 } 5094 }
5031 5095
5032 info->SetFunction(result); 5096 info->SetFunction(result);
5033 return (result != NULL); 5097 return (result != NULL);
5034 } 5098 }
5035 5099
5036 } } // namespace v8::internal 5100 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/preparser.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698