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