| 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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 // Implementation of Parser | 430 // Implementation of Parser |
| 431 | 431 |
| 432 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { | 432 bool ParserTraits::IsEvalOrArguments(Handle<String> identifier) const { |
| 433 return identifier.is_identical_to( | 433 return identifier.is_identical_to( |
| 434 parser_->isolate()->factory()->eval_string()) || | 434 parser_->isolate()->factory()->eval_string()) || |
| 435 identifier.is_identical_to( | 435 identifier.is_identical_to( |
| 436 parser_->isolate()->factory()->arguments_string()); | 436 parser_->isolate()->factory()->arguments_string()); |
| 437 } | 437 } |
| 438 | 438 |
| 439 | 439 |
| 440 bool ParserTraits::IsThisProperty(Expression* expression) { |
| 441 ASSERT(expression != NULL); |
| 442 Property* property = expression->AsProperty(); |
| 443 return property != NULL && |
| 444 property->obj()->AsVariableProxy() != NULL && |
| 445 property->obj()->AsVariableProxy()->is_this(); |
| 446 } |
| 447 |
| 448 |
| 449 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, |
| 450 Expression* right) { |
| 451 ASSERT(left != NULL); |
| 452 if (left->AsProperty() != NULL && |
| 453 right->AsFunctionLiteral() != NULL) { |
| 454 right->AsFunctionLiteral()->set_pretenure(); |
| 455 } |
| 456 } |
| 457 |
| 458 |
| 459 Expression* ParserTraits::ValidateAssignmentLeftHandSide( |
| 460 Expression* expression) const { |
| 461 ASSERT(expression != NULL); |
| 462 if (!expression->IsValidLeftHandSide()) { |
| 463 Handle<String> message = |
| 464 parser_->isolate()->factory()->invalid_lhs_in_assignment_string(); |
| 465 expression = parser_->NewThrowReferenceError(message); |
| 466 } |
| 467 return expression; |
| 468 } |
| 469 |
| 470 |
| 471 Expression* ParserTraits::MarkExpressionAsLValue(Expression* expression) { |
| 472 VariableProxy* proxy = expression != NULL |
| 473 ? expression->AsVariableProxy() |
| 474 : NULL; |
| 475 if (proxy != NULL) proxy->MarkAsLValue(); |
| 476 return expression; |
| 477 } |
| 478 |
| 479 |
| 480 void ParserTraits::CheckStrictModeLValue(Expression* expression, |
| 481 bool* ok) { |
| 482 VariableProxy* lhs = expression != NULL |
| 483 ? expression->AsVariableProxy() |
| 484 : NULL; |
| 485 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
| 486 parser_->ReportMessage("strict_eval_arguments", |
| 487 Vector<const char*>::empty()); |
| 488 *ok = false; |
| 489 } |
| 490 } |
| 491 |
| 492 |
| 440 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 493 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
| 441 const char* message, | 494 const char* message, |
| 442 Vector<const char*> args) { | 495 Vector<const char*> args) { |
| 443 if (parser_->stack_overflow()) { | 496 if (parser_->stack_overflow()) { |
| 444 // Suppress the error message (syntax error or such) in the presence of a | 497 // Suppress the error message (syntax error or such) in the presence of a |
| 445 // stack overflow. The isolate allows only one pending exception at at time | 498 // stack overflow. The isolate allows only one pending exception at at time |
| 446 // and we want to report the stack overflow later. | 499 // and we want to report the stack overflow later. |
| 447 return; | 500 return; |
| 448 } | 501 } |
| 449 MessageLocation location(parser_->script_, | 502 MessageLocation location(parser_->script_, |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 } | 612 } |
| 560 | 613 |
| 561 | 614 |
| 562 Literal* ParserTraits::GetLiteralTheHole( | 615 Literal* ParserTraits::GetLiteralTheHole( |
| 563 int position, AstNodeFactory<AstConstructionVisitor>* factory) { | 616 int position, AstNodeFactory<AstConstructionVisitor>* factory) { |
| 564 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), | 617 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), |
| 565 RelocInfo::kNoPosition); | 618 RelocInfo::kNoPosition); |
| 566 } | 619 } |
| 567 | 620 |
| 568 | 621 |
| 569 Expression* ParserTraits::ParseAssignmentExpression(bool accept_IN, bool* ok) { | |
| 570 return parser_->ParseAssignmentExpression(accept_IN, ok); | |
| 571 } | |
| 572 | |
| 573 | |
| 574 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { | 622 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { |
| 575 return parser_->ParseV8Intrinsic(ok); | 623 return parser_->ParseV8Intrinsic(ok); |
| 576 } | 624 } |
| 577 | 625 |
| 578 | 626 |
| 579 FunctionLiteral* ParserTraits::ParseFunctionLiteral( | 627 FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
| 580 Handle<String> name, | 628 Handle<String> name, |
| 581 Scanner::Location function_name_location, | 629 Scanner::Location function_name_location, |
| 582 bool name_is_strict_reserved, | 630 bool name_is_strict_reserved, |
| 583 bool is_generator, | 631 bool is_generator, |
| 584 int function_token_position, | 632 int function_token_position, |
| 585 FunctionLiteral::FunctionType type, | 633 FunctionLiteral::FunctionType type, |
| 586 bool* ok) { | 634 bool* ok) { |
| 587 return parser_->ParseFunctionLiteral(name, function_name_location, | 635 return parser_->ParseFunctionLiteral(name, function_name_location, |
| 588 name_is_strict_reserved, is_generator, | 636 name_is_strict_reserved, is_generator, |
| 589 function_token_position, type, ok); | 637 function_token_position, type, ok); |
| 590 } | 638 } |
| 591 | 639 |
| 592 | 640 |
| 641 Expression* ParserTraits::ParseYieldExpression(bool* ok) { |
| 642 return parser_->ParseYieldExpression(ok); |
| 643 } |
| 644 |
| 645 |
| 646 Expression* ParserTraits::ParseConditionalExpression(bool accept_IN, bool* ok) { |
| 647 return parser_->ParseConditionalExpression(accept_IN, ok); |
| 648 } |
| 649 |
| 650 |
| 593 Parser::Parser(CompilationInfo* info) | 651 Parser::Parser(CompilationInfo* info) |
| 594 : ParserBase<ParserTraits>(&scanner_, | 652 : ParserBase<ParserTraits>(&scanner_, |
| 595 info->isolate()->stack_guard()->real_climit(), | 653 info->isolate()->stack_guard()->real_climit(), |
| 596 info->extension(), | 654 info->extension(), |
| 597 info->zone(), | 655 info->zone(), |
| 598 this), | 656 this), |
| 599 isolate_(info->isolate()), | 657 isolate_(info->isolate()), |
| 600 symbol_cache_(0, info->zone()), | 658 symbol_cache_(0, info->zone()), |
| 601 script_(info->script()), | 659 script_(info->script()), |
| 602 scanner_(isolate_->unicode_cache()), | 660 scanner_(isolate_->unicode_cache()), |
| (...skipping 2267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2870 result->set_scope(for_scope); | 2928 result->set_scope(for_scope); |
| 2871 loop->Initialize(NULL, cond, next, body); | 2929 loop->Initialize(NULL, cond, next, body); |
| 2872 return result; | 2930 return result; |
| 2873 } else { | 2931 } else { |
| 2874 loop->Initialize(init, cond, next, body); | 2932 loop->Initialize(init, cond, next, body); |
| 2875 return loop; | 2933 return loop; |
| 2876 } | 2934 } |
| 2877 } | 2935 } |
| 2878 | 2936 |
| 2879 | 2937 |
| 2880 // Precedence = 2 | |
| 2881 Expression* Parser::ParseAssignmentExpression(bool accept_IN, bool* ok) { | |
| 2882 // AssignmentExpression :: | |
| 2883 // ConditionalExpression | |
| 2884 // YieldExpression | |
| 2885 // LeftHandSideExpression AssignmentOperator AssignmentExpression | |
| 2886 | |
| 2887 if (peek() == Token::YIELD && is_generator()) { | |
| 2888 return ParseYieldExpression(ok); | |
| 2889 } | |
| 2890 | |
| 2891 if (fni_ != NULL) fni_->Enter(); | |
| 2892 Expression* expression = ParseConditionalExpression(accept_IN, CHECK_OK); | |
| 2893 | |
| 2894 if (!Token::IsAssignmentOp(peek())) { | |
| 2895 if (fni_ != NULL) fni_->Leave(); | |
| 2896 // Parsed conditional expression only (no assignment). | |
| 2897 return expression; | |
| 2898 } | |
| 2899 | |
| 2900 // Signal a reference error if the expression is an invalid left-hand | |
| 2901 // side expression. We could report this as a syntax error here but | |
| 2902 // for compatibility with JSC we choose to report the error at | |
| 2903 // runtime. | |
| 2904 // TODO(ES5): Should change parsing for spec conformance. | |
| 2905 if (expression == NULL || !expression->IsValidLeftHandSide()) { | |
| 2906 Handle<String> message = | |
| 2907 isolate()->factory()->invalid_lhs_in_assignment_string(); | |
| 2908 expression = NewThrowReferenceError(message); | |
| 2909 } | |
| 2910 | |
| 2911 if (strict_mode() == STRICT) { | |
| 2912 // Assignment to eval or arguments is disallowed in strict mode. | |
| 2913 CheckStrictModeLValue(expression, CHECK_OK); | |
| 2914 } | |
| 2915 MarkAsLValue(expression); | |
| 2916 | |
| 2917 Token::Value op = Next(); // Get assignment operator. | |
| 2918 int pos = position(); | |
| 2919 Expression* right = ParseAssignmentExpression(accept_IN, CHECK_OK); | |
| 2920 | |
| 2921 // TODO(1231235): We try to estimate the set of properties set by | |
| 2922 // constructors. We define a new property whenever there is an | |
| 2923 // assignment to a property of 'this'. We should probably only add | |
| 2924 // properties if we haven't seen them before. Otherwise we'll | |
| 2925 // probably overestimate the number of properties. | |
| 2926 Property* property = expression ? expression->AsProperty() : NULL; | |
| 2927 if (op == Token::ASSIGN && | |
| 2928 property != NULL && | |
| 2929 property->obj()->AsVariableProxy() != NULL && | |
| 2930 property->obj()->AsVariableProxy()->is_this()) { | |
| 2931 function_state_->AddProperty(); | |
| 2932 } | |
| 2933 | |
| 2934 // If we assign a function literal to a property we pretenure the | |
| 2935 // literal so it can be added as a constant function property. | |
| 2936 if (property != NULL && right->AsFunctionLiteral() != NULL) { | |
| 2937 right->AsFunctionLiteral()->set_pretenure(); | |
| 2938 } | |
| 2939 | |
| 2940 if (fni_ != NULL) { | |
| 2941 // Check if the right hand side is a call to avoid inferring a | |
| 2942 // name if we're dealing with "a = function(){...}();"-like | |
| 2943 // expression. | |
| 2944 if ((op == Token::INIT_VAR | |
| 2945 || op == Token::INIT_CONST_LEGACY | |
| 2946 || op == Token::ASSIGN) | |
| 2947 && (right->AsCall() == NULL && right->AsCallNew() == NULL)) { | |
| 2948 fni_->Infer(); | |
| 2949 } else { | |
| 2950 fni_->RemoveLastFunction(); | |
| 2951 } | |
| 2952 fni_->Leave(); | |
| 2953 } | |
| 2954 | |
| 2955 return factory()->NewAssignment(op, expression, right, pos); | |
| 2956 } | |
| 2957 | |
| 2958 | |
| 2959 Expression* Parser::ParseYieldExpression(bool* ok) { | 2938 Expression* Parser::ParseYieldExpression(bool* ok) { |
| 2960 // YieldExpression :: | 2939 // YieldExpression :: |
| 2961 // 'yield' '*'? AssignmentExpression | 2940 // 'yield' '*'? AssignmentExpression |
| 2962 int pos = peek_position(); | 2941 int pos = peek_position(); |
| 2963 Expect(Token::YIELD, CHECK_OK); | 2942 Expect(Token::YIELD, CHECK_OK); |
| 2964 Yield::Kind kind = | 2943 Yield::Kind kind = |
| 2965 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; | 2944 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; |
| 2966 Expression* generator_object = factory()->NewVariableProxy( | 2945 Expression* generator_object = factory()->NewVariableProxy( |
| 2967 function_state_->generator_object_variable()); | 2946 function_state_->generator_object_variable()); |
| 2968 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); | 2947 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3177 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3156 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3178 Handle<String> message = | 3157 Handle<String> message = |
| 3179 isolate()->factory()->invalid_lhs_in_prefix_op_string(); | 3158 isolate()->factory()->invalid_lhs_in_prefix_op_string(); |
| 3180 expression = NewThrowReferenceError(message); | 3159 expression = NewThrowReferenceError(message); |
| 3181 } | 3160 } |
| 3182 | 3161 |
| 3183 if (strict_mode() == STRICT) { | 3162 if (strict_mode() == STRICT) { |
| 3184 // Prefix expression operand in strict mode may not be eval or arguments. | 3163 // Prefix expression operand in strict mode may not be eval or arguments. |
| 3185 CheckStrictModeLValue(expression, CHECK_OK); | 3164 CheckStrictModeLValue(expression, CHECK_OK); |
| 3186 } | 3165 } |
| 3187 MarkAsLValue(expression); | 3166 MarkExpressionAsLValue(expression); |
| 3188 | 3167 |
| 3189 return factory()->NewCountOperation(op, | 3168 return factory()->NewCountOperation(op, |
| 3190 true /* prefix */, | 3169 true /* prefix */, |
| 3191 expression, | 3170 expression, |
| 3192 position()); | 3171 position()); |
| 3193 | 3172 |
| 3194 } else { | 3173 } else { |
| 3195 return ParsePostfixExpression(ok); | 3174 return ParsePostfixExpression(ok); |
| 3196 } | 3175 } |
| 3197 } | 3176 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3211 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3190 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
| 3212 Handle<String> message = | 3191 Handle<String> message = |
| 3213 isolate()->factory()->invalid_lhs_in_postfix_op_string(); | 3192 isolate()->factory()->invalid_lhs_in_postfix_op_string(); |
| 3214 expression = NewThrowReferenceError(message); | 3193 expression = NewThrowReferenceError(message); |
| 3215 } | 3194 } |
| 3216 | 3195 |
| 3217 if (strict_mode() == STRICT) { | 3196 if (strict_mode() == STRICT) { |
| 3218 // Postfix expression operand in strict mode may not be eval or arguments. | 3197 // Postfix expression operand in strict mode may not be eval or arguments. |
| 3219 CheckStrictModeLValue(expression, CHECK_OK); | 3198 CheckStrictModeLValue(expression, CHECK_OK); |
| 3220 } | 3199 } |
| 3221 MarkAsLValue(expression); | 3200 MarkExpressionAsLValue(expression); |
| 3222 | 3201 |
| 3223 Token::Value next = Next(); | 3202 Token::Value next = Next(); |
| 3224 expression = | 3203 expression = |
| 3225 factory()->NewCountOperation(next, | 3204 factory()->NewCountOperation(next, |
| 3226 false /* postfix */, | 3205 false /* postfix */, |
| 3227 expression, | 3206 expression, |
| 3228 position()); | 3207 position()); |
| 3229 } | 3208 } |
| 3230 return expression; | 3209 return expression; |
| 3231 } | 3210 } |
| (...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4060 return factory()->NewCallRuntime(name, function, args, pos); | 4039 return factory()->NewCallRuntime(name, function, args, pos); |
| 4061 } | 4040 } |
| 4062 | 4041 |
| 4063 | 4042 |
| 4064 Literal* Parser::GetLiteralUndefined(int position) { | 4043 Literal* Parser::GetLiteralUndefined(int position) { |
| 4065 return factory()->NewLiteral( | 4044 return factory()->NewLiteral( |
| 4066 isolate()->factory()->undefined_value(), position); | 4045 isolate()->factory()->undefined_value(), position); |
| 4067 } | 4046 } |
| 4068 | 4047 |
| 4069 | 4048 |
| 4070 void Parser::MarkAsLValue(Expression* expression) { | |
| 4071 VariableProxy* proxy = expression != NULL | |
| 4072 ? expression->AsVariableProxy() | |
| 4073 : NULL; | |
| 4074 | |
| 4075 if (proxy != NULL) proxy->MarkAsLValue(); | |
| 4076 } | |
| 4077 | |
| 4078 | |
| 4079 // Checks LHS expression for assignment and prefix/postfix increment/decrement | |
| 4080 // in strict mode. | |
| 4081 void Parser::CheckStrictModeLValue(Expression* expression, | |
| 4082 bool* ok) { | |
| 4083 ASSERT(strict_mode() == STRICT); | |
| 4084 VariableProxy* lhs = expression != NULL | |
| 4085 ? expression->AsVariableProxy() | |
| 4086 : NULL; | |
| 4087 | |
| 4088 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | |
| 4089 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); | |
| 4090 *ok = false; | |
| 4091 } | |
| 4092 } | |
| 4093 | |
| 4094 | |
| 4095 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 4049 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
| 4096 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 4050 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
| 4097 if (decl != NULL) { | 4051 if (decl != NULL) { |
| 4098 // In harmony mode we treat conflicting variable bindinds as early | 4052 // In harmony mode we treat conflicting variable bindinds as early |
| 4099 // errors. See ES5 16 for a definition of early errors. | 4053 // errors. See ES5 16 for a definition of early errors. |
| 4100 Handle<String> name = decl->proxy()->name(); | 4054 Handle<String> name = decl->proxy()->name(); |
| 4101 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 4055 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
| 4102 const char* elms[2] = { "Variable", c_string.get() }; | 4056 const char* elms[2] = { "Variable", c_string.get() }; |
| 4103 Vector<const char*> args(elms, 2); | 4057 Vector<const char*> args(elms, 2); |
| 4104 int position = decl->proxy()->position(); | 4058 int position = decl->proxy()->position(); |
| (...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5168 ASSERT(info()->isolate()->has_pending_exception()); | 5122 ASSERT(info()->isolate()->has_pending_exception()); |
| 5169 } else { | 5123 } else { |
| 5170 result = ParseProgram(); | 5124 result = ParseProgram(); |
| 5171 } | 5125 } |
| 5172 } | 5126 } |
| 5173 info()->SetFunction(result); | 5127 info()->SetFunction(result); |
| 5174 return (result != NULL); | 5128 return (result != NULL); |
| 5175 } | 5129 } |
| 5176 | 5130 |
| 5177 } } // namespace v8::internal | 5131 } } // namespace v8::internal |
| OLD | NEW |