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

Side by Side Diff: src/parser.cc

Issue 203193004: Move ParseUnaryExpression into ParserBase and add tests. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: oops 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
« src/parser.h ('K') | « 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 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 439
440 bool ParserTraits::IsThisProperty(Expression* expression) { 440 bool ParserTraits::IsThisProperty(Expression* expression) {
441 ASSERT(expression != NULL); 441 ASSERT(expression != NULL);
442 Property* property = expression->AsProperty(); 442 Property* property = expression->AsProperty();
443 return property != NULL && 443 return property != NULL &&
444 property->obj()->AsVariableProxy() != NULL && 444 property->obj()->AsVariableProxy() != NULL &&
445 property->obj()->AsVariableProxy()->is_this(); 445 property->obj()->AsVariableProxy()->is_this();
446 } 446 }
447 447
448 448
449 bool ParserTraits::IsIdentifier(Expression* expression) {
450 VariableProxy* operand = expression->AsVariableProxy();
451 return operand != NULL && !operand->is_this();
452 }
453
454
449 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, 455 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
450 Expression* right) { 456 Expression* right) {
451 ASSERT(left != NULL); 457 ASSERT(left != NULL);
452 if (left->AsProperty() != NULL && 458 if (left->AsProperty() != NULL &&
453 right->AsFunctionLiteral() != NULL) { 459 right->AsFunctionLiteral() != NULL) {
454 right->AsFunctionLiteral()->set_pretenure(); 460 right->AsFunctionLiteral()->set_pretenure();
455 } 461 }
456 } 462 }
457 463
458 464
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 return true; 537 return true;
532 } 538 }
533 default: 539 default:
534 break; 540 break;
535 } 541 }
536 } 542 }
537 return false; 543 return false;
538 } 544 }
539 545
540 546
547 bool ParserTraits::ShortcutLiteralUnaryExpression(
548 Expression** expression, Token::Value op, int pos,
549 AstNodeFactory<AstConstructionVisitor>* factory) {
550 ASSERT(expression != NULL && *expression != NULL);
551 if ((*expression)->AsLiteral() != NULL) {
552 Handle<Object> literal = (*expression)->AsLiteral()->value();
553 if (op == Token::NOT) {
554 // Convert the literal to a boolean condition and negate it.
555 bool condition = literal->BooleanValue();
556 Handle<Object> result =
557 parser_->isolate()->factory()->ToBoolean(!condition);
558 *expression = factory->NewLiteral(result, pos);
559 return true;
560 } else if (literal->IsNumber()) {
561 // Compute some expressions involving only number literals.
562 double value = literal->Number();
563 switch (op) {
564 case Token::ADD:
565 return true;
566 case Token::SUB:
567 *expression = factory->NewNumberLiteral(-value, pos);
568 return true;
569 case Token::BIT_NOT:
570 *expression = factory->NewNumberLiteral(~DoubleToInt32(value), pos);
571 return true;
572 default:
573 break;
574 }
575 }
576 }
577 return false;
578 }
579
580
581 bool ParserTraits::AddUnaryExpressionTypeFeedback(
582 Expression** expression, Token::Value op, int pos,
583 AstNodeFactory<AstConstructionVisitor>* factory) {
584 // Desugar '+foo' => 'foo*1'
585 if (op == Token::ADD) {
586 *expression = factory->NewBinaryOperation(
587 Token::MUL, *expression, factory->NewNumberLiteral(1, pos), pos);
588 return true;
589 }
590 // The same idea for '-foo' => 'foo*(-1)'.
591 if (op == Token::SUB) {
592 *expression = factory->NewBinaryOperation(
593 Token::MUL, *expression, factory->NewNumberLiteral(-1, pos), pos);
594 return true;
595 }
596 // ...and one more time for '~foo' => 'foo^(~0)'.
597 if (op == Token::BIT_NOT) {
598 *expression = factory->NewBinaryOperation(
599 Token::BIT_XOR, *expression, factory->NewNumberLiteral(~0, pos), pos);
600 return true;
601 }
602 return false;
603 }
604
605
541 void ParserTraits::ReportMessageAt(Scanner::Location source_location, 606 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
542 const char* message, 607 const char* message,
543 Vector<const char*> args, 608 Vector<const char*> args,
544 bool is_reference_error) { 609 bool is_reference_error) {
545 if (parser_->stack_overflow()) { 610 if (parser_->stack_overflow()) {
546 // Suppress the error message (syntax error or such) in the presence of a 611 // Suppress the error message (syntax error or such) in the presence of a
547 // stack overflow. The isolate allows only one pending exception at at time 612 // stack overflow. The isolate allows only one pending exception at at time
548 // and we want to report the stack overflow later. 613 // and we want to report the stack overflow later.
549 return; 614 return;
550 } 615 }
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 bool is_generator, 751 bool is_generator,
687 int function_token_position, 752 int function_token_position,
688 FunctionLiteral::FunctionType type, 753 FunctionLiteral::FunctionType type,
689 bool* ok) { 754 bool* ok) {
690 return parser_->ParseFunctionLiteral(name, function_name_location, 755 return parser_->ParseFunctionLiteral(name, function_name_location,
691 name_is_strict_reserved, is_generator, 756 name_is_strict_reserved, is_generator,
692 function_token_position, type, ok); 757 function_token_position, type, ok);
693 } 758 }
694 759
695 760
696 Expression* ParserTraits::ParseUnaryExpression(bool* ok) { 761 Expression* ParserTraits::ParsePostfixExpression(bool* ok) {
697 return parser_->ParseUnaryExpression(ok); 762 return parser_->ParsePostfixExpression(ok);
698 } 763 }
699 764
700 765
701 Parser::Parser(CompilationInfo* info) 766 Parser::Parser(CompilationInfo* info)
702 : ParserBase<ParserTraits>(&scanner_, 767 : ParserBase<ParserTraits>(&scanner_,
703 info->isolate()->stack_guard()->real_climit(), 768 info->isolate()->stack_guard()->real_climit(),
704 info->extension(), 769 info->extension(),
705 info->zone(), 770 info->zone(),
706 this), 771 this),
707 isolate_(info->isolate()), 772 isolate_(info->isolate()),
(...skipping 2267 matching lines...) Expand 10 before | Expand all | Expand 10 after
2975 result->set_scope(for_scope); 3040 result->set_scope(for_scope);
2976 loop->Initialize(NULL, cond, next, body); 3041 loop->Initialize(NULL, cond, next, body);
2977 return result; 3042 return result;
2978 } else { 3043 } else {
2979 loop->Initialize(init, cond, next, body); 3044 loop->Initialize(init, cond, next, body);
2980 return loop; 3045 return loop;
2981 } 3046 }
2982 } 3047 }
2983 3048
2984 3049
2985 Expression* Parser::ParseUnaryExpression(bool* ok) {
2986 // UnaryExpression ::
2987 // PostfixExpression
2988 // 'delete' UnaryExpression
2989 // 'void' UnaryExpression
2990 // 'typeof' UnaryExpression
2991 // '++' UnaryExpression
2992 // '--' UnaryExpression
2993 // '+' UnaryExpression
2994 // '-' UnaryExpression
2995 // '~' UnaryExpression
2996 // '!' UnaryExpression
2997
2998 Token::Value op = peek();
2999 if (Token::IsUnaryOp(op)) {
3000 op = Next();
3001 int pos = position();
3002 Expression* expression = ParseUnaryExpression(CHECK_OK);
3003
3004 if (expression != NULL && (expression->AsLiteral() != NULL)) {
3005 Handle<Object> literal = expression->AsLiteral()->value();
3006 if (op == Token::NOT) {
3007 // Convert the literal to a boolean condition and negate it.
3008 bool condition = literal->BooleanValue();
3009 Handle<Object> result = isolate()->factory()->ToBoolean(!condition);
3010 return factory()->NewLiteral(result, pos);
3011 } else if (literal->IsNumber()) {
3012 // Compute some expressions involving only number literals.
3013 double value = literal->Number();
3014 switch (op) {
3015 case Token::ADD:
3016 return expression;
3017 case Token::SUB:
3018 return factory()->NewNumberLiteral(-value, pos);
3019 case Token::BIT_NOT:
3020 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
3021 default:
3022 break;
3023 }
3024 }
3025 }
3026
3027 // "delete identifier" is a syntax error in strict mode.
3028 if (op == Token::DELETE && strict_mode() == STRICT) {
3029 VariableProxy* operand = expression->AsVariableProxy();
3030 if (operand != NULL && !operand->is_this()) {
3031 ReportMessage("strict_delete", Vector<const char*>::empty());
3032 *ok = false;
3033 return NULL;
3034 }
3035 }
3036
3037 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback
3038 // without any special stub and the multiplication is removed later in
3039 // Crankshaft's canonicalization pass.
3040 if (op == Token::ADD) {
3041 return factory()->NewBinaryOperation(Token::MUL,
3042 expression,
3043 factory()->NewNumberLiteral(1, pos),
3044 pos);
3045 }
3046 // The same idea for '-foo' => 'foo*(-1)'.
3047 if (op == Token::SUB) {
3048 return factory()->NewBinaryOperation(Token::MUL,
3049 expression,
3050 factory()->NewNumberLiteral(-1, pos),
3051 pos);
3052 }
3053 // ...and one more time for '~foo' => 'foo^(~0)'.
3054 if (op == Token::BIT_NOT) {
3055 return factory()->NewBinaryOperation(Token::BIT_XOR,
3056 expression,
3057 factory()->NewNumberLiteral(~0, pos),
3058 pos);
3059 }
3060
3061 return factory()->NewUnaryOperation(op, expression, pos);
3062
3063 } else if (Token::IsCountOp(op)) {
3064 op = Next();
3065 Scanner::Location lhs_location = scanner()->peek_location();
3066 Expression* expression = ParseUnaryExpression(CHECK_OK);
3067 if (expression == NULL || !expression->IsValidLeftHandSide()) {
3068 ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true);
3069 *ok = false;
3070 return NULL;
3071 }
3072
3073 if (strict_mode() == STRICT) {
3074 // Prefix expression operand in strict mode may not be eval or arguments.
3075 CheckStrictModeLValue(expression, CHECK_OK);
3076 }
3077 MarkExpressionAsLValue(expression);
3078
3079 return factory()->NewCountOperation(op,
3080 true /* prefix */,
3081 expression,
3082 position());
3083
3084 } else {
3085 return ParsePostfixExpression(ok);
3086 }
3087 }
3088
3089
3090 Expression* Parser::ParsePostfixExpression(bool* ok) { 3050 Expression* Parser::ParsePostfixExpression(bool* ok) {
3091 // PostfixExpression :: 3051 // PostfixExpression ::
3092 // LeftHandSideExpression ('++' | '--')? 3052 // LeftHandSideExpression ('++' | '--')?
3093 3053
3094 Scanner::Location lhs_location = scanner()->peek_location(); 3054 Scanner::Location lhs_location = scanner()->peek_location();
3095 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); 3055 Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
3096 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 3056 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
3097 Token::IsCountOp(peek())) { 3057 Token::IsCountOp(peek())) {
3098 if (expression == NULL || !expression->IsValidLeftHandSide()) { 3058 if (expression == NULL || !expression->IsValidLeftHandSide()) {
3099 ReportMessageAt(lhs_location, "invalid_lhs_in_postfix_op", true); 3059 ReportMessageAt(lhs_location, "invalid_lhs_in_postfix_op", true);
(...skipping 1837 matching lines...) Expand 10 before | Expand all | Expand 10 after
4937 ASSERT(info()->isolate()->has_pending_exception()); 4897 ASSERT(info()->isolate()->has_pending_exception());
4938 } else { 4898 } else {
4939 result = ParseProgram(); 4899 result = ParseProgram();
4940 } 4900 }
4941 } 4901 }
4942 info()->SetFunction(result); 4902 info()->SetFunction(result);
4943 return (result != NULL); 4903 return (result != NULL);
4944 } 4904 }
4945 4905
4946 } } // namespace v8::internal 4906 } } // namespace v8::internal
OLDNEW
« src/parser.h ('K') | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698