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

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: Address code review comments 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') | no next file with comments »
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 741 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 scope); 752 scope);
753 TemporaryScope temp_scope(&this->temp_scope_); 753 TemporaryScope temp_scope(&this->temp_scope_);
754 754
755 if (info->strict_mode()) { 755 if (info->strict_mode()) {
756 temp_scope.EnableStrictMode(); 756 temp_scope.EnableStrictMode();
757 } 757 }
758 758
759 FunctionLiteralType type = 759 FunctionLiteralType type =
760 info->is_expression() ? EXPRESSION : DECLARATION; 760 info->is_expression() ? EXPRESSION : DECLARATION;
761 bool ok = true; 761 bool ok = true;
762 result = ParseFunctionLiteral(name, RelocInfo::kNoPosition, type, &ok); 762 result = ParseFunctionLiteral(name,
763 false, // Strict mode name already checked.
764 RelocInfo::kNoPosition, type, &ok);
763 // Make sure the results agree. 765 // Make sure the results agree.
764 ASSERT(ok == (result != NULL)); 766 ASSERT(ok == (result != NULL));
765 // The only errors should be stack overflows. 767 // The only errors should be stack overflows.
766 ASSERT(ok || stack_overflow_); 768 ASSERT(ok || stack_overflow_);
767 } 769 }
768 770
769 // Make sure the target stack is empty. 771 // Make sure the target stack is empty.
770 ASSERT(target_stack_ == NULL); 772 ASSERT(target_stack_ == NULL);
771 773
772 // If there was a stack overflow we have to get rid of AST and it is 774 // 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
1441 return new ExpressionStatement( 1443 return new ExpressionStatement(
1442 new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition)); 1444 new Assignment(Token::INIT_VAR, var, lit, RelocInfo::kNoPosition));
1443 } 1445 }
1444 1446
1445 1447
1446 Statement* Parser::ParseFunctionDeclaration(bool* ok) { 1448 Statement* Parser::ParseFunctionDeclaration(bool* ok) {
1447 // FunctionDeclaration :: 1449 // FunctionDeclaration ::
1448 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 1450 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
1449 Expect(Token::FUNCTION, CHECK_OK); 1451 Expect(Token::FUNCTION, CHECK_OK);
1450 int function_token_position = scanner().location().beg_pos; 1452 int function_token_position = scanner().location().beg_pos;
1451 Handle<String> name = ParseIdentifier(CHECK_OK); 1453 bool is_reserved = false;
1454 Handle<String> name = ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
1452 FunctionLiteral* fun = ParseFunctionLiteral(name, 1455 FunctionLiteral* fun = ParseFunctionLiteral(name,
1456 is_reserved,
1453 function_token_position, 1457 function_token_position,
1454 DECLARATION, 1458 DECLARATION,
1455 CHECK_OK); 1459 CHECK_OK);
1456 // Even if we're not at the top-level of the global or a function 1460 // Even if we're not at the top-level of the global or a function
1457 // scope, we treat is as such and introduce the function with it's 1461 // scope, we treat is as such and introduce the function with it's
1458 // initial value upon entering the corresponding scope. 1462 // initial value upon entering the corresponding scope.
1459 Declare(name, Variable::VAR, fun, true, CHECK_OK); 1463 Declare(name, Variable::VAR, fun, true, CHECK_OK);
1460 return EmptyStatement(); 1464 return EmptyStatement();
1461 } 1465 }
1462 1466
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1701 1705
1702 return false; 1706 return false;
1703 } 1707 }
1704 1708
1705 1709
1706 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels, 1710 Statement* Parser::ParseExpressionOrLabelledStatement(ZoneStringList* labels,
1707 bool* ok) { 1711 bool* ok) {
1708 // ExpressionStatement | LabelledStatement :: 1712 // ExpressionStatement | LabelledStatement ::
1709 // Expression ';' 1713 // Expression ';'
1710 // Identifier ':' Statement 1714 // Identifier ':' Statement
1711 bool starts_with_idenfifier = (peek() == Token::IDENTIFIER); 1715 bool starts_with_idenfifier = peek_any_identifier();
1712 Expression* expr = ParseExpression(true, CHECK_OK); 1716 Expression* expr = ParseExpression(true, CHECK_OK);
1713 if (peek() == Token::COLON && starts_with_idenfifier && expr && 1717 if (peek() == Token::COLON && starts_with_idenfifier && expr &&
1714 expr->AsVariableProxy() != NULL && 1718 expr->AsVariableProxy() != NULL &&
1715 !expr->AsVariableProxy()->is_this()) { 1719 !expr->AsVariableProxy()->is_this()) {
1716 // Expression is a single identifier, and not, e.g., a parenthesized 1720 // Expression is a single identifier, and not, e.g., a parenthesized
1717 // identifier. 1721 // identifier.
1718 VariableProxy* var = expr->AsVariableProxy(); 1722 VariableProxy* var = expr->AsVariableProxy();
1719 Handle<String> label = var->name(); 1723 Handle<String> label = var->name();
1720 // TODO(1240780): We don't check for redeclaration of labels 1724 // TODO(1240780): We don't check for redeclaration of labels
1721 // during preparsing since keeping track of the set of active 1725 // during preparsing since keeping track of the set of active
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after
2690 // MemberExpression :: 2694 // MemberExpression ::
2691 // (PrimaryExpression | FunctionLiteral) 2695 // (PrimaryExpression | FunctionLiteral)
2692 // ('[' Expression ']' | '.' Identifier | Arguments)* 2696 // ('[' Expression ']' | '.' Identifier | Arguments)*
2693 2697
2694 // Parse the initial primary or function expression. 2698 // Parse the initial primary or function expression.
2695 Expression* result = NULL; 2699 Expression* result = NULL;
2696 if (peek() == Token::FUNCTION) { 2700 if (peek() == Token::FUNCTION) {
2697 Expect(Token::FUNCTION, CHECK_OK); 2701 Expect(Token::FUNCTION, CHECK_OK);
2698 int function_token_position = scanner().location().beg_pos; 2702 int function_token_position = scanner().location().beg_pos;
2699 Handle<String> name; 2703 Handle<String> name;
2700 if (peek() == Token::IDENTIFIER) name = ParseIdentifier(CHECK_OK); 2704 bool is_reserved_name = false;
2701 result = ParseFunctionLiteral(name, function_token_position, 2705 if (peek_any_identifier()) {
2702 NESTED, CHECK_OK); 2706 name = ParseIdentifierOrReservedWord(&is_reserved_name, CHECK_OK);
2707 }
2708 result = ParseFunctionLiteral(name, is_reserved_name,
2709 function_token_position, NESTED, CHECK_OK);
2703 } else { 2710 } else {
2704 result = ParsePrimaryExpression(CHECK_OK); 2711 result = ParsePrimaryExpression(CHECK_OK);
2705 } 2712 }
2706 2713
2707 while (true) { 2714 while (true) {
2708 switch (peek()) { 2715 switch (peek()) {
2709 case Token::LBRACK: { 2716 case Token::LBRACK: {
2710 Consume(Token::LBRACK); 2717 Consume(Token::LBRACK);
2711 int pos = scanner().location().beg_pos; 2718 int pos = scanner().location().beg_pos;
2712 Expression* index = ParseExpression(true, CHECK_OK); 2719 Expression* index = ParseExpression(true, CHECK_OK);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2761 return ReportMessage("unexpected_eos", Vector<const char*>::empty()); 2768 return ReportMessage("unexpected_eos", Vector<const char*>::empty());
2762 case Token::NUMBER: 2769 case Token::NUMBER:
2763 return ReportMessage("unexpected_token_number", 2770 return ReportMessage("unexpected_token_number",
2764 Vector<const char*>::empty()); 2771 Vector<const char*>::empty());
2765 case Token::STRING: 2772 case Token::STRING:
2766 return ReportMessage("unexpected_token_string", 2773 return ReportMessage("unexpected_token_string",
2767 Vector<const char*>::empty()); 2774 Vector<const char*>::empty());
2768 case Token::IDENTIFIER: 2775 case Token::IDENTIFIER:
2769 return ReportMessage("unexpected_token_identifier", 2776 return ReportMessage("unexpected_token_identifier",
2770 Vector<const char*>::empty()); 2777 Vector<const char*>::empty());
2778 case Token::FUTURE_RESERVED_WORD:
2779 return ReportMessage(temp_scope_->StrictMode() ?
2780 "unexpected_strict_reserved" :
2781 "unexpected_token_identifier",
2782 Vector<const char*>::empty());
2771 default: 2783 default:
2772 const char* name = Token::String(token); 2784 const char* name = Token::String(token);
2773 ASSERT(name != NULL); 2785 ASSERT(name != NULL);
2774 ReportMessage("unexpected_token", Vector<const char*>(&name, 1)); 2786 ReportMessage("unexpected_token", Vector<const char*>(&name, 1));
2775 } 2787 }
2776 } 2788 }
2777 2789
2778 2790
2779 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { 2791 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
2780 SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS); 2792 SmartPointer<char> name_string = name->ToCString(DISALLOW_NULLS);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
2816 case Token::TRUE_LITERAL: 2828 case Token::TRUE_LITERAL:
2817 Consume(Token::TRUE_LITERAL); 2829 Consume(Token::TRUE_LITERAL);
2818 result = new Literal(Factory::true_value()); 2830 result = new Literal(Factory::true_value());
2819 break; 2831 break;
2820 2832
2821 case Token::FALSE_LITERAL: 2833 case Token::FALSE_LITERAL:
2822 Consume(Token::FALSE_LITERAL); 2834 Consume(Token::FALSE_LITERAL);
2823 result = new Literal(Factory::false_value()); 2835 result = new Literal(Factory::false_value());
2824 break; 2836 break;
2825 2837
2826 case Token::IDENTIFIER: { 2838 case Token::IDENTIFIER:
2839 case Token::FUTURE_RESERVED_WORD: {
2827 Handle<String> name = ParseIdentifier(CHECK_OK); 2840 Handle<String> name = ParseIdentifier(CHECK_OK);
2828 if (fni_ != NULL) fni_->PushVariableName(name); 2841 if (fni_ != NULL) fni_->PushVariableName(name);
2829 result = top_scope_->NewUnresolved(name, inside_with()); 2842 result = top_scope_->NewUnresolved(name, inside_with());
2830 break; 2843 break;
2831 } 2844 }
2832 2845
2833 case Token::NUMBER: { 2846 case Token::NUMBER: {
2834 Consume(Token::NUMBER); 2847 Consume(Token::NUMBER);
2835 ASSERT(scanner().is_literal_ascii()); 2848 ASSERT(scanner().is_literal_ascii());
2836 double value = StringToDouble(scanner().literal_ascii_string(), 2849 double value = StringToDouble(scanner().literal_ascii_string(),
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
3223 3236
3224 3237
3225 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, 3238 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter,
3226 bool* ok) { 3239 bool* ok) {
3227 // Special handling of getter and setter syntax: 3240 // Special handling of getter and setter syntax:
3228 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } 3241 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
3229 // We have already read the "get" or "set" keyword. 3242 // We have already read the "get" or "set" keyword.
3230 Token::Value next = Next(); 3243 Token::Value next = Next();
3231 bool is_keyword = Token::IsKeyword(next); 3244 bool is_keyword = Token::IsKeyword(next);
3232 if (next == Token::IDENTIFIER || next == Token::NUMBER || 3245 if (next == Token::IDENTIFIER || next == Token::NUMBER ||
3246 next == Token::FUTURE_RESERVED_WORD ||
3233 next == Token::STRING || is_keyword) { 3247 next == Token::STRING || is_keyword) {
3234 Handle<String> name; 3248 Handle<String> name;
3235 if (is_keyword) { 3249 if (is_keyword) {
3236 name = Factory::LookupAsciiSymbol(Token::String(next)); 3250 name = Factory::LookupAsciiSymbol(Token::String(next));
3237 } else { 3251 } else {
3238 name = GetSymbol(CHECK_OK); 3252 name = GetSymbol(CHECK_OK);
3239 } 3253 }
3240 FunctionLiteral* value = 3254 FunctionLiteral* value =
3241 ParseFunctionLiteral(name, 3255 ParseFunctionLiteral(name,
3256 false, // reserved words are allowed here
3242 RelocInfo::kNoPosition, 3257 RelocInfo::kNoPosition,
3243 DECLARATION, 3258 DECLARATION,
3244 CHECK_OK); 3259 CHECK_OK);
3245 // Allow any number of parameters for compatiabilty with JSC. 3260 // Allow any number of parameters for compatiabilty with JSC.
3246 // Specification only allows zero parameters for get and one for set. 3261 // Specification only allows zero parameters for get and one for set.
3247 ObjectLiteral::Property* property = 3262 ObjectLiteral::Property* property =
3248 new ObjectLiteral::Property(is_getter, value); 3263 new ObjectLiteral::Property(is_getter, value);
3249 return property; 3264 return property;
3250 } else { 3265 } else {
3251 ReportUnexpectedToken(next); 3266 ReportUnexpectedToken(next);
(...skipping 22 matching lines...) Expand all
3274 while (peek() != Token::RBRACE) { 3289 while (peek() != Token::RBRACE) {
3275 if (fni_ != NULL) fni_->Enter(); 3290 if (fni_ != NULL) fni_->Enter();
3276 3291
3277 Literal* key = NULL; 3292 Literal* key = NULL;
3278 Token::Value next = peek(); 3293 Token::Value next = peek();
3279 3294
3280 // Location of the property name token 3295 // Location of the property name token
3281 Scanner::Location loc = scanner().peek_location(); 3296 Scanner::Location loc = scanner().peek_location();
3282 3297
3283 switch (next) { 3298 switch (next) {
3299 case Token::FUTURE_RESERVED_WORD:
3284 case Token::IDENTIFIER: { 3300 case Token::IDENTIFIER: {
3285 bool is_getter = false; 3301 bool is_getter = false;
3286 bool is_setter = false; 3302 bool is_setter = false;
3287 Handle<String> id = 3303 Handle<String> id =
3288 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); 3304 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
3289 if (fni_ != NULL) fni_->PushLiteralName(id); 3305 if (fni_ != NULL) fni_->PushLiteralName(id);
3290 3306
3291 if ((is_getter || is_setter) && peek() != Token::COLON) { 3307 if ((is_getter || is_setter) && peek() != Token::COLON) {
3292 // Update loc to point to the identifier 3308 // Update loc to point to the identifier
3293 loc = scanner().peek_location(); 3309 loc = scanner().peek_location();
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
3422 result->Add(argument); 3438 result->Add(argument);
3423 done = (peek() == Token::RPAREN); 3439 done = (peek() == Token::RPAREN);
3424 if (!done) Expect(Token::COMMA, CHECK_OK); 3440 if (!done) Expect(Token::COMMA, CHECK_OK);
3425 } 3441 }
3426 Expect(Token::RPAREN, CHECK_OK); 3442 Expect(Token::RPAREN, CHECK_OK);
3427 return result; 3443 return result;
3428 } 3444 }
3429 3445
3430 3446
3431 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name, 3447 FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
3448 bool name_is_reserved,
3432 int function_token_position, 3449 int function_token_position,
3433 FunctionLiteralType type, 3450 FunctionLiteralType type,
3434 bool* ok) { 3451 bool* ok) {
3435 // Function :: 3452 // Function ::
3436 // '(' FormalParameterList? ')' '{' FunctionBody '}' 3453 // '(' FormalParameterList? ')' '{' FunctionBody '}'
3437 bool is_named = !var_name.is_null(); 3454 bool is_named = !var_name.is_null();
3438 3455
3439 // The name associated with this function. If it's a function expression, 3456 // The name associated with this function. If it's a function expression,
3440 // this is the actual function name, otherwise this is the name of the 3457 // this is the actual function name, otherwise this is the name of the
3441 // variable declared and initialized with the function (expression). In 3458 // variable declared and initialized with the function (expression). In
(...skipping 13 matching lines...) Expand all
3455 scope); 3472 scope);
3456 TemporaryScope temp_scope(&this->temp_scope_); 3473 TemporaryScope temp_scope(&this->temp_scope_);
3457 top_scope_->SetScopeName(name); 3474 top_scope_->SetScopeName(name);
3458 3475
3459 // FormalParameterList :: 3476 // FormalParameterList ::
3460 // '(' (Identifier)*[','] ')' 3477 // '(' (Identifier)*[','] ')'
3461 Expect(Token::LPAREN, CHECK_OK); 3478 Expect(Token::LPAREN, CHECK_OK);
3462 int start_pos = scanner().location().beg_pos; 3479 int start_pos = scanner().location().beg_pos;
3463 Scanner::Location name_loc = Scanner::NoLocation(); 3480 Scanner::Location name_loc = Scanner::NoLocation();
3464 Scanner::Location dupe_loc = Scanner::NoLocation(); 3481 Scanner::Location dupe_loc = Scanner::NoLocation();
3482 Scanner::Location reserved_loc = Scanner::NoLocation();
3465 3483
3466 bool done = (peek() == Token::RPAREN); 3484 bool done = (peek() == Token::RPAREN);
3467 while (!done) { 3485 while (!done) {
3468 Handle<String> param_name = ParseIdentifier(CHECK_OK); 3486 bool is_reserved = false;
3487 Handle<String> param_name =
3488 ParseIdentifierOrReservedWord(&is_reserved, CHECK_OK);
3469 3489
3470 // Store locations for possible future error reports. 3490 // Store locations for possible future error reports.
3471 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) { 3491 if (!name_loc.IsValid() && IsEvalOrArguments(param_name)) {
3472 name_loc = scanner().location(); 3492 name_loc = scanner().location();
3473 } 3493 }
3474 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) { 3494 if (!dupe_loc.IsValid() && top_scope_->IsDeclared(param_name)) {
3475 dupe_loc = scanner().location(); 3495 dupe_loc = scanner().location();
3476 } 3496 }
3497 if (!reserved_loc.IsValid() && is_reserved) {
3498 reserved_loc = scanner().location();
3499 }
3477 3500
3478 Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR); 3501 Variable* parameter = top_scope_->DeclareLocal(param_name, Variable::VAR);
3479 top_scope_->AddParameter(parameter); 3502 top_scope_->AddParameter(parameter);
3480 num_parameters++; 3503 num_parameters++;
3481 done = (peek() == Token::RPAREN); 3504 done = (peek() == Token::RPAREN);
3482 if (!done) Expect(Token::COMMA, CHECK_OK); 3505 if (!done) Expect(Token::COMMA, CHECK_OK);
3483 } 3506 }
3484 Expect(Token::RPAREN, CHECK_OK); 3507 Expect(Token::RPAREN, CHECK_OK);
3485 3508
3486 Expect(Token::LBRACE, CHECK_OK); 3509 Expect(Token::LBRACE, CHECK_OK);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
3547 Expect(Token::RBRACE, CHECK_OK); 3570 Expect(Token::RBRACE, CHECK_OK);
3548 end_pos = scanner().location().end_pos; 3571 end_pos = scanner().location().end_pos;
3549 } 3572 }
3550 3573
3551 // Validate strict mode. 3574 // Validate strict mode.
3552 if (temp_scope_->StrictMode()) { 3575 if (temp_scope_->StrictMode()) {
3553 if (IsEvalOrArguments(name)) { 3576 if (IsEvalOrArguments(name)) {
3554 int position = function_token_position != RelocInfo::kNoPosition 3577 int position = function_token_position != RelocInfo::kNoPosition
3555 ? function_token_position 3578 ? function_token_position
3556 : (start_pos > 0 ? start_pos - 1 : start_pos); 3579 : (start_pos > 0 ? start_pos - 1 : start_pos);
3557 ReportMessageAt(Scanner::Location(position, start_pos), 3580 Scanner::Location location = Scanner::Location(position, start_pos);
3581 ReportMessageAt(location,
3558 "strict_function_name", Vector<const char*>::empty()); 3582 "strict_function_name", Vector<const char*>::empty());
3559 *ok = false; 3583 *ok = false;
3560 return NULL; 3584 return NULL;
3561 } 3585 }
3562 if (name_loc.IsValid()) { 3586 if (name_loc.IsValid()) {
3563 ReportMessageAt(name_loc, "strict_param_name", 3587 ReportMessageAt(name_loc, "strict_param_name",
3564 Vector<const char*>::empty()); 3588 Vector<const char*>::empty());
3565 *ok = false; 3589 *ok = false;
3566 return NULL; 3590 return NULL;
3567 } 3591 }
3568 if (dupe_loc.IsValid()) { 3592 if (dupe_loc.IsValid()) {
3569 ReportMessageAt(dupe_loc, "strict_param_dupe", 3593 ReportMessageAt(dupe_loc, "strict_param_dupe",
3570 Vector<const char*>::empty()); 3594 Vector<const char*>::empty());
3571 *ok = false; 3595 *ok = false;
3572 return NULL; 3596 return NULL;
3573 } 3597 }
3598 if (name_is_reserved) {
3599 int position = function_token_position != RelocInfo::kNoPosition
3600 ? function_token_position
3601 : (start_pos > 0 ? start_pos - 1 : start_pos);
3602 Scanner::Location location = Scanner::Location(position, start_pos);
3603 ReportMessageAt(location, "strict_reserved_word",
3604 Vector<const char*>::empty());
3605 *ok = false;
3606 return NULL;
3607 }
3608 if (reserved_loc.IsValid()) {
3609 ReportMessageAt(reserved_loc, "strict_reserved_word",
3610 Vector<const char*>::empty());
3611 *ok = false;
3612 return NULL;
3613 }
3574 CheckOctalLiteral(start_pos, end_pos, CHECK_OK); 3614 CheckOctalLiteral(start_pos, end_pos, CHECK_OK);
3575 } 3615 }
3576 3616
3577 FunctionLiteral* function_literal = 3617 FunctionLiteral* function_literal =
3578 new FunctionLiteral(name, 3618 new FunctionLiteral(name,
3579 top_scope_, 3619 top_scope_,
3580 body, 3620 body,
3581 materialized_literal_count, 3621 materialized_literal_count,
3582 expected_property_count, 3622 expected_property_count,
3583 only_simple_this_property_assignments, 3623 only_simple_this_property_assignments,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
3635 ReportMessage("illegal_access", Vector<const char*>::empty()); 3675 ReportMessage("illegal_access", Vector<const char*>::empty());
3636 *ok = false; 3676 *ok = false;
3637 return NULL; 3677 return NULL;
3638 } 3678 }
3639 3679
3640 // We have a valid intrinsics call or a call to a builtin. 3680 // We have a valid intrinsics call or a call to a builtin.
3641 return new CallRuntime(name, function, args); 3681 return new CallRuntime(name, function, args);
3642 } 3682 }
3643 3683
3644 3684
3685 bool Parser::peek_any_identifier() {
3686 Token::Value next = peek();
3687 return next == Token::IDENTIFIER ||
3688 next == Token::FUTURE_RESERVED_WORD;
3689 }
3690
3691
3645 void Parser::Consume(Token::Value token) { 3692 void Parser::Consume(Token::Value token) {
3646 Token::Value next = Next(); 3693 Token::Value next = Next();
3647 USE(next); 3694 USE(next);
3648 USE(token); 3695 USE(token);
3649 ASSERT(next == token); 3696 ASSERT(next == token);
3650 } 3697 }
3651 3698
3652 3699
3653 void Parser::Expect(Token::Value token, bool* ok) { 3700 void Parser::Expect(Token::Value token, bool* ok) {
3654 Token::Value next = Next(); 3701 Token::Value next = Next();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
3694 return new Literal(Factory::the_hole_value()); 3741 return new Literal(Factory::the_hole_value());
3695 } 3742 }
3696 3743
3697 3744
3698 Literal* Parser::GetLiteralNumber(double value) { 3745 Literal* Parser::GetLiteralNumber(double value) {
3699 return NewNumberLiteral(value); 3746 return NewNumberLiteral(value);
3700 } 3747 }
3701 3748
3702 3749
3703 Handle<String> Parser::ParseIdentifier(bool* ok) { 3750 Handle<String> Parser::ParseIdentifier(bool* ok) {
3704 Expect(Token::IDENTIFIER, ok); 3751 bool is_reserved;
3752 return ParseIdentifierOrReservedWord(&is_reserved, ok);
3753 }
3754
3755
3756 Handle<String> Parser::ParseIdentifierOrReservedWord(bool* is_reserved,
3757 bool* ok) {
3758 *is_reserved = false;
3759 if (temp_scope_->StrictMode()) {
3760 Expect(Token::IDENTIFIER, ok);
3761 } else {
3762 if (!Check(Token::IDENTIFIER)) {
3763 Expect(Token::FUTURE_RESERVED_WORD, ok);
3764 *is_reserved = true;
3765 }
3766 }
3705 if (!*ok) return Handle<String>(); 3767 if (!*ok) return Handle<String>();
3706 return GetSymbol(ok); 3768 return GetSymbol(ok);
3707 } 3769 }
3708 3770
3709 3771
3710 Handle<String> Parser::ParseIdentifierName(bool* ok) { 3772 Handle<String> Parser::ParseIdentifierName(bool* ok) {
3711 Token::Value next = Next(); 3773 Token::Value next = Next();
3712 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) { 3774 if (next != Token::IDENTIFIER &&
3775 next != Token::FUTURE_RESERVED_WORD &&
3776 !Token::IsKeyword(next)) {
3713 ReportUnexpectedToken(next); 3777 ReportUnexpectedToken(next);
3714 *ok = false; 3778 *ok = false;
3715 return Handle<String>(); 3779 return Handle<String>();
3716 } 3780 }
3717 return GetSymbol(ok); 3781 return GetSymbol(ok);
3718 } 3782 }
3719 3783
3720 3784
3721 // Checks LHS expression for assignment and prefix/postfix increment/decrement 3785 // Checks LHS expression for assignment and prefix/postfix increment/decrement
3722 // in strict mode. 3786 // in strict mode.
(...skipping 19 matching lines...) Expand all
3742 if (beg_pos <= octal && octal <= end_pos) { 3806 if (beg_pos <= octal && octal <= end_pos) {
3743 ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal", 3807 ReportMessageAt(Scanner::Location(octal, octal + 1), "strict_octal_literal",
3744 Vector<const char*>::empty()); 3808 Vector<const char*>::empty());
3745 scanner().clear_octal_position(); 3809 scanner().clear_octal_position();
3746 *ok = false; 3810 *ok = false;
3747 } 3811 }
3748 } 3812 }
3749 3813
3750 3814
3751 // This function reads an identifier and determines whether or not it 3815 // This function reads an identifier and determines whether or not it
3752 // is 'get' or 'set'. The reason for not using ParseIdentifier and 3816 // is 'get' or 'set'.
3753 // checking on the output is that this involves heap allocation which
3754 // we can't do during preparsing.
3755 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, 3817 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get,
3756 bool* is_set, 3818 bool* is_set,
3757 bool* ok) { 3819 bool* ok) {
3758 Expect(Token::IDENTIFIER, ok); 3820 Handle<String> result = ParseIdentifier(ok);
3759 if (!*ok) return Handle<String>(); 3821 if (!*ok) return Handle<String>();
3760 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) { 3822 if (scanner().is_literal_ascii() && scanner().literal_length() == 3) {
3761 const char* token = scanner().literal_ascii_string().start(); 3823 const char* token = scanner().literal_ascii_string().start();
3762 *is_get = strncmp(token, "get", 3) == 0; 3824 *is_get = strncmp(token, "get", 3) == 0;
3763 *is_set = !*is_get && strncmp(token, "set", 3) == 0; 3825 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
3764 } 3826 }
3765 return GetSymbol(ok); 3827 return result;
3766 } 3828 }
3767 3829
3768 3830
3769 // ---------------------------------------------------------------------------- 3831 // ----------------------------------------------------------------------------
3770 // Parser support 3832 // Parser support
3771 3833
3772 3834
3773 bool Parser::TargetStackContainsLabel(Handle<String> label) { 3835 bool Parser::TargetStackContainsLabel(Handle<String> label) {
3774 for (Target* t = target_stack_; t != NULL; t = t->previous()) { 3836 for (Target* t = target_stack_; t != NULL; t = t->previous()) {
3775 BreakableStatement* stat = t->node()->AsBreakableStatement(); 3837 BreakableStatement* stat = t->node()->AsBreakableStatement();
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
3897 case Token::EOS: 3959 case Token::EOS:
3898 message = "unexpected_eos"; 3960 message = "unexpected_eos";
3899 break; 3961 break;
3900 case Token::NUMBER: 3962 case Token::NUMBER:
3901 message = "unexpected_token_number"; 3963 message = "unexpected_token_number";
3902 break; 3964 break;
3903 case Token::STRING: 3965 case Token::STRING:
3904 message = "unexpected_token_string"; 3966 message = "unexpected_token_string";
3905 break; 3967 break;
3906 case Token::IDENTIFIER: 3968 case Token::IDENTIFIER:
3969 case Token::FUTURE_RESERVED_WORD:
3907 message = "unexpected_token_identifier"; 3970 message = "unexpected_token_identifier";
3908 break; 3971 break;
3909 default: 3972 default:
3910 message = "unexpected_token"; 3973 message = "unexpected_token";
3911 name_opt = Token::String(token); 3974 name_opt = Token::String(token);
3912 ASSERT(name_opt != NULL); 3975 ASSERT(name_opt != NULL);
3913 break; 3976 break;
3914 } 3977 }
3915 3978
3916 Scanner::Location source_location = scanner_.location(); 3979 Scanner::Location source_location = scanner_.location();
(...skipping 1120 matching lines...) Expand 10 before | Expand all | Expand 10 after
5037 info->is_global(), 5100 info->is_global(),
5038 info->StrictMode()); 5101 info->StrictMode());
5039 } 5102 }
5040 } 5103 }
5041 5104
5042 info->SetFunction(result); 5105 info->SetFunction(result);
5043 return (result != NULL); 5106 return (result != NULL);
5044 } 5107 }
5045 5108
5046 } } // namespace v8::internal 5109 } } // 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