Chromium Code Reviews| 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 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |