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 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |