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