| 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 |