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

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: clang build fixes 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 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 426
427 bool ParserTraits::IsThisProperty(Expression* expression) { 427 bool ParserTraits::IsThisProperty(Expression* expression) {
428 ASSERT(expression != NULL); 428 ASSERT(expression != NULL);
429 Property* property = expression->AsProperty(); 429 Property* property = expression->AsProperty();
430 return property != NULL && 430 return property != NULL &&
431 property->obj()->AsVariableProxy() != NULL && 431 property->obj()->AsVariableProxy() != NULL &&
432 property->obj()->AsVariableProxy()->is_this(); 432 property->obj()->AsVariableProxy()->is_this();
433 } 433 }
434 434
435 435
436 bool ParserTraits::IsIdentifier(Expression* expression) {
437 VariableProxy* operand = expression->AsVariableProxy();
438 return operand != NULL && !operand->is_this();
439 }
440
441
436 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, 442 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left,
437 Expression* right) { 443 Expression* right) {
438 ASSERT(left != NULL); 444 ASSERT(left != NULL);
439 if (left->AsProperty() != NULL && 445 if (left->AsProperty() != NULL &&
440 right->AsFunctionLiteral() != NULL) { 446 right->AsFunctionLiteral() != NULL) {
441 right->AsFunctionLiteral()->set_pretenure(); 447 right->AsFunctionLiteral()->set_pretenure();
442 } 448 }
443 } 449 }
444 450
445 451
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 return true; 524 return true;
519 } 525 }
520 default: 526 default:
521 break; 527 break;
522 } 528 }
523 } 529 }
524 return false; 530 return false;
525 } 531 }
526 532
527 533
534 Expression* ParserTraits::BuildUnaryExpression(
535 Expression* expression, Token::Value op, int pos,
536 AstNodeFactory<AstConstructionVisitor>* factory) {
537 ASSERT(expression != NULL);
538 if (expression->AsLiteral() != NULL) {
539 Handle<Object> literal = expression->AsLiteral()->value();
540 if (op == Token::NOT) {
541 // Convert the literal to a boolean condition and negate it.
542 bool condition = literal->BooleanValue();
543 Handle<Object> result =
544 parser_->isolate()->factory()->ToBoolean(!condition);
545 return factory->NewLiteral(result, pos);
546 } else if (literal->IsNumber()) {
547 // Compute some expressions involving only number literals.
548 double value = literal->Number();
549 switch (op) {
550 case Token::ADD:
551 return expression;
552 case Token::SUB:
553 return factory->NewNumberLiteral(-value, pos);
554 case Token::BIT_NOT:
555 return factory->NewNumberLiteral(~DoubleToInt32(value), pos);
556 default:
557 break;
558 }
559 }
560 }
561 // Desugar '+foo' => 'foo*1'
562 if (op == Token::ADD) {
563 return factory->NewBinaryOperation(
564 Token::MUL, expression, factory->NewNumberLiteral(1, pos), pos);
565 }
566 // The same idea for '-foo' => 'foo*(-1)'.
567 if (op == Token::SUB) {
568 return factory->NewBinaryOperation(
569 Token::MUL, expression, factory->NewNumberLiteral(-1, pos), pos);
570 }
571 // ...and one more time for '~foo' => 'foo^(~0)'.
572 if (op == Token::BIT_NOT) {
573 return factory->NewBinaryOperation(
574 Token::BIT_XOR, expression, factory->NewNumberLiteral(~0, pos), pos);
575 }
576 return factory->NewUnaryOperation(op, expression, pos);
577 }
578
579
528 void ParserTraits::ReportMessageAt(Scanner::Location source_location, 580 void ParserTraits::ReportMessageAt(Scanner::Location source_location,
529 const char* message, 581 const char* message,
530 Vector<const char*> args, 582 Vector<const char*> args,
531 bool is_reference_error) { 583 bool is_reference_error) {
532 if (parser_->stack_overflow()) { 584 if (parser_->stack_overflow()) {
533 // Suppress the error message (syntax error or such) in the presence of a 585 // Suppress the error message (syntax error or such) in the presence of a
534 // stack overflow. The isolate allows only one pending exception at at time 586 // stack overflow. The isolate allows only one pending exception at at time
535 // and we want to report the stack overflow later. 587 // and we want to report the stack overflow later.
536 return; 588 return;
537 } 589 }
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 bool is_generator, 733 bool is_generator,
682 int function_token_position, 734 int function_token_position,
683 FunctionLiteral::FunctionType type, 735 FunctionLiteral::FunctionType type,
684 bool* ok) { 736 bool* ok) {
685 return parser_->ParseFunctionLiteral(name, function_name_location, 737 return parser_->ParseFunctionLiteral(name, function_name_location,
686 name_is_strict_reserved, is_generator, 738 name_is_strict_reserved, is_generator,
687 function_token_position, type, ok); 739 function_token_position, type, ok);
688 } 740 }
689 741
690 742
691 Expression* ParserTraits::ParseUnaryExpression(bool* ok) { 743 Expression* ParserTraits::ParsePostfixExpression(bool* ok) {
692 return parser_->ParseUnaryExpression(ok); 744 return parser_->ParsePostfixExpression(ok);
693 } 745 }
694 746
695 747
696 Parser::Parser(CompilationInfo* info) 748 Parser::Parser(CompilationInfo* info)
697 : ParserBase<ParserTraits>(&scanner_, 749 : ParserBase<ParserTraits>(&scanner_,
698 info->isolate()->stack_guard()->real_climit(), 750 info->isolate()->stack_guard()->real_climit(),
699 info->extension(), 751 info->extension(),
700 NULL, 752 NULL,
701 info->zone(), 753 info->zone(),
702 this), 754 this),
(...skipping 2280 matching lines...) Expand 10 before | Expand all | Expand 10 after
2983 result->set_scope(for_scope); 3035 result->set_scope(for_scope);
2984 loop->Initialize(NULL, cond, next, body); 3036 loop->Initialize(NULL, cond, next, body);
2985 return result; 3037 return result;
2986 } else { 3038 } else {
2987 loop->Initialize(init, cond, next, body); 3039 loop->Initialize(init, cond, next, body);
2988 return loop; 3040 return loop;
2989 } 3041 }
2990 } 3042 }
2991 3043
2992 3044
2993 Expression* Parser::ParseUnaryExpression(bool* ok) {
2994 // UnaryExpression ::
2995 // PostfixExpression
2996 // 'delete' UnaryExpression
2997 // 'void' UnaryExpression
2998 // 'typeof' UnaryExpression
2999 // '++' UnaryExpression
3000 // '--' UnaryExpression
3001 // '+' UnaryExpression
3002 // '-' UnaryExpression
3003 // '~' UnaryExpression
3004 // '!' UnaryExpression
3005
3006 Token::Value op = peek();
3007 if (Token::IsUnaryOp(op)) {
3008 op = Next();
3009 int pos = position();
3010 Expression* expression = ParseUnaryExpression(CHECK_OK);
3011
3012 if (expression != NULL && (expression->AsLiteral() != NULL)) {
3013 Handle<Object> literal = expression->AsLiteral()->value();
3014 if (op == Token::NOT) {
3015 // Convert the literal to a boolean condition and negate it.
3016 bool condition = literal->BooleanValue();
3017 Handle<Object> result = isolate()->factory()->ToBoolean(!condition);
3018 return factory()->NewLiteral(result, pos);
3019 } else if (literal->IsNumber()) {
3020 // Compute some expressions involving only number literals.
3021 double value = literal->Number();
3022 switch (op) {
3023 case Token::ADD:
3024 return expression;
3025 case Token::SUB:
3026 return factory()->NewNumberLiteral(-value, pos);
3027 case Token::BIT_NOT:
3028 return factory()->NewNumberLiteral(~DoubleToInt32(value), pos);
3029 default:
3030 break;
3031 }
3032 }
3033 }
3034
3035 // "delete identifier" is a syntax error in strict mode.
3036 if (op == Token::DELETE && strict_mode() == STRICT) {
3037 VariableProxy* operand = expression->AsVariableProxy();
3038 if (operand != NULL && !operand->is_this()) {
3039 ReportMessage("strict_delete", Vector<const char*>::empty());
3040 *ok = false;
3041 return NULL;
3042 }
3043 }
3044
3045 // Desugar '+foo' into 'foo*1', this enables the collection of type feedback
3046 // without any special stub and the multiplication is removed later in
3047 // Crankshaft's canonicalization pass.
3048 if (op == Token::ADD) {
3049 return factory()->NewBinaryOperation(Token::MUL,
3050 expression,
3051 factory()->NewNumberLiteral(1, pos),
3052 pos);
3053 }
3054 // The same idea for '-foo' => 'foo*(-1)'.
3055 if (op == Token::SUB) {
3056 return factory()->NewBinaryOperation(Token::MUL,
3057 expression,
3058 factory()->NewNumberLiteral(-1, pos),
3059 pos);
3060 }
3061 // ...and one more time for '~foo' => 'foo^(~0)'.
3062 if (op == Token::BIT_NOT) {
3063 return factory()->NewBinaryOperation(Token::BIT_XOR,
3064 expression,
3065 factory()->NewNumberLiteral(~0, pos),
3066 pos);
3067 }
3068
3069 return factory()->NewUnaryOperation(op, expression, pos);
3070
3071 } else if (Token::IsCountOp(op)) {
3072 op = Next();
3073 Scanner::Location lhs_location = scanner()->peek_location();
3074 Expression* expression = ParseUnaryExpression(CHECK_OK);
3075 if (expression == NULL || !expression->IsValidLeftHandSide()) {
3076 ReportMessageAt(lhs_location, "invalid_lhs_in_prefix_op", true);
3077 *ok = false;
3078 return NULL;
3079 }
3080
3081 if (strict_mode() == STRICT) {
3082 // Prefix expression operand in strict mode may not be eval or arguments.
3083 CheckStrictModeLValue(expression, CHECK_OK);
3084 }
3085 MarkExpressionAsLValue(expression);
3086
3087 return factory()->NewCountOperation(op,
3088 true /* prefix */,
3089 expression,
3090 position());
3091
3092 } else {
3093 return ParsePostfixExpression(ok);
3094 }
3095 }
3096
3097
3098 Expression* Parser::ParsePostfixExpression(bool* ok) { 3045 Expression* Parser::ParsePostfixExpression(bool* ok) {
3099 // PostfixExpression :: 3046 // PostfixExpression ::
3100 // LeftHandSideExpression ('++' | '--')? 3047 // LeftHandSideExpression ('++' | '--')?
3101 3048
3102 Scanner::Location lhs_location = scanner()->peek_location(); 3049 Scanner::Location lhs_location = scanner()->peek_location();
3103 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); 3050 Expression* expression = ParseLeftHandSideExpression(CHECK_OK);
3104 if (!scanner()->HasAnyLineTerminatorBeforeNext() && 3051 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
3105 Token::IsCountOp(peek())) { 3052 Token::IsCountOp(peek())) {
3106 if (expression == NULL || !expression->IsValidLeftHandSide()) { 3053 if (expression == NULL || !expression->IsValidLeftHandSide()) {
3107 ReportMessageAt(lhs_location, "invalid_lhs_in_postfix_op", true); 3054 ReportMessageAt(lhs_location, "invalid_lhs_in_postfix_op", true);
(...skipping 1843 matching lines...) Expand 10 before | Expand all | Expand 10 after
4951 ASSERT(info()->isolate()->has_pending_exception()); 4898 ASSERT(info()->isolate()->has_pending_exception());
4952 } else { 4899 } else {
4953 result = ParseProgram(); 4900 result = ParseProgram();
4954 } 4901 }
4955 } 4902 }
4956 info()->SetFunction(result); 4903 info()->SetFunction(result);
4957 return (result != NULL); 4904 return (result != NULL);
4958 } 4905 }
4959 4906
4960 } } // namespace v8::internal 4907 } } // 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