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