OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 property->obj()->AsVariableProxy()->is_this(); | 432 property->obj()->AsVariableProxy()->is_this(); |
433 } | 433 } |
434 | 434 |
435 | 435 |
436 bool ParserTraits::IsIdentifier(Expression* expression) { | 436 bool ParserTraits::IsIdentifier(Expression* expression) { |
437 VariableProxy* operand = expression->AsVariableProxy(); | 437 VariableProxy* operand = expression->AsVariableProxy(); |
438 return operand != NULL && !operand->is_this(); | 438 return operand != NULL && !operand->is_this(); |
439 } | 439 } |
440 | 440 |
441 | 441 |
| 442 void ParserTraits::PushPropertyName(FuncNameInferrer* fni, |
| 443 Expression* expression) { |
| 444 if (expression->IsPropertyName()) { |
| 445 fni->PushLiteralName(expression->AsLiteral()->AsPropertyName()); |
| 446 } else { |
| 447 fni->PushLiteralName( |
| 448 parser_->isolate()->factory()->anonymous_function_string()); |
| 449 } |
| 450 } |
| 451 |
| 452 |
442 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, | 453 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, |
443 Expression* right) { | 454 Expression* right) { |
444 ASSERT(left != NULL); | 455 ASSERT(left != NULL); |
445 if (left->AsProperty() != NULL && | 456 if (left->AsProperty() != NULL && |
446 right->AsFunctionLiteral() != NULL) { | 457 right->AsFunctionLiteral() != NULL) { |
447 right->AsFunctionLiteral()->set_pretenure(); | 458 right->AsFunctionLiteral()->set_pretenure(); |
448 } | 459 } |
449 } | 460 } |
450 | 461 |
451 | 462 |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 bool is_generator, | 754 bool is_generator, |
744 int function_token_position, | 755 int function_token_position, |
745 FunctionLiteral::FunctionType type, | 756 FunctionLiteral::FunctionType type, |
746 bool* ok) { | 757 bool* ok) { |
747 return parser_->ParseFunctionLiteral(name, function_name_location, | 758 return parser_->ParseFunctionLiteral(name, function_name_location, |
748 name_is_strict_reserved, is_generator, | 759 name_is_strict_reserved, is_generator, |
749 function_token_position, type, ok); | 760 function_token_position, type, ok); |
750 } | 761 } |
751 | 762 |
752 | 763 |
753 Expression* ParserTraits::ParseMemberWithNewPrefixesExpression(bool* ok) { | |
754 return parser_->ParseMemberWithNewPrefixesExpression(ok); | |
755 } | |
756 | |
757 | |
758 Parser::Parser(CompilationInfo* info) | 764 Parser::Parser(CompilationInfo* info) |
759 : ParserBase<ParserTraits>(&scanner_, | 765 : ParserBase<ParserTraits>(&scanner_, |
760 info->isolate()->stack_guard()->real_climit(), | 766 info->isolate()->stack_guard()->real_climit(), |
761 info->extension(), | 767 info->extension(), |
762 NULL, | 768 NULL, |
763 info->zone(), | 769 info->zone(), |
764 this), | 770 this), |
765 isolate_(info->isolate()), | 771 isolate_(info->isolate()), |
766 symbol_cache_(0, info->zone()), | 772 symbol_cache_(0, info->zone()), |
767 script_(info->script()), | 773 script_(info->script()), |
(...skipping 2278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3046 result->set_scope(for_scope); | 3052 result->set_scope(for_scope); |
3047 loop->Initialize(NULL, cond, next, body); | 3053 loop->Initialize(NULL, cond, next, body); |
3048 return result; | 3054 return result; |
3049 } else { | 3055 } else { |
3050 loop->Initialize(init, cond, next, body); | 3056 loop->Initialize(init, cond, next, body); |
3051 return loop; | 3057 return loop; |
3052 } | 3058 } |
3053 } | 3059 } |
3054 | 3060 |
3055 | 3061 |
3056 Expression* Parser::ParseMemberWithNewPrefixesExpression(bool* ok) { | |
3057 // NewExpression :: | |
3058 // ('new')+ MemberExpression | |
3059 | |
3060 // The grammar for new expressions is pretty warped. We can have several 'new' | |
3061 // keywords following each other, and then a MemberExpression. When we see '(' | |
3062 // after the MemberExpression, it's associated with the rightmost unassociated | |
3063 // 'new' to create a NewExpression with arguments. However, a NewExpression | |
3064 // can also occur without arguments. | |
3065 | |
3066 // Examples of new expression: | |
3067 // new foo.bar().baz means (new (foo.bar)()).baz | |
3068 // new foo()() means (new foo())() | |
3069 // new new foo()() means (new (new foo())()) | |
3070 // new new foo means new (new foo) | |
3071 // new new foo() means new (new foo()) | |
3072 // new new foo().bar().baz means (new (new foo()).bar()).baz | |
3073 | |
3074 if (peek() == Token::NEW) { | |
3075 Consume(Token::NEW); | |
3076 int new_pos = position(); | |
3077 Expression* result = ParseMemberWithNewPrefixesExpression(CHECK_OK); | |
3078 if (peek() == Token::LPAREN) { | |
3079 // NewExpression with arguments. | |
3080 ZoneList<Expression*>* args = ParseArguments(CHECK_OK); | |
3081 result = factory()->NewCallNew(result, args, new_pos); | |
3082 // The expression can still continue with . or [ after the arguments. | |
3083 result = ParseMemberExpressionContinuation(result, CHECK_OK); | |
3084 return result; | |
3085 } | |
3086 // NewExpression without arguments. | |
3087 return factory()->NewCallNew( | |
3088 result, new(zone()) ZoneList<Expression*>(0, zone()), new_pos); | |
3089 } | |
3090 // No 'new' keyword. | |
3091 return ParseMemberExpression(ok); | |
3092 } | |
3093 | |
3094 | |
3095 Expression* Parser::ParseMemberExpression(bool* ok) { | |
3096 // MemberExpression :: | |
3097 // (PrimaryExpression | FunctionLiteral) | |
3098 // ('[' Expression ']' | '.' Identifier | Arguments)* | |
3099 | |
3100 // The '[' Expression ']' and '.' Identifier parts are parsed by | |
3101 // ParseMemberExpressionContinuation, and the Arguments part is parsed by the | |
3102 // caller. | |
3103 | |
3104 // Parse the initial primary or function expression. | |
3105 Expression* result = NULL; | |
3106 if (peek() == Token::FUNCTION) { | |
3107 Consume(Token::FUNCTION); | |
3108 int function_token_position = position(); | |
3109 bool is_generator = allow_generators() && Check(Token::MUL); | |
3110 Handle<String> name; | |
3111 bool is_strict_reserved_name = false; | |
3112 Scanner::Location function_name_location = Scanner::Location::invalid(); | |
3113 FunctionLiteral::FunctionType function_type = | |
3114 FunctionLiteral::ANONYMOUS_EXPRESSION; | |
3115 if (peek_any_identifier()) { | |
3116 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved_name, | |
3117 CHECK_OK); | |
3118 function_name_location = scanner()->location(); | |
3119 function_type = FunctionLiteral::NAMED_EXPRESSION; | |
3120 } | |
3121 result = ParseFunctionLiteral(name, | |
3122 function_name_location, | |
3123 is_strict_reserved_name, | |
3124 is_generator, | |
3125 function_token_position, | |
3126 function_type, | |
3127 CHECK_OK); | |
3128 } else { | |
3129 result = ParsePrimaryExpression(CHECK_OK); | |
3130 } | |
3131 | |
3132 result = ParseMemberExpressionContinuation(result, CHECK_OK); | |
3133 return result; | |
3134 } | |
3135 | |
3136 | |
3137 Expression* Parser::ParseMemberExpressionContinuation(Expression* expression, | |
3138 bool* ok) { | |
3139 // Parses this part of MemberExpression: | |
3140 // ('[' Expression ']' | '.' Identifier)* | |
3141 while (true) { | |
3142 switch (peek()) { | |
3143 case Token::LBRACK: { | |
3144 Consume(Token::LBRACK); | |
3145 int pos = position(); | |
3146 Expression* index = ParseExpression(true, CHECK_OK); | |
3147 expression = factory()->NewProperty(expression, index, pos); | |
3148 if (fni_ != NULL) { | |
3149 if (index->IsPropertyName()) { | |
3150 fni_->PushLiteralName(index->AsLiteral()->AsPropertyName()); | |
3151 } else { | |
3152 fni_->PushLiteralName( | |
3153 isolate()->factory()->anonymous_function_string()); | |
3154 } | |
3155 } | |
3156 Expect(Token::RBRACK, CHECK_OK); | |
3157 break; | |
3158 } | |
3159 case Token::PERIOD: { | |
3160 Consume(Token::PERIOD); | |
3161 int pos = position(); | |
3162 Handle<String> name = ParseIdentifierName(CHECK_OK); | |
3163 expression = factory()->NewProperty( | |
3164 expression, factory()->NewLiteral(name, pos), pos); | |
3165 if (fni_ != NULL) fni_->PushLiteralName(name); | |
3166 break; | |
3167 } | |
3168 default: | |
3169 return expression; | |
3170 } | |
3171 } | |
3172 ASSERT(false); | |
3173 return NULL; | |
3174 } | |
3175 | |
3176 | |
3177 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { | 3062 DebuggerStatement* Parser::ParseDebuggerStatement(bool* ok) { |
3178 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser | 3063 // In ECMA-262 'debugger' is defined as a reserved keyword. In some browser |
3179 // contexts this is used as a statement which invokes the debugger as i a | 3064 // contexts this is used as a statement which invokes the debugger as i a |
3180 // break point is present. | 3065 // break point is present. |
3181 // DebuggerStatement :: | 3066 // DebuggerStatement :: |
3182 // 'debugger' ';' | 3067 // 'debugger' ';' |
3183 | 3068 |
3184 int pos = peek_position(); | 3069 int pos = peek_position(); |
3185 Expect(Token::DEBUGGER, CHECK_OK); | 3070 Expect(Token::DEBUGGER, CHECK_OK); |
3186 ExpectSemicolon(CHECK_OK); | 3071 ExpectSemicolon(CHECK_OK); |
(...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4805 ASSERT(info()->isolate()->has_pending_exception()); | 4690 ASSERT(info()->isolate()->has_pending_exception()); |
4806 } else { | 4691 } else { |
4807 result = ParseProgram(); | 4692 result = ParseProgram(); |
4808 } | 4693 } |
4809 } | 4694 } |
4810 info()->SetFunction(result); | 4695 info()->SetFunction(result); |
4811 return (result != NULL); | 4696 return (result != NULL); |
4812 } | 4697 } |
4813 | 4698 |
4814 } } // namespace v8::internal | 4699 } } // namespace v8::internal |
OLD | NEW |