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 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 Expression* ParsePostfixExpression(bool* ok); | 203 Expression* ParsePostfixExpression(bool* ok); |
204 Expression* ParseLeftHandSideExpression(bool* ok); | 204 Expression* ParseLeftHandSideExpression(bool* ok); |
205 Expression* ParseNewExpression(bool* ok); | 205 Expression* ParseNewExpression(bool* ok); |
206 Expression* ParseMemberExpression(bool* ok); | 206 Expression* ParseMemberExpression(bool* ok); |
207 Expression* ParseNewPrefix(PositionStack* stack, bool* ok); | 207 Expression* ParseNewPrefix(PositionStack* stack, bool* ok); |
208 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack, | 208 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
209 bool* ok); | 209 bool* ok); |
210 Expression* ParsePrimaryExpression(bool* ok); | 210 Expression* ParsePrimaryExpression(bool* ok); |
211 Expression* ParseArrayLiteral(bool* ok); | 211 Expression* ParseArrayLiteral(bool* ok); |
212 Expression* ParseObjectLiteral(bool* ok); | 212 Expression* ParseObjectLiteral(bool* ok); |
| 213 ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok); |
213 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); | 214 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); |
214 | 215 |
215 // Populate the constant properties fixed array for a materialized object | 216 // Populate the constant properties fixed array for a materialized object |
216 // literal. | 217 // literal. |
217 void BuildObjectLiteralConstantProperties( | 218 void BuildObjectLiteralConstantProperties( |
218 ZoneList<ObjectLiteral::Property*>* properties, | 219 ZoneList<ObjectLiteral::Property*>* properties, |
219 Handle<FixedArray> constants, | 220 Handle<FixedArray> constants, |
220 bool* is_simple, | 221 bool* is_simple, |
221 bool* fast_elements, | 222 bool* fast_elements, |
222 int* depth); | 223 int* depth); |
(...skipping 3146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3369 | 3370 |
3370 case Token::MOD: | 3371 case Token::MOD: |
3371 if (allow_natives_syntax_ || extension_ != NULL) { | 3372 if (allow_natives_syntax_ || extension_ != NULL) { |
3372 result = ParseV8Intrinsic(CHECK_OK); | 3373 result = ParseV8Intrinsic(CHECK_OK); |
3373 break; | 3374 break; |
3374 } | 3375 } |
3375 // If we're not allowing special syntax we fall-through to the | 3376 // If we're not allowing special syntax we fall-through to the |
3376 // default case. | 3377 // default case. |
3377 | 3378 |
3378 default: { | 3379 default: { |
3379 Token::Value tok = peek(); | 3380 Token::Value tok = Next(); |
3380 // Token::Peek returns the value of the next token but | |
3381 // location() gives info about the current token. | |
3382 // Therefore, we need to read ahead to the next token | |
3383 Next(); | |
3384 ReportUnexpectedToken(tok); | 3381 ReportUnexpectedToken(tok); |
3385 *ok = false; | 3382 *ok = false; |
3386 return NULL; | 3383 return NULL; |
3387 } | 3384 } |
3388 } | 3385 } |
3389 | 3386 |
3390 return result; | 3387 return result; |
3391 } | 3388 } |
3392 | 3389 |
3393 | 3390 |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3577 constant_properties->set(position++, *key); | 3574 constant_properties->set(position++, *key); |
3578 constant_properties->set(position++, *value); | 3575 constant_properties->set(position++, *value); |
3579 } | 3576 } |
3580 *fast_elements = | 3577 *fast_elements = |
3581 (max_element_index <= 32) || ((2 * elements) >= max_element_index); | 3578 (max_element_index <= 32) || ((2 * elements) >= max_element_index); |
3582 *is_simple = is_simple_acc; | 3579 *is_simple = is_simple_acc; |
3583 *depth = depth_acc; | 3580 *depth = depth_acc; |
3584 } | 3581 } |
3585 | 3582 |
3586 | 3583 |
| 3584 ObjectLiteral::Property* Parser::ParseObjectLiteralGetSet(bool is_getter, |
| 3585 bool* ok) { |
| 3586 // Special handling of getter and setter syntax: |
| 3587 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... } |
| 3588 // We have already read the "get" or "set" keyword. |
| 3589 Token::Value next = Next(); |
| 3590 if (next == Token::IDENTIFIER || |
| 3591 next == Token::STRING || |
| 3592 next == Token::NUMBER || |
| 3593 Token::IsKeyword(next)) { |
| 3594 Handle<String> name = |
| 3595 factory()->LookupSymbol(scanner_.literal_string(), |
| 3596 scanner_.literal_length()); |
| 3597 FunctionLiteral* value = |
| 3598 ParseFunctionLiteral(name, |
| 3599 RelocInfo::kNoPosition, |
| 3600 DECLARATION, |
| 3601 CHECK_OK); |
| 3602 ObjectLiteral::Property* property = |
| 3603 NEW(ObjectLiteral::Property(is_getter, value)); |
| 3604 return property; |
| 3605 } else { |
| 3606 ReportUnexpectedToken(next); |
| 3607 *ok = false; |
| 3608 return NULL; |
| 3609 } |
| 3610 } |
| 3611 |
| 3612 |
3587 Expression* Parser::ParseObjectLiteral(bool* ok) { | 3613 Expression* Parser::ParseObjectLiteral(bool* ok) { |
3588 // ObjectLiteral :: | 3614 // ObjectLiteral :: |
3589 // '{' ( | 3615 // '{' ( |
3590 // ((IdentifierName | String | Number) ':' AssignmentExpression) | 3616 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
3591 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) | 3617 // | (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral) |
3592 // )*[','] '}' | 3618 // )*[','] '}' |
3593 | 3619 |
3594 ZoneListWrapper<ObjectLiteral::Property> properties = | 3620 ZoneListWrapper<ObjectLiteral::Property> properties = |
3595 factory()->NewList<ObjectLiteral::Property>(4); | 3621 factory()->NewList<ObjectLiteral::Property>(4); |
3596 int number_of_boilerplate_properties = 0; | 3622 int number_of_boilerplate_properties = 0; |
3597 | 3623 |
3598 Expect(Token::LBRACE, CHECK_OK); | 3624 Expect(Token::LBRACE, CHECK_OK); |
3599 while (peek() != Token::RBRACE) { | 3625 while (peek() != Token::RBRACE) { |
3600 Literal* key = NULL; | 3626 Literal* key = NULL; |
3601 Token::Value next = peek(); | 3627 Token::Value next = peek(); |
3602 switch (next) { | 3628 switch (next) { |
3603 case Token::IDENTIFIER: { | 3629 case Token::IDENTIFIER: { |
3604 // Store identifier keys as literal symbols to avoid | |
3605 // resolving them when compiling code for the object | |
3606 // literal. | |
3607 bool is_getter = false; | 3630 bool is_getter = false; |
3608 bool is_setter = false; | 3631 bool is_setter = false; |
3609 Handle<String> id = | 3632 Handle<String> id = |
3610 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); | 3633 ParseIdentifierOrGetOrSet(&is_getter, &is_setter, CHECK_OK); |
3611 if (is_getter || is_setter) { | 3634 if ((is_getter || is_setter) && peek() != Token::COLON) { |
3612 // Special handling of getter and setter syntax. | |
3613 Handle<String> name; | |
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()); | |
3623 FunctionLiteral* value = | |
3624 ParseFunctionLiteral(name, | |
3625 RelocInfo::kNoPosition, | |
3626 DECLARATION, | |
3627 CHECK_OK); | |
3628 ObjectLiteral::Property* property = | 3635 ObjectLiteral::Property* property = |
3629 NEW(ObjectLiteral::Property(is_getter, value)); | 3636 ParseObjectLiteralGetSet(is_getter, CHECK_OK); |
3630 if (IsBoilerplateProperty(property)) { | 3637 if (IsBoilerplateProperty(property)) { |
3631 number_of_boilerplate_properties++; | 3638 number_of_boilerplate_properties++; |
3632 } | 3639 } |
3633 properties.Add(property); | 3640 properties.Add(property); |
3634 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); | 3641 if (peek() != Token::RBRACE) Expect(Token::COMMA, CHECK_OK); |
3635 continue; // restart the while | 3642 continue; // restart the while |
3636 } | |
3637 } | 3643 } |
| 3644 // Failed to parse as get/set property, so it's just a property |
| 3645 // called "get" or "set". |
3638 key = NEW(Literal(id)); | 3646 key = NEW(Literal(id)); |
3639 break; | 3647 break; |
3640 } | 3648 } |
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. | |
3646 case Token::STRING: { | 3649 case Token::STRING: { |
3647 Consume(next); | 3650 Consume(Token::STRING); |
3648 Handle<String> string = | 3651 Handle<String> string = |
3649 factory()->LookupSymbol(scanner_.literal_string(), | 3652 factory()->LookupSymbol(scanner_.literal_string(), |
3650 scanner_.literal_length()); | 3653 scanner_.literal_length()); |
3651 uint32_t index; | 3654 uint32_t index; |
3652 if (next == Token::STRING && | 3655 if (!string.is_null() && |
3653 !string.is_null() && | |
3654 string->AsArrayIndex(&index)) { | 3656 string->AsArrayIndex(&index)) { |
3655 key = NewNumberLiteral(index); | 3657 key = NewNumberLiteral(index); |
3656 } else { | 3658 break; |
3657 key = NEW(Literal(string)); | |
3658 } | 3659 } |
| 3660 key = NEW(Literal(string)); |
3659 break; | 3661 break; |
3660 } | 3662 } |
3661 | |
3662 case Token::NUMBER: { | 3663 case Token::NUMBER: { |
3663 Consume(Token::NUMBER); | 3664 Consume(Token::NUMBER); |
3664 double value = | 3665 double value = |
3665 StringToDouble(scanner_.literal_string(), ALLOW_HEX | ALLOW_OCTALS); | 3666 StringToDouble(scanner_.literal_string(), ALLOW_HEX | ALLOW_OCTALS); |
3666 key = NewNumberLiteral(value); | 3667 key = NewNumberLiteral(value); |
3667 break; | 3668 break; |
3668 } | 3669 } |
3669 | |
3670 default: | 3670 default: |
3671 Expect(Token::RBRACE, CHECK_OK); | 3671 if (Token::IsKeyword(next)) { |
3672 break; | 3672 Consume(next); |
| 3673 Handle<String> string = |
| 3674 factory()->LookupSymbol(scanner_.literal_string(), |
| 3675 scanner_.literal_length()); |
| 3676 key = NEW(Literal(string)); |
| 3677 } else { |
| 3678 // Unexpected token. |
| 3679 Token::Value next = Next(); |
| 3680 ReportUnexpectedToken(next); |
| 3681 *ok = false; |
| 3682 return NULL; |
| 3683 } |
3673 } | 3684 } |
3674 | 3685 |
3675 Expect(Token::COLON, CHECK_OK); | 3686 Expect(Token::COLON, CHECK_OK); |
3676 Expression* value = ParseAssignmentExpression(true, CHECK_OK); | 3687 Expression* value = ParseAssignmentExpression(true, CHECK_OK); |
3677 | 3688 |
3678 ObjectLiteral::Property* property = | 3689 ObjectLiteral::Property* property = |
3679 NEW(ObjectLiteral::Property(key, value)); | 3690 NEW(ObjectLiteral::Property(key, value)); |
3680 | 3691 |
3681 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. | 3692 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. |
3682 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; | 3693 if (IsBoilerplateProperty(property)) number_of_boilerplate_properties++; |
(...skipping 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5230 parser.ParseLazy(script_source, name, | 5241 parser.ParseLazy(script_source, name, |
5231 start_position, end_position, is_expression); | 5242 start_position, end_position, is_expression); |
5232 return result; | 5243 return result; |
5233 } | 5244 } |
5234 | 5245 |
5235 | 5246 |
5236 #undef NEW | 5247 #undef NEW |
5237 | 5248 |
5238 | 5249 |
5239 } } // namespace v8::internal | 5250 } } // namespace v8::internal |
OLD | NEW |