| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |