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 | |
442 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, | 436 void ParserTraits::CheckAssigningFunctionLiteralToProperty(Expression* left, |
443 Expression* right) { | 437 Expression* right) { |
444 ASSERT(left != NULL); | 438 ASSERT(left != NULL); |
445 if (left->AsProperty() != NULL && | 439 if (left->AsProperty() != NULL && |
446 right->AsFunctionLiteral() != NULL) { | 440 right->AsFunctionLiteral() != NULL) { |
447 right->AsFunctionLiteral()->set_pretenure(); | 441 right->AsFunctionLiteral()->set_pretenure(); |
448 } | 442 } |
449 } | 443 } |
450 | 444 |
451 | 445 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 return true; | 518 return true; |
525 } | 519 } |
526 default: | 520 default: |
527 break; | 521 break; |
528 } | 522 } |
529 } | 523 } |
530 return false; | 524 return false; |
531 } | 525 } |
532 | 526 |
533 | 527 |
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 | |
580 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 528 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
581 const char* message, | 529 const char* message, |
582 Vector<const char*> args, | 530 Vector<const char*> args, |
583 bool is_reference_error) { | 531 bool is_reference_error) { |
584 if (parser_->stack_overflow()) { | 532 if (parser_->stack_overflow()) { |
585 // Suppress the error message (syntax error or such) in the presence of a | 533 // Suppress the error message (syntax error or such) in the presence of a |
586 // stack overflow. The isolate allows only one pending exception at at time | 534 // stack overflow. The isolate allows only one pending exception at at time |
587 // and we want to report the stack overflow later. | 535 // and we want to report the stack overflow later. |
588 return; | 536 return; |
589 } | 537 } |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 bool is_generator, | 681 bool is_generator, |
734 int function_token_position, | 682 int function_token_position, |
735 FunctionLiteral::FunctionType type, | 683 FunctionLiteral::FunctionType type, |
736 bool* ok) { | 684 bool* ok) { |
737 return parser_->ParseFunctionLiteral(name, function_name_location, | 685 return parser_->ParseFunctionLiteral(name, function_name_location, |
738 name_is_strict_reserved, is_generator, | 686 name_is_strict_reserved, is_generator, |
739 function_token_position, type, ok); | 687 function_token_position, type, ok); |
740 } | 688 } |
741 | 689 |
742 | 690 |
743 Expression* ParserTraits::ParsePostfixExpression(bool* ok) { | 691 Expression* ParserTraits::ParseUnaryExpression(bool* ok) { |
744 return parser_->ParsePostfixExpression(ok); | 692 return parser_->ParseUnaryExpression(ok); |
745 } | 693 } |
746 | 694 |
747 | 695 |
748 Parser::Parser(CompilationInfo* info) | 696 Parser::Parser(CompilationInfo* info) |
749 : ParserBase<ParserTraits>(&scanner_, | 697 : ParserBase<ParserTraits>(&scanner_, |
750 info->isolate()->stack_guard()->real_climit(), | 698 info->isolate()->stack_guard()->real_climit(), |
751 info->extension(), | 699 info->extension(), |
752 NULL, | 700 NULL, |
753 info->zone(), | 701 info->zone(), |
754 this), | 702 this), |
(...skipping 2280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3035 result->set_scope(for_scope); | 2983 result->set_scope(for_scope); |
3036 loop->Initialize(NULL, cond, next, body); | 2984 loop->Initialize(NULL, cond, next, body); |
3037 return result; | 2985 return result; |
3038 } else { | 2986 } else { |
3039 loop->Initialize(init, cond, next, body); | 2987 loop->Initialize(init, cond, next, body); |
3040 return loop; | 2988 return loop; |
3041 } | 2989 } |
3042 } | 2990 } |
3043 | 2991 |
3044 | 2992 |
| 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 |
3045 Expression* Parser::ParsePostfixExpression(bool* ok) { | 3098 Expression* Parser::ParsePostfixExpression(bool* ok) { |
3046 // PostfixExpression :: | 3099 // PostfixExpression :: |
3047 // LeftHandSideExpression ('++' | '--')? | 3100 // LeftHandSideExpression ('++' | '--')? |
3048 | 3101 |
3049 Scanner::Location lhs_location = scanner()->peek_location(); | 3102 Scanner::Location lhs_location = scanner()->peek_location(); |
3050 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); | 3103 Expression* expression = ParseLeftHandSideExpression(CHECK_OK); |
3051 if (!scanner()->HasAnyLineTerminatorBeforeNext() && | 3104 if (!scanner()->HasAnyLineTerminatorBeforeNext() && |
3052 Token::IsCountOp(peek())) { | 3105 Token::IsCountOp(peek())) { |
3053 if (expression == NULL || !expression->IsValidLeftHandSide()) { | 3106 if (expression == NULL || !expression->IsValidLeftHandSide()) { |
3054 ReportMessageAt(lhs_location, "invalid_lhs_in_postfix_op", true); | 3107 ReportMessageAt(lhs_location, "invalid_lhs_in_postfix_op", true); |
(...skipping 1843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4898 ASSERT(info()->isolate()->has_pending_exception()); | 4951 ASSERT(info()->isolate()->has_pending_exception()); |
4899 } else { | 4952 } else { |
4900 result = ParseProgram(); | 4953 result = ParseProgram(); |
4901 } | 4954 } |
4902 } | 4955 } |
4903 info()->SetFunction(result); | 4956 info()->SetFunction(result); |
4904 return (result != NULL); | 4957 return (result != NULL); |
4905 } | 4958 } |
4906 | 4959 |
4907 } } // namespace v8::internal | 4960 } } // namespace v8::internal |
OLD | NEW |