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 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3967 return factory()->NewCallRuntime(name, function, args, pos); | 3946 return factory()->NewCallRuntime(name, function, args, pos); |
3968 } | 3947 } |
3969 | 3948 |
3970 | 3949 |
3971 Literal* Parser::GetLiteralUndefined(int position) { | 3950 Literal* Parser::GetLiteralUndefined(int position) { |
3972 return factory()->NewLiteral( | 3951 return factory()->NewLiteral( |
3973 isolate()->factory()->undefined_value(), position); | 3952 isolate()->factory()->undefined_value(), position); |
3974 } | 3953 } |
3975 | 3954 |
3976 | 3955 |
3977 void Parser::MarkAsLValue(Expression* expression) { | |
3978 VariableProxy* proxy = expression != NULL | |
3979 ? expression->AsVariableProxy() | |
3980 : NULL; | |
3981 | |
3982 if (proxy != NULL) proxy->MarkAsLValue(); | |
3983 } | |
3984 | |
3985 | |
3986 // Checks LHS expression for assignment and prefix/postfix increment/decrement | |
3987 // in strict mode. | |
3988 void Parser::CheckStrictModeLValue(Expression* expression, | |
3989 bool* ok) { | |
3990 ASSERT(strict_mode() == STRICT); | |
3991 VariableProxy* lhs = expression != NULL | |
3992 ? expression->AsVariableProxy() | |
3993 : NULL; | |
3994 | |
3995 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | |
3996 ReportMessage("strict_eval_arguments", Vector<const char*>::empty()); | |
3997 *ok = false; | |
3998 } | |
3999 } | |
4000 | |
4001 | |
4002 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 3956 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
4003 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 3957 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
4004 if (decl != NULL) { | 3958 if (decl != NULL) { |
4005 // In harmony mode we treat conflicting variable bindinds as early | 3959 // In harmony mode we treat conflicting variable bindinds as early |
4006 // errors. See ES5 16 for a definition of early errors. | 3960 // errors. See ES5 16 for a definition of early errors. |
4007 Handle<String> name = decl->proxy()->name(); | 3961 Handle<String> name = decl->proxy()->name(); |
4008 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 3962 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
4009 const char* elms[2] = { "Variable", c_string.get() }; | 3963 const char* elms[2] = { "Variable", c_string.get() }; |
4010 Vector<const char*> args(elms, 2); | 3964 Vector<const char*> args(elms, 2); |
4011 int position = decl->proxy()->position(); | 3965 int position = decl->proxy()->position(); |
(...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5075 ASSERT(info()->isolate()->has_pending_exception()); | 5029 ASSERT(info()->isolate()->has_pending_exception()); |
5076 } else { | 5030 } else { |
5077 result = ParseProgram(); | 5031 result = ParseProgram(); |
5078 } | 5032 } |
5079 } | 5033 } |
5080 info()->SetFunction(result); | 5034 info()->SetFunction(result); |
5081 return (result != NULL); | 5035 return (result != NULL); |
5082 } | 5036 } |
5083 | 5037 |
5084 } } // namespace v8::internal | 5038 } } // namespace v8::internal |
OLD | NEW |