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 |