Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(540)

Side by Side Diff: src/parser.cc

Issue 199233003: Revert "Move ParseAssignmentExpression to ParserBase." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698