| 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 |