| 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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 258 void Expect(Token::Value token, bool* ok); | 258 void Expect(Token::Value token, bool* ok); |
| 259 bool Check(Token::Value token); | 259 bool Check(Token::Value token); |
| 260 void ExpectSemicolon(bool* ok); | 260 void ExpectSemicolon(bool* ok); |
| 261 | 261 |
| 262 // Get odd-ball literals. | 262 // Get odd-ball literals. |
| 263 Literal* GetLiteralUndefined(); | 263 Literal* GetLiteralUndefined(); |
| 264 Literal* GetLiteralTheHole(); | 264 Literal* GetLiteralTheHole(); |
| 265 Literal* GetLiteralNumber(double value); | 265 Literal* GetLiteralNumber(double value); |
| 266 | 266 |
| 267 Handle<String> ParseIdentifier(bool* ok); | 267 Handle<String> ParseIdentifier(bool* ok); |
| 268 Handle<String> ParseIdentifierName(bool* ok); |
| 268 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get, | 269 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get, |
| 269 bool* is_set, | 270 bool* is_set, |
| 270 bool* ok); | 271 bool* ok); |
| 271 | 272 |
| 272 // Parser support | 273 // Parser support |
| 273 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, | 274 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, |
| 274 FunctionLiteral* fun, | 275 FunctionLiteral* fun, |
| 275 bool resolve, | 276 bool resolve, |
| 276 bool* ok) = 0; | 277 bool* ok) = 0; |
| 277 | 278 |
| (...skipping 2836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3114 } | 3115 } |
| 3115 } | 3116 } |
| 3116 } | 3117 } |
| 3117 result = factory()->NewCall(result, args, pos); | 3118 result = factory()->NewCall(result, args, pos); |
| 3118 break; | 3119 break; |
| 3119 } | 3120 } |
| 3120 | 3121 |
| 3121 case Token::PERIOD: { | 3122 case Token::PERIOD: { |
| 3122 Consume(Token::PERIOD); | 3123 Consume(Token::PERIOD); |
| 3123 int pos = scanner().location().beg_pos; | 3124 int pos = scanner().location().beg_pos; |
| 3124 Handle<String> name = ParseIdentifier(CHECK_OK); | 3125 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 3125 result = factory()->NewProperty(result, NEW(Literal(name)), pos); | 3126 result = factory()->NewProperty(result, NEW(Literal(name)), pos); |
| 3126 break; | 3127 break; |
| 3127 } | 3128 } |
| 3128 | 3129 |
| 3129 default: | 3130 default: |
| 3130 return result; | 3131 return result; |
| 3131 } | 3132 } |
| 3132 } | 3133 } |
| 3133 } | 3134 } |
| 3134 | 3135 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3200 Consume(Token::LBRACK); | 3201 Consume(Token::LBRACK); |
| 3201 int pos = scanner().location().beg_pos; | 3202 int pos = scanner().location().beg_pos; |
| 3202 Expression* index = ParseExpression(true, CHECK_OK); | 3203 Expression* index = ParseExpression(true, CHECK_OK); |
| 3203 result = factory()->NewProperty(result, index, pos); | 3204 result = factory()->NewProperty(result, index, pos); |
| 3204 Expect(Token::RBRACK, CHECK_OK); | 3205 Expect(Token::RBRACK, CHECK_OK); |
| 3205 break; | 3206 break; |
| 3206 } | 3207 } |
| 3207 case Token::PERIOD: { | 3208 case Token::PERIOD: { |
| 3208 Consume(Token::PERIOD); | 3209 Consume(Token::PERIOD); |
| 3209 int pos = scanner().location().beg_pos; | 3210 int pos = scanner().location().beg_pos; |
| 3210 Handle<String> name = ParseIdentifier(CHECK_OK); | 3211 Handle<String> name = ParseIdentifierName(CHECK_OK); |
| 3211 result = factory()->NewProperty(result, NEW(Literal(name)), pos); | 3212 result = factory()->NewProperty(result, NEW(Literal(name)), pos); |
| 3212 break; | 3213 break; |
| 3213 } | 3214 } |
| 3214 case Token::LPAREN: { | 3215 case Token::LPAREN: { |
| 3215 if ((stack == NULL) || stack->is_empty()) return result; | 3216 if ((stack == NULL) || stack->is_empty()) return result; |
| 3216 // Consume one of the new prefixes (already parsed). | 3217 // Consume one of the new prefixes (already parsed). |
| 3217 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | 3218 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); |
| 3218 int last = stack->pop(); | 3219 int last = stack->pop(); |
| 3219 result = NEW(CallNew(result, args, last)); | 3220 result = NEW(CallNew(result, args, last)); |
| 3220 break; | 3221 break; |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3579 *fast_elements = | 3580 *fast_elements = |
| 3580 (max_element_index <= 32) || ((2 * elements) >= max_element_index); | 3581 (max_element_index <= 32) || ((2 * elements) >= max_element_index); |
| 3581 *is_simple = is_simple_acc; | 3582 *is_simple = is_simple_acc; |
| 3582 *depth = depth_acc; | 3583 *depth = depth_acc; |
| 3583 } | 3584 } |
| 3584 | 3585 |
| 3585 | 3586 |
| 3586 Expression* Parser::ParseObjectLiteral(bool* ok) { | 3587 Expression* Parser::ParseObjectLiteral(bool* ok) { |
| 3587 // ObjectLiteral :: | 3588 // ObjectLiteral :: |
| 3588 // '{' ( | 3589 // '{' ( |
| 3589 // ((Identifier | String | Number) ':' AssignmentExpression) | 3590 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
| 3590 // | (('get' | 'set') FunctionLiteral) | 3591 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
| 3591 // )*[','] '}' | 3592 // )*[','] '}' |
| 3592 | 3593 |
| 3593 ZoneListWrapper<ObjectLiteral::Property> properties = | 3594 ZoneListWrapper<ObjectLiteral::Property> properties = |
| 3594 factory()->NewList<ObjectLiteral::Property>(4); | 3595 factory()->NewList<ObjectLiteral::Property>(4); |
| 3595 int number_of_boilerplate_properties = 0; | 3596 int number_of_boilerplate_properties = 0; |
| 3596 | 3597 |
| 3597 Expect(Token::LBRACE, CHECK_OK); | 3598 Expect(Token::LBRACE, CHECK_OK); |
| 3598 while (peek() != Token::RBRACE) { | 3599 while (peek() != Token::RBRACE) { |
| 3599 Literal* key = NULL; | 3600 Literal* key = NULL; |
| 3600 switch (peek()) { | 3601 Token::Value next = peek(); |
| 3602 switch (next) { |
| 3601 case Token::IDENTIFIER: { | 3603 case Token::IDENTIFIER: { |
| 3602 // Store identifier keys as literal symbols to avoid | 3604 // Store identifier keys as literal symbols to avoid |
| 3603 // resolving them when compiling code for the object | 3605 // resolving them when compiling code for the object |
| 3604 // literal. | 3606 // literal. |
| 3605 bool is_getter = false; | 3607 bool is_getter = false; |
| 3606 bool is_setter = false; | 3608 bool is_setter = false; |
| 3607 Handle<String> id = | 3609 Handle<String> id = |
| 3608 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 3610 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
| 3609 if (is_getter || is_setter) { | 3611 if (is_getter || is_setter) { |
| 3610 // Special handling of getter and setter syntax. | 3612 // Special handling of getter and setter syntax. |
| 3611 if (peek() == Token::IDENTIFIER) { | 3613 Handle<String> name; |
| 3612 Handle<String> name = ParseIdentifier(CHECK_OK); | 3614 next = peek(); |
| 3615 if (next == Token::IDENTIFIER || |
| 3616 next == Token::STRING || |
| 3617 next == Token::NUMBER || |
| 3618 Token::IsKeyword(next)) { |
| 3619 Consume(next); |
| 3620 Handle<String> name = |
| 3621 factory()->LookupSymbol(scanner_.literal_string(), |
| 3622 scanner_.literal_length()); |
| 3613 FunctionLiteral* value = | 3623 FunctionLiteral* value = |
| 3614 ParseFunctionLiteral(name, RelocInfo::kNoPosition, | 3624 ParseFunctionLiteral(name, |
| 3615 DECLARATION, CHECK_OK); | 3625 RelocInfo::kNoPosition, |
| 3626 DECLARATION, |
| 3627 CHECK_OK); |
| 3616 ObjectLiteral::Property* property = | 3628 ObjectLiteral::Property* property = |
| 3617 NEW(ObjectLiteral::Property(is_getter, value)); | 3629 NEW(ObjectLiteral::Property(is_getter, value)); |
| 3618 if (IsBoilerplateProperty(property)) | 3630 if (IsBoilerplateProperty(property)) { |
| 3619 number_of_boilerplate_properties++; | 3631 number_of_boilerplate_properties++; |
| 3632 } |
| 3620 properties.Add(property); | 3633 properties.Add(property); |
| 3621 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3634 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
| 3622 continue; // restart the while | 3635 continue; // restart the while |
| 3623 } | 3636 } |
| 3624 } | 3637 } |
| 3625 key = NEW(Literal(id)); | 3638 key = NEW(Literal(id)); |
| 3626 break; | 3639 break; |
| 3627 } | 3640 } |
| 3628 | 3641 #define CASE_KEYWORD(name, ignore1, ignore2) \ |
| 3642 case Token::name: |
| 3643 TOKEN_LIST(IGNORE_TOKEN, CASE_KEYWORD, IGNORE_TOKEN) |
| 3644 #undef CASE_KEYWORD |
| 3645 // FALLTHROUGH - keyword tokens fall through to the same code as strings. |
| 3629 case Token::STRING: { | 3646 case Token::STRING: { |
| 3630 Consume(Token::STRING); | 3647 Consume(next); |
| 3631 Handle<String> string = | 3648 Handle<String> string = |
| 3632 factory()->LookupSymbol(scanner_.literal_string(), | 3649 factory()->LookupSymbol(scanner_.literal_string(), |
| 3633 scanner_.literal_length()); | 3650 scanner_.literal_length()); |
| 3634 uint32_t index; | 3651 uint32_t index; |
| 3635 if (!string.is_null() && string->AsArrayIndex(&index)) { | 3652 if (next == Token::STRING && |
| 3653 !string.is_null() && |
| 3654 string->AsArrayIndex(&index)) { |
| 3636 key = NewNumberLiteral(index); | 3655 key = NewNumberLiteral(index); |
| 3637 } else { | 3656 } else { |
| 3638 key = NEW(Literal(string)); | 3657 key = NEW(Literal(string)); |
| 3639 } | 3658 } |
| 3640 break; | 3659 break; |
| 3641 } | 3660 } |
| 3642 | 3661 |
| 3643 case Token::NUMBER: { | 3662 case Token::NUMBER: { |
| 3644 Consume(Token::NUMBER); | 3663 Consume(Token::NUMBER); |
| 3645 double value = | 3664 double value = |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4001 } | 4020 } |
| 4002 | 4021 |
| 4003 | 4022 |
| 4004 Handle<String> Parser::ParseIdentifier(bool* ok) { | 4023 Handle<String> Parser::ParseIdentifier(bool* ok) { |
| 4005 Expect(Token::IDENTIFIER, ok); | 4024 Expect(Token::IDENTIFIER, ok); |
| 4006 if (!*ok) return Handle<String>(); | 4025 if (!*ok) return Handle<String>(); |
| 4007 return factory()->LookupSymbol(scanner_.literal_string(), | 4026 return factory()->LookupSymbol(scanner_.literal_string(), |
| 4008 scanner_.literal_length()); | 4027 scanner_.literal_length()); |
| 4009 } | 4028 } |
| 4010 | 4029 |
| 4030 |
| 4031 Handle<String> Parser::ParseIdentifierName(bool* ok) { |
| 4032 Token::Value next = Next(); |
| 4033 if (next != Token::IDENTIFIER && !Token::IsKeyword(next)) { |
| 4034 ReportUnexpectedToken(next); |
| 4035 *ok = false; |
| 4036 return Handle<String>(); |
| 4037 } |
| 4038 return factory()->LookupSymbol(scanner_.literal_string(), |
| 4039 scanner_.literal_length()); |
| 4040 } |
| 4041 |
| 4042 |
| 4011 // This function reads an identifier and determines whether or not it | 4043 // This function reads an identifier and determines whether or not it |
| 4012 // is 'get' or 'set'. The reason for not using ParseIdentifier and | 4044 // is 'get' or 'set'. The reason for not using ParseIdentifier and |
| 4013 // checking on the output is that this involves heap allocation which | 4045 // checking on the output is that this involves heap allocation which |
| 4014 // we can't do during preparsing. | 4046 // we can't do during preparsing. |
| 4015 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, | 4047 Handle<String> Parser::ParseIdentifierOrGetOrSet(bool* is_get, |
| 4016 bool* is_set, | 4048 bool* is_set, |
| 4017 bool* ok) { | 4049 bool* ok) { |
| 4018 Expect(Token::IDENTIFIER, ok); | 4050 Expect(Token::IDENTIFIER, ok); |
| 4019 if (!*ok) return Handle<String>(); | 4051 if (!*ok) return Handle<String>(); |
| 4020 if (scanner_.literal_length() == 3) { | 4052 if (scanner_.literal_length() == 3) { |
| (...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5198 parser.ParseLazy(script_source, name, | 5230 parser.ParseLazy(script_source, name, |
| 5199 start_position, end_position, is_expression); | 5231 start_position, end_position, is_expression); |
| 5200 return result; | 5232 return result; |
| 5201 } | 5233 } |
| 5202 | 5234 |
| 5203 | 5235 |
| 5204 #undef NEW | 5236 #undef NEW |
| 5205 | 5237 |
| 5206 | 5238 |
| 5207 } } // namespace v8::internal | 5239 } } // namespace v8::internal |
| OLD | NEW |