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 | |
493 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 440 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
494 const char* message, | 441 const char* message, |
495 Vector<const char*> args) { | 442 Vector<const char*> args) { |
496 if (parser_->stack_overflow()) { | 443 if (parser_->stack_overflow()) { |
497 // Suppress the error message (syntax error or such) in the presence of a | 444 // Suppress the error message (syntax error or such) in the presence of a |
498 // stack overflow. The isolate allows only one pending exception at at time | 445 // stack overflow. The isolate allows only one pending exception at at time |
499 // and we want to report the stack overflow later. | 446 // and we want to report the stack overflow later. |
500 return; | 447 return; |
501 } | 448 } |
502 MessageLocation location(parser_->script_, | 449 MessageLocation location(parser_->script_, |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 } | 559 } |
613 | 560 |
614 | 561 |
615 Literal* ParserTraits::GetLiteralTheHole( | 562 Literal* ParserTraits::GetLiteralTheHole( |
616 int position, AstNodeFactory<AstConstructionVisitor>* factory) { | 563 int position, AstNodeFactory<AstConstructionVisitor>* factory) { |
617 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), | 564 return factory->NewLiteral(parser_->isolate()->factory()->the_hole_value(), |
618 RelocInfo::kNoPosition); | 565 RelocInfo::kNoPosition); |
619 } | 566 } |
620 | 567 |
621 | 568 |
| 569 Expression* ParserTraits::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 570 return parser_->ParseAssignmentExpression(accept_IN, ok); |
| 571 } |
| 572 |
| 573 |
622 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { | 574 Expression* ParserTraits::ParseV8Intrinsic(bool* ok) { |
623 return parser_->ParseV8Intrinsic(ok); | 575 return parser_->ParseV8Intrinsic(ok); |
624 } | 576 } |
625 | 577 |
626 | 578 |
627 FunctionLiteral* ParserTraits::ParseFunctionLiteral( | 579 FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
628 Handle<String> name, | 580 Handle<String> name, |
629 Scanner::Location function_name_location, | 581 Scanner::Location function_name_location, |
630 bool name_is_strict_reserved, | 582 bool name_is_strict_reserved, |
631 bool is_generator, | 583 bool is_generator, |
632 int function_token_position, | 584 int function_token_position, |
633 FunctionLiteral::FunctionType type, | 585 FunctionLiteral::FunctionType type, |
634 bool* ok) { | 586 bool* ok) { |
635 return parser_->ParseFunctionLiteral(name, function_name_location, | 587 return parser_->ParseFunctionLiteral(name, function_name_location, |
636 name_is_strict_reserved, is_generator, | 588 name_is_strict_reserved, is_generator, |
637 function_token_position, type, ok); | 589 function_token_position, type, ok); |
638 } | 590 } |
639 | 591 |
640 | 592 |
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 | |
651 Parser::Parser(CompilationInfo* info) | 593 Parser::Parser(CompilationInfo* info) |
652 : ParserBase<ParserTraits>(&scanner_, | 594 : ParserBase<ParserTraits>(&scanner_, |
653 info->isolate()->stack_guard()->real_climit(), | 595 info->isolate()->stack_guard()->real_climit(), |
654 info->extension(), | 596 info->extension(), |
655 info->zone(), | 597 info->zone(), |
656 this), | 598 this), |
657 isolate_(info->isolate()), | 599 isolate_(info->isolate()), |
658 symbol_cache_(0, info->zone()), | 600 symbol_cache_(0, info->zone()), |
659 script_(info->script()), | 601 script_(info->script()), |
660 scanner_(isolate_->unicode_cache()), | 602 scanner_(isolate_->unicode_cache()), |
(...skipping 2267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2928 result->set_scope(for_scope); | 2870 result->set_scope(for_scope); |
2929 loop->Initialize(NULL, cond, next, body); | 2871 loop->Initialize(NULL, cond, next, body); |
2930 return result; | 2872 return result; |
2931 } else { | 2873 } else { |
2932 loop->Initialize(init, cond, next, body); | 2874 loop->Initialize(init, cond, next, body); |
2933 return loop; | 2875 return loop; |
2934 } | 2876 } |
2935 } | 2877 } |
2936 | 2878 |
2937 | 2879 |
| 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 |
2938 Expression* Parser::ParseYieldExpression(bool* ok) { | 2959 Expression* Parser::ParseYieldExpression(bool* ok) { |
2939 // YieldExpression :: | 2960 // YieldExpression :: |
2940 // 'yield' '*'? AssignmentExpression | 2961 // 'yield' '*'? AssignmentExpression |
2941 int pos = peek_position(); | 2962 int pos = peek_position(); |
2942 Expect(Token::YIELD, CHECK_OK); | 2963 Expect(Token::YIELD, CHECK_OK); |
2943 Yield::Kind kind = | 2964 Yield::Kind kind = |
2944 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; | 2965 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; |
2945 Expression* generator_object = factory()->NewVariableProxy( | 2966 Expression* generator_object = factory()->NewVariableProxy( |
2946 function_state_->generator_object_variable()); | 2967 function_state_->generator_object_variable()); |
2947 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); | 2968 Expression* expression = ParseAssignmentExpression(false, CHECK_OK); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3156 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3177 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
3157 Handle<String> message = | 3178 Handle<String> message = |
3158 isolate()->factory()->invalid_lhs_in_prefix_op_string(); | 3179 isolate()->factory()->invalid_lhs_in_prefix_op_string(); |
3159 expression = NewThrowReferenceError(message); | 3180 expression = NewThrowReferenceError(message); |
3160 } | 3181 } |
3161 | 3182 |
3162 if (strict_mode() == STRICT) { | 3183 if (strict_mode() == STRICT) { |
3163 // Prefix expression operand in strict mode may not be eval or arguments. | 3184 // Prefix expression operand in strict mode may not be eval or arguments. |
3164 CheckStrictModeLValue(expression, CHECK_OK); | 3185 CheckStrictModeLValue(expression, CHECK_OK); |
3165 } | 3186 } |
3166 MarkExpressionAsLValue(expression); | 3187 MarkAsLValue(expression); |
3167 | 3188 |
3168 return factory()->NewCountOperation(op, | 3189 return factory()->NewCountOperation(op, |
3169 true /* prefix */, | 3190 true /* prefix */, |
3170 expression, | 3191 expression, |
3171 position()); | 3192 position()); |
3172 | 3193 |
3173 } else { | 3194 } else { |
3174 return ParsePostfixExpression(ok); | 3195 return ParsePostfixExpression(ok); |
3175 } | 3196 } |
3176 } | 3197 } |
(...skipping 13 matching lines...) Expand all Loading... |
3190 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3211 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
3191 Handle<String> message = | 3212 Handle<String> message = |
3192 isolate()->factory()->invalid_lhs_in_postfix_op_string(); | 3213 isolate()->factory()->invalid_lhs_in_postfix_op_string(); |
3193 expression = NewThrowReferenceError(message); | 3214 expression = NewThrowReferenceError(message); |
3194 } | 3215 } |
3195 | 3216 |
3196 if (strict_mode() == STRICT) { | 3217 if (strict_mode() == STRICT) { |
3197 // Postfix expression operand in strict mode may not be eval or arguments. | 3218 // Postfix expression operand in strict mode may not be eval or arguments. |
3198 CheckStrictModeLValue(expression, CHECK_OK); | 3219 CheckStrictModeLValue(expression, CHECK_OK); |
3199 } | 3220 } |
3200 MarkExpressionAsLValue(expression); | 3221 MarkAsLValue(expression); |
3201 | 3222 |
3202 Token::Value next = Next(); | 3223 Token::Value next = Next(); |
3203 expression = | 3224 expression = |
3204 factory()->NewCountOperation(next, | 3225 factory()->NewCountOperation(next, |
3205 false /* postfix */, | 3226 false /* postfix */, |
3206 expression, | 3227 expression, |
3207 position()); | 3228 position()); |
3208 } | 3229 } |
3209 return expression; | 3230 return expression; |
3210 } | 3231 } |
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3946 return factory()->NewCallRuntime(name, function, args, pos); | 3967 return factory()->NewCallRuntime(name, function, args, pos); |
3947 } | 3968 } |
3948 | 3969 |
3949 | 3970 |
3950 Literal* Parser::GetLiteralUndefined(int position) { | 3971 Literal* Parser::GetLiteralUndefined(int position) { |
3951 return factory()->NewLiteral( | 3972 return factory()->NewLiteral( |
3952 isolate()->factory()->undefined_value(), position); | 3973 isolate()->factory()->undefined_value(), position); |
3953 } | 3974 } |
3954 | 3975 |
3955 | 3976 |
| 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 |
3956 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { | 4002 void Parser::CheckConflictingVarDeclarations(Scope* scope, bool* ok) { |
3957 Declaration* decl = scope->CheckConflictingVarDeclarations(); | 4003 Declaration* decl = scope->CheckConflictingVarDeclarations(); |
3958 if (decl != NULL) { | 4004 if (decl != NULL) { |
3959 // In harmony mode we treat conflicting variable bindinds as early | 4005 // In harmony mode we treat conflicting variable bindinds as early |
3960 // errors. See ES5 16 for a definition of early errors. | 4006 // errors. See ES5 16 for a definition of early errors. |
3961 Handle<String> name = decl->proxy()->name(); | 4007 Handle<String> name = decl->proxy()->name(); |
3962 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); | 4008 SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS); |
3963 const char* elms[2] = { "Variable", c_string.get() }; | 4009 const char* elms[2] = { "Variable", c_string.get() }; |
3964 Vector<const char*> args(elms, 2); | 4010 Vector<const char*> args(elms, 2); |
3965 int position = decl->proxy()->position(); | 4011 int position = decl->proxy()->position(); |
(...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5029 ASSERT(info()->isolate()->has_pending_exception()); | 5075 ASSERT(info()->isolate()->has_pending_exception()); |
5030 } else { | 5076 } else { |
5031 result = ParseProgram(); | 5077 result = ParseProgram(); |
5032 } | 5078 } |
5033 } | 5079 } |
5034 info()->SetFunction(result); | 5080 info()->SetFunction(result); |
5035 return (result != NULL); | 5081 return (result != NULL); |
5036 } | 5082 } |
5037 | 5083 |
5038 } } // namespace v8::internal | 5084 } } // namespace v8::internal |
OLD | NEW |