| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 if (Token::IsCompareOp(op)) return true; | 329 if (Token::IsCompareOp(op)) return true; |
| 330 // TODO(kasperl): Once the unary bit not stub allows leaving out | 330 // TODO(kasperl): Once the unary bit not stub allows leaving out |
| 331 // the inlined smi case, we should get rid of this check. | 331 // the inlined smi case, we should get rid of this check. |
| 332 if (op == Token::BIT_NOT) return true; | 332 if (op == Token::BIT_NOT) return true; |
| 333 // Inline smi case inside loops, but not division and modulo which | 333 // Inline smi case inside loops, but not division and modulo which |
| 334 // are too complicated and take up too much space. | 334 // are too complicated and take up too much space. |
| 335 return (op != Token::DIV) && (op != Token::MOD) && (loop_depth_ > 0); | 335 return (op != Token::DIV) && (op != Token::MOD) && (loop_depth_ > 0); |
| 336 } | 336 } |
| 337 | 337 |
| 338 | 338 |
| 339 void FullCodeGenerator::PrepareTest(Label* materialize_true, | 339 void FullCodeGenerator::EffectContext::DropAndPlug(int count, |
| 340 Label* materialize_false, | 340 Register reg) const { |
| 341 Label** if_true, | 341 ASSERT(count > 0); |
| 342 Label** if_false, | 342 __ Drop(count); |
| 343 Label** fall_through) { | 343 } |
| 344 switch (context_) { | 344 |
| 345 case Expression::kUninitialized: | 345 |
| 346 UNREACHABLE(); | 346 void FullCodeGenerator::AccumulatorValueContext::DropAndPlug( |
| 347 break; | 347 int count, |
| 348 case Expression::kEffect: | 348 Register reg) const { |
| 349 // In an effect context, the true and the false case branch to the | 349 ASSERT(count > 0); |
| 350 // same label. | 350 __ Drop(count); |
| 351 *if_true = *if_false = *fall_through = materialize_true; | 351 __ Move(result_register(), reg); |
| 352 break; | 352 } |
| 353 case Expression::kValue: | 353 |
| 354 *if_true = *fall_through = materialize_true; | 354 |
| 355 *if_false = materialize_false; | 355 void FullCodeGenerator::TestContext::DropAndPlug(int count, |
| 356 break; | 356 Register reg) const { |
| 357 case Expression::kTest: | 357 ASSERT(count > 0); |
| 358 *if_true = true_label_; | 358 // For simplicity we always test the accumulator register. |
| 359 *if_false = false_label_; | 359 __ Drop(count); |
| 360 *fall_through = fall_through_; | 360 __ Move(result_register(), reg); |
| 361 break; | 361 codegen()->DoTest(true_label_, false_label_, fall_through_); |
| 362 } | 362 } |
| 363 |
| 364 |
| 365 void FullCodeGenerator::EffectContext::Plug(Register reg) const { |
| 366 // Nothing to do. |
| 367 } |
| 368 |
| 369 |
| 370 void FullCodeGenerator::AccumulatorValueContext::Plug(Register reg) const { |
| 371 // Move value into place. |
| 372 __ Move(result_register(), reg); |
| 373 } |
| 374 |
| 375 |
| 376 void FullCodeGenerator::StackValueContext::Plug(Register reg) const { |
| 377 // Move value into place. |
| 378 __ push(reg); |
| 379 } |
| 380 |
| 381 |
| 382 void FullCodeGenerator::TestContext::Plug(Register reg) const { |
| 383 // For simplicity we always test the accumulator register. |
| 384 __ Move(result_register(), reg); |
| 385 codegen()->DoTest(true_label_, false_label_, fall_through_); |
| 386 } |
| 387 |
| 388 |
| 389 void FullCodeGenerator::EffectContext::PlugTOS() const { |
| 390 __ Drop(1); |
| 391 } |
| 392 |
| 393 |
| 394 void FullCodeGenerator::AccumulatorValueContext::PlugTOS() const { |
| 395 __ pop(result_register()); |
| 396 } |
| 397 |
| 398 |
| 399 void FullCodeGenerator::StackValueContext::PlugTOS() const { |
| 400 } |
| 401 |
| 402 |
| 403 void FullCodeGenerator::TestContext::PlugTOS() const { |
| 404 // For simplicity we always test the accumulator register. |
| 405 __ pop(result_register()); |
| 406 codegen()->DoTest(true_label_, false_label_, fall_through_); |
| 407 } |
| 408 |
| 409 |
| 410 void FullCodeGenerator::EffectContext::PrepareTest( |
| 411 Label* materialize_true, |
| 412 Label* materialize_false, |
| 413 Label** if_true, |
| 414 Label** if_false, |
| 415 Label** fall_through) const { |
| 416 // In an effect context, the true and the false case branch to the |
| 417 // same label. |
| 418 *if_true = *if_false = *fall_through = materialize_true; |
| 419 } |
| 420 |
| 421 |
| 422 void FullCodeGenerator::AccumulatorValueContext::PrepareTest( |
| 423 Label* materialize_true, |
| 424 Label* materialize_false, |
| 425 Label** if_true, |
| 426 Label** if_false, |
| 427 Label** fall_through) const { |
| 428 *if_true = *fall_through = materialize_true; |
| 429 *if_false = materialize_false; |
| 430 } |
| 431 |
| 432 |
| 433 void FullCodeGenerator::StackValueContext::PrepareTest( |
| 434 Label* materialize_true, |
| 435 Label* materialize_false, |
| 436 Label** if_true, |
| 437 Label** if_false, |
| 438 Label** fall_through) const { |
| 439 *if_true = *fall_through = materialize_true; |
| 440 *if_false = materialize_false; |
| 441 } |
| 442 |
| 443 |
| 444 void FullCodeGenerator::TestContext::PrepareTest( |
| 445 Label* materialize_true, |
| 446 Label* materialize_false, |
| 447 Label** if_true, |
| 448 Label** if_false, |
| 449 Label** fall_through) const { |
| 450 *if_true = true_label_; |
| 451 *if_false = false_label_; |
| 452 *fall_through = fall_through_; |
| 363 } | 453 } |
| 364 | 454 |
| 365 | 455 |
| 366 void FullCodeGenerator::VisitDeclarations( | 456 void FullCodeGenerator::VisitDeclarations( |
| 367 ZoneList<Declaration*>* declarations) { | 457 ZoneList<Declaration*>* declarations) { |
| 368 int length = declarations->length(); | 458 int length = declarations->length(); |
| 369 int globals = 0; | 459 int globals = 0; |
| 370 for (int i = 0; i < length; i++) { | 460 for (int i = 0; i < length; i++) { |
| 371 Declaration* decl = declarations->at(i); | 461 Declaration* decl = declarations->at(i); |
| 372 Variable* var = decl->proxy()->var(); | 462 Variable* var = decl->proxy()->var(); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 case Token::SHL: | 645 case Token::SHL: |
| 556 case Token::SHR: | 646 case Token::SHR: |
| 557 case Token::SAR: { | 647 case Token::SAR: { |
| 558 // Figure out if either of the operands is a constant. | 648 // Figure out if either of the operands is a constant. |
| 559 ConstantOperand constant = ShouldInlineSmiCase(op) | 649 ConstantOperand constant = ShouldInlineSmiCase(op) |
| 560 ? GetConstantOperand(op, left, right) | 650 ? GetConstantOperand(op, left, right) |
| 561 : kNoConstants; | 651 : kNoConstants; |
| 562 | 652 |
| 563 // Load only the operands that we need to materialize. | 653 // Load only the operands that we need to materialize. |
| 564 if (constant == kNoConstants) { | 654 if (constant == kNoConstants) { |
| 565 VisitForValue(left, kStack); | 655 VisitForStackValue(left); |
| 566 VisitForValue(right, kAccumulator); | 656 VisitForAccumulatorValue(right); |
| 567 } else if (constant == kRightConstant) { | 657 } else if (constant == kRightConstant) { |
| 568 VisitForValue(left, kAccumulator); | 658 VisitForAccumulatorValue(left); |
| 569 } else { | 659 } else { |
| 570 ASSERT(constant == kLeftConstant); | 660 ASSERT(constant == kLeftConstant); |
| 571 VisitForValue(right, kAccumulator); | 661 VisitForAccumulatorValue(right); |
| 572 } | 662 } |
| 573 | 663 |
| 574 SetSourcePosition(expr->position()); | 664 SetSourcePosition(expr->position()); |
| 575 if (ShouldInlineSmiCase(op)) { | 665 if (ShouldInlineSmiCase(op)) { |
| 576 EmitInlineSmiBinaryOp(expr, op, context_, mode, left, right, constant); | 666 EmitInlineSmiBinaryOp(expr, op, mode, left, right, constant); |
| 577 } else { | 667 } else { |
| 578 EmitBinaryOp(op, context_, mode); | 668 EmitBinaryOp(op, mode); |
| 579 } | 669 } |
| 580 break; | 670 break; |
| 581 } | 671 } |
| 582 | 672 |
| 583 default: | 673 default: |
| 584 UNREACHABLE(); | 674 UNREACHABLE(); |
| 585 } | 675 } |
| 586 } | 676 } |
| 587 | 677 |
| 588 | 678 |
| 589 void FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { | 679 void FullCodeGenerator::EmitLogicalOperation(BinaryOperation* expr) { |
| 590 Label eval_right, done; | 680 Label eval_right, done; |
| 591 | 681 |
| 592 // Set up the appropriate context for the left subexpression based | 682 context()->EmitLogicalLeft(expr, &eval_right, &done); |
| 593 // on the operation and our own context. Initially assume we can | |
| 594 // inherit both true and false labels from our context. | |
| 595 if (expr->op() == Token::OR) { | |
| 596 switch (context_) { | |
| 597 case Expression::kUninitialized: | |
| 598 UNREACHABLE(); | |
| 599 case Expression::kEffect: | |
| 600 VisitForControl(expr->left(), &done, &eval_right, &eval_right); | |
| 601 break; | |
| 602 case Expression::kValue: | |
| 603 VisitLogicalForValue(expr->left(), expr->op(), location_, &done); | |
| 604 break; | |
| 605 case Expression::kTest: | |
| 606 VisitForControl(expr->left(), true_label_, &eval_right, &eval_right); | |
| 607 break; | |
| 608 } | |
| 609 } else { | |
| 610 ASSERT_EQ(Token::AND, expr->op()); | |
| 611 switch (context_) { | |
| 612 case Expression::kUninitialized: | |
| 613 UNREACHABLE(); | |
| 614 case Expression::kEffect: | |
| 615 VisitForControl(expr->left(), &eval_right, &done, &eval_right); | |
| 616 break; | |
| 617 case Expression::kValue: | |
| 618 VisitLogicalForValue(expr->left(), expr->op(), location_, &done); | |
| 619 break; | |
| 620 case Expression::kTest: | |
| 621 VisitForControl(expr->left(), &eval_right, false_label_, &eval_right); | |
| 622 break; | |
| 623 } | |
| 624 } | |
| 625 | 683 |
| 626 __ bind(&eval_right); | 684 __ bind(&eval_right); |
| 627 Visit(expr->right()); | 685 Visit(expr->right()); |
| 628 | 686 |
| 629 __ bind(&done); | 687 __ bind(&done); |
| 630 } | 688 } |
| 631 | 689 |
| 632 | 690 |
| 633 void FullCodeGenerator::VisitLogicalForValue(Expression* expr, | 691 // Set up the appropriate context for the left subexpression based |
| 634 Token::Value op, | 692 // on the operation and our own context. Initially assume we can |
| 635 Location where, | 693 // inherit both true and false labels from our context. |
| 636 Label* done) { | 694 |
| 637 ASSERT(op == Token::AND || op == Token::OR); | 695 void FullCodeGenerator::EffectContext::EmitLogicalLeft(BinaryOperation* expr, |
| 638 VisitForValue(expr, kAccumulator); | 696 Label* eval_right, |
| 697 Label* done) const { |
| 698 if (expr->op() == Token::OR) { |
| 699 codegen()->VisitForControl(expr->left(), done, eval_right, eval_right); |
| 700 } else { |
| 701 ASSERT(expr->op() == Token::AND); |
| 702 codegen()->VisitForControl(expr->left(), eval_right, done, eval_right); |
| 703 } |
| 704 } |
| 705 |
| 706 |
| 707 void FullCodeGenerator::AccumulatorValueContext::EmitLogicalLeft( |
| 708 BinaryOperation* expr, |
| 709 Label* eval_right, |
| 710 Label* done) const { |
| 711 codegen()->Visit(expr->left()); |
| 639 __ push(result_register()); | 712 __ push(result_register()); |
| 640 | 713 Label discard, restore; |
| 641 Label discard; | 714 if (expr->op() == Token::OR) { |
| 642 switch (where) { | 715 codegen()->DoTest(&restore, &discard, &restore); |
| 643 case kAccumulator: { | 716 } else { |
| 644 Label restore; | 717 ASSERT(expr->op() == Token::AND); |
| 645 if (op == Token::OR) { | 718 codegen()->DoTest(&discard, &restore, &restore); |
| 646 DoTest(&restore, &discard, &restore); | |
| 647 } else { | |
| 648 DoTest(&discard, &restore, &restore); | |
| 649 } | |
| 650 __ bind(&restore); | |
| 651 __ pop(result_register()); | |
| 652 __ jmp(done); | |
| 653 break; | |
| 654 } | |
| 655 case kStack: { | |
| 656 if (op == Token::OR) { | |
| 657 DoTest(done, &discard, &discard); | |
| 658 } else { | |
| 659 DoTest(&discard, done, &discard); | |
| 660 } | |
| 661 break; | |
| 662 } | |
| 663 } | 719 } |
| 664 | 720 __ bind(&restore); |
| 721 __ pop(result_register()); |
| 722 __ jmp(done); |
| 665 __ bind(&discard); | 723 __ bind(&discard); |
| 666 __ Drop(1); | 724 __ Drop(1); |
| 667 } | 725 } |
| 668 | 726 |
| 669 | 727 |
| 728 void FullCodeGenerator::StackValueContext::EmitLogicalLeft( |
| 729 BinaryOperation* expr, |
| 730 Label* eval_right, |
| 731 Label* done) const { |
| 732 codegen()->VisitForAccumulatorValue(expr->left()); |
| 733 __ push(result_register()); |
| 734 Label discard; |
| 735 if (expr->op() == Token::OR) { |
| 736 codegen()->DoTest(done, &discard, &discard); |
| 737 } else { |
| 738 ASSERT(expr->op() == Token::AND); |
| 739 codegen()->DoTest(&discard, done, &discard); |
| 740 } |
| 741 __ bind(&discard); |
| 742 __ Drop(1); |
| 743 } |
| 744 |
| 745 |
| 746 void FullCodeGenerator::TestContext::EmitLogicalLeft(BinaryOperation* expr, |
| 747 Label* eval_right, |
| 748 Label* done) const { |
| 749 if (expr->op() == Token::OR) { |
| 750 codegen()->VisitForControl(expr->left(), |
| 751 true_label_, eval_right, eval_right); |
| 752 } else { |
| 753 ASSERT(expr->op() == Token::AND); |
| 754 codegen()->VisitForControl(expr->left(), |
| 755 eval_right, false_label_, eval_right); |
| 756 } |
| 757 } |
| 758 |
| 759 |
| 670 void FullCodeGenerator::VisitBlock(Block* stmt) { | 760 void FullCodeGenerator::VisitBlock(Block* stmt) { |
| 671 Comment cmnt(masm_, "[ Block"); | 761 Comment cmnt(masm_, "[ Block"); |
| 672 Breakable nested_statement(this, stmt); | 762 Breakable nested_statement(this, stmt); |
| 673 SetStatementPosition(stmt); | 763 SetStatementPosition(stmt); |
| 674 VisitStatements(stmt->statements()); | 764 VisitStatements(stmt->statements()); |
| 675 __ bind(nested_statement.break_target()); | 765 __ bind(nested_statement.break_target()); |
| 676 } | 766 } |
| 677 | 767 |
| 678 | 768 |
| 679 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { | 769 void FullCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 | 830 |
| 741 Breakable* target = current->AsBreakable(); | 831 Breakable* target = current->AsBreakable(); |
| 742 __ jmp(target->break_target()); | 832 __ jmp(target->break_target()); |
| 743 } | 833 } |
| 744 | 834 |
| 745 | 835 |
| 746 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { | 836 void FullCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
| 747 Comment cmnt(masm_, "[ ReturnStatement"); | 837 Comment cmnt(masm_, "[ ReturnStatement"); |
| 748 SetStatementPosition(stmt); | 838 SetStatementPosition(stmt); |
| 749 Expression* expr = stmt->expression(); | 839 Expression* expr = stmt->expression(); |
| 750 VisitForValue(expr, kAccumulator); | 840 VisitForAccumulatorValue(expr); |
| 751 | 841 |
| 752 // Exit all nested statements. | 842 // Exit all nested statements. |
| 753 NestedStatement* current = nesting_stack_; | 843 NestedStatement* current = nesting_stack_; |
| 754 int stack_depth = 0; | 844 int stack_depth = 0; |
| 755 while (current != NULL) { | 845 while (current != NULL) { |
| 756 stack_depth = current->Exit(stack_depth); | 846 stack_depth = current->Exit(stack_depth); |
| 757 current = current->outer(); | 847 current = current->outer(); |
| 758 } | 848 } |
| 759 __ Drop(stack_depth); | 849 __ Drop(stack_depth); |
| 760 | 850 |
| 761 EmitReturnSequence(); | 851 EmitReturnSequence(); |
| 762 } | 852 } |
| 763 | 853 |
| 764 | 854 |
| 765 void FullCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) { | 855 void FullCodeGenerator::VisitWithEnterStatement(WithEnterStatement* stmt) { |
| 766 Comment cmnt(masm_, "[ WithEnterStatement"); | 856 Comment cmnt(masm_, "[ WithEnterStatement"); |
| 767 SetStatementPosition(stmt); | 857 SetStatementPosition(stmt); |
| 768 | 858 |
| 769 VisitForValue(stmt->expression(), kStack); | 859 VisitForStackValue(stmt->expression()); |
| 770 if (stmt->is_catch_block()) { | 860 if (stmt->is_catch_block()) { |
| 771 __ CallRuntime(Runtime::kPushCatchContext, 1); | 861 __ CallRuntime(Runtime::kPushCatchContext, 1); |
| 772 } else { | 862 } else { |
| 773 __ CallRuntime(Runtime::kPushContext, 1); | 863 __ CallRuntime(Runtime::kPushContext, 1); |
| 774 } | 864 } |
| 775 // Both runtime calls return the new context in both the context and the | 865 // Both runtime calls return the new context in both the context and the |
| 776 // result registers. | 866 // result registers. |
| 777 | 867 |
| 778 // Update local stack frame context field. | 868 // Update local stack frame context field. |
| 779 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); | 869 StoreToFrameField(StandardFrameConstants::kContextOffset, context_register()); |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1040 void FullCodeGenerator::VisitConditional(Conditional* expr) { | 1130 void FullCodeGenerator::VisitConditional(Conditional* expr) { |
| 1041 Comment cmnt(masm_, "[ Conditional"); | 1131 Comment cmnt(masm_, "[ Conditional"); |
| 1042 Label true_case, false_case, done; | 1132 Label true_case, false_case, done; |
| 1043 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); | 1133 VisitForControl(expr->condition(), &true_case, &false_case, &true_case); |
| 1044 | 1134 |
| 1045 __ bind(&true_case); | 1135 __ bind(&true_case); |
| 1046 SetExpressionPosition(expr->then_expression(), | 1136 SetExpressionPosition(expr->then_expression(), |
| 1047 expr->then_expression_position()); | 1137 expr->then_expression_position()); |
| 1048 Visit(expr->then_expression()); | 1138 Visit(expr->then_expression()); |
| 1049 // If control flow falls through Visit, jump to done. | 1139 // If control flow falls through Visit, jump to done. |
| 1050 if (context_ == Expression::kEffect || context_ == Expression::kValue) { | 1140 if (!context()->IsTest()) { |
| 1051 __ jmp(&done); | 1141 __ jmp(&done); |
| 1052 } | 1142 } |
| 1053 | 1143 |
| 1054 __ bind(&false_case); | 1144 __ bind(&false_case); |
| 1055 SetExpressionPosition(expr->else_expression(), | 1145 SetExpressionPosition(expr->else_expression(), |
| 1056 expr->else_expression_position()); | 1146 expr->else_expression_position()); |
| 1057 Visit(expr->else_expression()); | 1147 Visit(expr->else_expression()); |
| 1058 // If control flow falls through Visit, merge it with true case here. | 1148 // If control flow falls through Visit, merge it with true case here. |
| 1059 if (context_ == Expression::kEffect || context_ == Expression::kValue) { | 1149 if (!context()->IsTest()) { |
| 1060 __ bind(&done); | 1150 __ bind(&done); |
| 1061 } | 1151 } |
| 1062 } | 1152 } |
| 1063 | 1153 |
| 1064 | 1154 |
| 1065 void FullCodeGenerator::VisitSlot(Slot* expr) { | 1155 void FullCodeGenerator::VisitSlot(Slot* expr) { |
| 1066 // Slots do not appear directly in the AST. | 1156 // Slots do not appear directly in the AST. |
| 1067 UNREACHABLE(); | 1157 UNREACHABLE(); |
| 1068 } | 1158 } |
| 1069 | 1159 |
| 1070 | 1160 |
| 1071 void FullCodeGenerator::VisitLiteral(Literal* expr) { | 1161 void FullCodeGenerator::VisitLiteral(Literal* expr) { |
| 1072 Comment cmnt(masm_, "[ Literal"); | 1162 Comment cmnt(masm_, "[ Literal"); |
| 1073 Apply(context_, expr); | 1163 context()->Plug(expr->handle()); |
| 1074 } | 1164 } |
| 1075 | 1165 |
| 1076 | 1166 |
| 1077 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { | 1167 void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 1078 Comment cmnt(masm_, "[ FunctionLiteral"); | 1168 Comment cmnt(masm_, "[ FunctionLiteral"); |
| 1079 | 1169 |
| 1080 // Build the function boilerplate and instantiate it. | 1170 // Build the function boilerplate and instantiate it. |
| 1081 Handle<SharedFunctionInfo> function_info = | 1171 Handle<SharedFunctionInfo> function_info = |
| 1082 Compiler::BuildFunctionInfo(expr, script(), this); | 1172 Compiler::BuildFunctionInfo(expr, script(), this); |
| 1083 if (HasStackOverflow()) return; | 1173 if (HasStackOverflow()) return; |
| 1084 EmitNewClosure(function_info); | 1174 EmitNewClosure(function_info); |
| 1085 } | 1175 } |
| 1086 | 1176 |
| 1087 | 1177 |
| 1088 void FullCodeGenerator::VisitSharedFunctionInfoLiteral( | 1178 void FullCodeGenerator::VisitSharedFunctionInfoLiteral( |
| 1089 SharedFunctionInfoLiteral* expr) { | 1179 SharedFunctionInfoLiteral* expr) { |
| 1090 Comment cmnt(masm_, "[ SharedFunctionInfoLiteral"); | 1180 Comment cmnt(masm_, "[ SharedFunctionInfoLiteral"); |
| 1091 EmitNewClosure(expr->shared_function_info()); | 1181 EmitNewClosure(expr->shared_function_info()); |
| 1092 } | 1182 } |
| 1093 | 1183 |
| 1094 | 1184 |
| 1095 void FullCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { | 1185 void FullCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { |
| 1096 // Call runtime routine to allocate the catch extension object and | 1186 // Call runtime routine to allocate the catch extension object and |
| 1097 // assign the exception value to the catch variable. | 1187 // assign the exception value to the catch variable. |
| 1098 Comment cmnt(masm_, "[ CatchExtensionObject"); | 1188 Comment cmnt(masm_, "[ CatchExtensionObject"); |
| 1099 VisitForValue(expr->key(), kStack); | 1189 VisitForStackValue(expr->key()); |
| 1100 VisitForValue(expr->value(), kStack); | 1190 VisitForStackValue(expr->value()); |
| 1101 // Create catch extension object. | 1191 // Create catch extension object. |
| 1102 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); | 1192 __ CallRuntime(Runtime::kCreateCatchExtensionObject, 2); |
| 1103 Apply(context_, result_register()); | 1193 context()->Plug(result_register()); |
| 1104 } | 1194 } |
| 1105 | 1195 |
| 1106 | 1196 |
| 1107 void FullCodeGenerator::VisitThrow(Throw* expr) { | 1197 void FullCodeGenerator::VisitThrow(Throw* expr) { |
| 1108 Comment cmnt(masm_, "[ Throw"); | 1198 Comment cmnt(masm_, "[ Throw"); |
| 1109 VisitForValue(expr->exception(), kStack); | 1199 VisitForStackValue(expr->exception()); |
| 1110 __ CallRuntime(Runtime::kThrow, 1); | 1200 __ CallRuntime(Runtime::kThrow, 1); |
| 1111 // Never returns here. | 1201 // Never returns here. |
| 1112 } | 1202 } |
| 1113 | 1203 |
| 1114 | 1204 |
| 1115 void FullCodeGenerator::VisitIncrementOperation(IncrementOperation* expr) { | 1205 void FullCodeGenerator::VisitIncrementOperation(IncrementOperation* expr) { |
| 1116 UNREACHABLE(); | 1206 UNREACHABLE(); |
| 1117 } | 1207 } |
| 1118 | 1208 |
| 1119 | 1209 |
| 1120 int FullCodeGenerator::TryFinally::Exit(int stack_depth) { | 1210 int FullCodeGenerator::TryFinally::Exit(int stack_depth) { |
| 1121 // The macros used here must preserve the result register. | 1211 // The macros used here must preserve the result register. |
| 1122 __ Drop(stack_depth); | 1212 __ Drop(stack_depth); |
| 1123 __ PopTryHandler(); | 1213 __ PopTryHandler(); |
| 1124 __ Call(finally_entry_); | 1214 __ Call(finally_entry_); |
| 1125 return 0; | 1215 return 0; |
| 1126 } | 1216 } |
| 1127 | 1217 |
| 1128 | 1218 |
| 1129 int FullCodeGenerator::TryCatch::Exit(int stack_depth) { | 1219 int FullCodeGenerator::TryCatch::Exit(int stack_depth) { |
| 1130 // The macros used here must preserve the result register. | 1220 // The macros used here must preserve the result register. |
| 1131 __ Drop(stack_depth); | 1221 __ Drop(stack_depth); |
| 1132 __ PopTryHandler(); | 1222 __ PopTryHandler(); |
| 1133 return 0; | 1223 return 0; |
| 1134 } | 1224 } |
| 1135 | 1225 |
| 1136 | 1226 |
| 1137 void FullCodeGenerator::EmitRegExpCloneResult(ZoneList<Expression*>* args) { | 1227 void FullCodeGenerator::EmitRegExpCloneResult(ZoneList<Expression*>* args) { |
| 1138 ASSERT(args->length() == 1); | 1228 ASSERT(args->length() == 1); |
| 1139 VisitForValue(args->at(0), kStack); | 1229 VisitForStackValue(args->at(0)); |
| 1140 __ CallRuntime(Runtime::kRegExpCloneResult, 1); | 1230 __ CallRuntime(Runtime::kRegExpCloneResult, 1); |
| 1141 Apply(context_, result_register()); | 1231 context()->Plug(result_register()); |
| 1142 } | 1232 } |
| 1143 | 1233 |
| 1144 #undef __ | 1234 #undef __ |
| 1145 | 1235 |
| 1146 | 1236 |
| 1147 } } // namespace v8::internal | 1237 } } // namespace v8::internal |
| OLD | NEW |