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 |