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 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 ? expression->AsVariableProxy() | 483 ? expression->AsVariableProxy() |
484 : NULL; | 484 : NULL; |
485 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { | 485 if (lhs != NULL && !lhs->is_this() && IsEvalOrArguments(lhs->name())) { |
486 parser_->ReportMessage("strict_eval_arguments", | 486 parser_->ReportMessage("strict_eval_arguments", |
487 Vector<const char*>::empty()); | 487 Vector<const char*>::empty()); |
488 *ok = false; | 488 *ok = false; |
489 } | 489 } |
490 } | 490 } |
491 | 491 |
492 | 492 |
| 493 bool ParserTraits::ShortcutNumericLiteralBinaryExpression( |
| 494 Expression** x, Expression* y, Token::Value op, int pos, |
| 495 AstNodeFactory<AstConstructionVisitor>* factory) { |
| 496 if ((*x)->AsLiteral() && (*x)->AsLiteral()->value()->IsNumber() && |
| 497 y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { |
| 498 double x_val = (*x)->AsLiteral()->value()->Number(); |
| 499 double y_val = y->AsLiteral()->value()->Number(); |
| 500 switch (op) { |
| 501 case Token::ADD: |
| 502 *x = factory->NewNumberLiteral(x_val + y_val, pos); |
| 503 return true; |
| 504 case Token::SUB: |
| 505 *x = factory->NewNumberLiteral(x_val - y_val, pos); |
| 506 return true; |
| 507 case Token::MUL: |
| 508 *x = factory->NewNumberLiteral(x_val * y_val, pos); |
| 509 return true; |
| 510 case Token::DIV: |
| 511 *x = factory->NewNumberLiteral(x_val / y_val, pos); |
| 512 return true; |
| 513 case Token::BIT_OR: { |
| 514 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); |
| 515 *x = factory->NewNumberLiteral(value, pos); |
| 516 return true; |
| 517 } |
| 518 case Token::BIT_AND: { |
| 519 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); |
| 520 *x = factory->NewNumberLiteral(value, pos); |
| 521 return true; |
| 522 } |
| 523 case Token::BIT_XOR: { |
| 524 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); |
| 525 *x = factory->NewNumberLiteral(value, pos); |
| 526 return true; |
| 527 } |
| 528 case Token::SHL: { |
| 529 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); |
| 530 *x = factory->NewNumberLiteral(value, pos); |
| 531 return true; |
| 532 } |
| 533 case Token::SHR: { |
| 534 uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
| 535 uint32_t value = DoubleToUint32(x_val) >> shift; |
| 536 *x = factory->NewNumberLiteral(value, pos); |
| 537 return true; |
| 538 } |
| 539 case Token::SAR: { |
| 540 uint32_t shift = DoubleToInt32(y_val) & 0x1f; |
| 541 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); |
| 542 *x = factory->NewNumberLiteral(value, pos); |
| 543 return true; |
| 544 } |
| 545 default: |
| 546 break; |
| 547 } |
| 548 } |
| 549 return false; |
| 550 } |
| 551 |
| 552 |
493 void ParserTraits::ReportMessageAt(Scanner::Location source_location, | 553 void ParserTraits::ReportMessageAt(Scanner::Location source_location, |
494 const char* message, | 554 const char* message, |
495 Vector<const char*> args) { | 555 Vector<const char*> args) { |
496 if (parser_->stack_overflow()) { | 556 if (parser_->stack_overflow()) { |
497 // Suppress the error message (syntax error or such) in the presence of a | 557 // Suppress the error message (syntax error or such) in the presence of a |
498 // stack overflow. The isolate allows only one pending exception at at time | 558 // stack overflow. The isolate allows only one pending exception at at time |
499 // and we want to report the stack overflow later. | 559 // and we want to report the stack overflow later. |
500 return; | 560 return; |
501 } | 561 } |
502 MessageLocation location(parser_->script_, | 562 MessageLocation location(parser_->script_, |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
631 bool is_generator, | 691 bool is_generator, |
632 int function_token_position, | 692 int function_token_position, |
633 FunctionLiteral::FunctionType type, | 693 FunctionLiteral::FunctionType type, |
634 bool* ok) { | 694 bool* ok) { |
635 return parser_->ParseFunctionLiteral(name, function_name_location, | 695 return parser_->ParseFunctionLiteral(name, function_name_location, |
636 name_is_strict_reserved, is_generator, | 696 name_is_strict_reserved, is_generator, |
637 function_token_position, type, ok); | 697 function_token_position, type, ok); |
638 } | 698 } |
639 | 699 |
640 | 700 |
641 Expression* ParserTraits::ParseBinaryExpression(int prec, bool accept_IN, | 701 Expression* ParserTraits::ParseUnaryExpression(bool* ok) { |
642 bool* ok) { | 702 return parser_->ParseUnaryExpression(ok); |
643 return parser_->ParseBinaryExpression(prec, accept_IN, ok); | |
644 } | 703 } |
645 | 704 |
646 | 705 |
647 Parser::Parser(CompilationInfo* info) | 706 Parser::Parser(CompilationInfo* info) |
648 : ParserBase<ParserTraits>(&scanner_, | 707 : ParserBase<ParserTraits>(&scanner_, |
649 info->isolate()->stack_guard()->real_climit(), | 708 info->isolate()->stack_guard()->real_climit(), |
650 info->extension(), | 709 info->extension(), |
651 info->zone(), | 710 info->zone(), |
652 this), | 711 this), |
653 isolate_(info->isolate()), | 712 isolate_(info->isolate()), |
(...skipping 2270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2924 result->set_scope(for_scope); | 2983 result->set_scope(for_scope); |
2925 loop->Initialize(NULL, cond, next, body); | 2984 loop->Initialize(NULL, cond, next, body); |
2926 return result; | 2985 return result; |
2927 } else { | 2986 } else { |
2928 loop->Initialize(init, cond, next, body); | 2987 loop->Initialize(init, cond, next, body); |
2929 return loop; | 2988 return loop; |
2930 } | 2989 } |
2931 } | 2990 } |
2932 | 2991 |
2933 | 2992 |
2934 // Precedence >= 4 | |
2935 Expression* Parser::ParseBinaryExpression(int prec, bool accept_IN, bool* ok) { | |
2936 ASSERT(prec >= 4); | |
2937 Expression* x = ParseUnaryExpression(CHECK_OK); | |
2938 for (int prec1 = Precedence(peek(), accept_IN); prec1 >= prec; prec1--) { | |
2939 // prec1 >= 4 | |
2940 while (Precedence(peek(), accept_IN) == prec1) { | |
2941 Token::Value op = Next(); | |
2942 int pos = position(); | |
2943 Expression* y = ParseBinaryExpression(prec1 + 1, accept_IN, CHECK_OK); | |
2944 | |
2945 // Compute some expressions involving only number literals. | |
2946 if (x && x->AsLiteral() && x->AsLiteral()->value()->IsNumber() && | |
2947 y && y->AsLiteral() && y->AsLiteral()->value()->IsNumber()) { | |
2948 double x_val = x->AsLiteral()->value()->Number(); | |
2949 double y_val = y->AsLiteral()->value()->Number(); | |
2950 | |
2951 switch (op) { | |
2952 case Token::ADD: | |
2953 x = factory()->NewNumberLiteral(x_val + y_val, pos); | |
2954 continue; | |
2955 case Token::SUB: | |
2956 x = factory()->NewNumberLiteral(x_val - y_val, pos); | |
2957 continue; | |
2958 case Token::MUL: | |
2959 x = factory()->NewNumberLiteral(x_val * y_val, pos); | |
2960 continue; | |
2961 case Token::DIV: | |
2962 x = factory()->NewNumberLiteral(x_val / y_val, pos); | |
2963 continue; | |
2964 case Token::BIT_OR: { | |
2965 int value = DoubleToInt32(x_val) | DoubleToInt32(y_val); | |
2966 x = factory()->NewNumberLiteral(value, pos); | |
2967 continue; | |
2968 } | |
2969 case Token::BIT_AND: { | |
2970 int value = DoubleToInt32(x_val) & DoubleToInt32(y_val); | |
2971 x = factory()->NewNumberLiteral(value, pos); | |
2972 continue; | |
2973 } | |
2974 case Token::BIT_XOR: { | |
2975 int value = DoubleToInt32(x_val) ^ DoubleToInt32(y_val); | |
2976 x = factory()->NewNumberLiteral(value, pos); | |
2977 continue; | |
2978 } | |
2979 case Token::SHL: { | |
2980 int value = DoubleToInt32(x_val) << (DoubleToInt32(y_val) & 0x1f); | |
2981 x = factory()->NewNumberLiteral(value, pos); | |
2982 continue; | |
2983 } | |
2984 case Token::SHR: { | |
2985 uint32_t shift = DoubleToInt32(y_val) & 0x1f; | |
2986 uint32_t value = DoubleToUint32(x_val) >> shift; | |
2987 x = factory()->NewNumberLiteral(value, pos); | |
2988 continue; | |
2989 } | |
2990 case Token::SAR: { | |
2991 uint32_t shift = DoubleToInt32(y_val) & 0x1f; | |
2992 int value = ArithmeticShiftRight(DoubleToInt32(x_val), shift); | |
2993 x = factory()->NewNumberLiteral(value, pos); | |
2994 continue; | |
2995 } | |
2996 default: | |
2997 break; | |
2998 } | |
2999 } | |
3000 | |
3001 // For now we distinguish between comparisons and other binary | |
3002 // operations. (We could combine the two and get rid of this | |
3003 // code and AST node eventually.) | |
3004 if (Token::IsCompareOp(op)) { | |
3005 // We have a comparison. | |
3006 Token::Value cmp = op; | |
3007 switch (op) { | |
3008 case Token::NE: cmp = Token::EQ; break; | |
3009 case Token::NE_STRICT: cmp = Token::EQ_STRICT; break; | |
3010 default: break; | |
3011 } | |
3012 x = factory()->NewCompareOperation(cmp, x, y, pos); | |
3013 if (cmp != op) { | |
3014 // The comparison was negated - add a NOT. | |
3015 x = factory()->NewUnaryOperation(Token::NOT, x, pos); | |
3016 } | |
3017 | |
3018 } else { | |
3019 // We have a "normal" binary operation. | |
3020 x = factory()->NewBinaryOperation(op, x, y, pos); | |
3021 } | |
3022 } | |
3023 } | |
3024 return x; | |
3025 } | |
3026 | |
3027 | |
3028 Expression* Parser::ParseUnaryExpression(bool* ok) { | 2993 Expression* Parser::ParseUnaryExpression(bool* ok) { |
3029 // UnaryExpression :: | 2994 // UnaryExpression :: |
3030 // PostfixExpression | 2995 // PostfixExpression |
3031 // 'delete' UnaryExpression | 2996 // 'delete' UnaryExpression |
3032 // 'void' UnaryExpression | 2997 // 'void' UnaryExpression |
3033 // 'typeof' UnaryExpression | 2998 // 'typeof' UnaryExpression |
3034 // '++' UnaryExpression | 2999 // '++' UnaryExpression |
3035 // '--' UnaryExpression | 3000 // '--' UnaryExpression |
3036 // '+' UnaryExpression | 3001 // '+' UnaryExpression |
3037 // '-' UnaryExpression | 3002 // '-' UnaryExpression |
(...skipping 2041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5079 ASSERT(info()->isolate()->has_pending_exception()); | 5044 ASSERT(info()->isolate()->has_pending_exception()); |
5080 } else { | 5045 } else { |
5081 result = ParseProgram(); | 5046 result = ParseProgram(); |
5082 } | 5047 } |
5083 } | 5048 } |
5084 info()->SetFunction(result); | 5049 info()->SetFunction(result); |
5085 return (result != NULL); | 5050 return (result != NULL); |
5086 } | 5051 } |
5087 | 5052 |
5088 } } // namespace v8::internal | 5053 } } // namespace v8::internal |
OLD | NEW |