| OLD | NEW | 
|---|
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 2700 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2711     shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); | 2711     shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); | 
| 2712   } | 2712   } | 
| 2713 | 2713 | 
| 2714   // Generate code for the statements in the try block. | 2714   // Generate code for the statements in the try block. | 
| 2715   VisitStatementsAndSpill(node->try_block()->statements()); | 2715   VisitStatementsAndSpill(node->try_block()->statements()); | 
| 2716 | 2716 | 
| 2717   // Stop the introduced shadowing and count the number of required unlinks. | 2717   // Stop the introduced shadowing and count the number of required unlinks. | 
| 2718   // After shadowing stops, the original targets are unshadowed and the | 2718   // After shadowing stops, the original targets are unshadowed and the | 
| 2719   // ShadowTargets represent the formerly shadowing targets. | 2719   // ShadowTargets represent the formerly shadowing targets. | 
| 2720   bool has_unlinks = false; | 2720   bool has_unlinks = false; | 
| 2721   for (int i = 0; i <= nof_escapes; i++) { | 2721   for (int i = 0; i < shadows.length(); i++) { | 
| 2722     shadows[i]->StopShadowing(); | 2722     shadows[i]->StopShadowing(); | 
| 2723     has_unlinks = has_unlinks || shadows[i]->is_linked(); | 2723     has_unlinks = has_unlinks || shadows[i]->is_linked(); | 
| 2724   } | 2724   } | 
| 2725   function_return_is_shadowed_ = function_return_was_shadowed; | 2725   function_return_is_shadowed_ = function_return_was_shadowed; | 
| 2726 | 2726 | 
| 2727   // Get an external reference to the handler address. | 2727   // Get an external reference to the handler address. | 
| 2728   ExternalReference handler_address(Top::k_handler_address); | 2728   ExternalReference handler_address(Top::k_handler_address); | 
| 2729 | 2729 | 
| 2730   // Make sure that there's nothing left on the stack above the | 2730   // Make sure that there's nothing left on the stack above the | 
| 2731   // handler structure. | 2731   // handler structure. | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 2742     // the handler list and drop the rest of this handler from the | 2742     // the handler list and drop the rest of this handler from the | 
| 2743     // frame. | 2743     // frame. | 
| 2744     frame_->EmitPop(Operand::StaticVariable(handler_address)); | 2744     frame_->EmitPop(Operand::StaticVariable(handler_address)); | 
| 2745     frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 2745     frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 
| 2746     if (has_unlinks) { | 2746     if (has_unlinks) { | 
| 2747       exit.Jump(); | 2747       exit.Jump(); | 
| 2748     } | 2748     } | 
| 2749   } | 2749   } | 
| 2750 | 2750 | 
| 2751   // Generate unlink code for the (formerly) shadowing targets that have been | 2751   // Generate unlink code for the (formerly) shadowing targets that have been | 
| 2752   // jumped to. | 2752   // jumped to.  Deallocate each shadow target. | 
| 2753   for (int i = 0; i <= nof_escapes; i++) { | 2753   for (int i = 0; i < shadows.length(); i++) { | 
| 2754     if (shadows[i]->is_linked()) { | 2754     if (shadows[i]->is_linked()) { | 
| 2755       // Unlink from try chain; be careful not to destroy the TOS. | 2755       // Unlink from try chain; be careful not to destroy the TOS. | 
| 2756       shadows[i]->Bind(); | 2756       shadows[i]->Bind(); | 
| 2757       // Because we can be jumping here (to spilled code) from unspilled | 2757       // Because we can be jumping here (to spilled code) from unspilled | 
| 2758       // code, we need to reestablish a spilled frame at this block. | 2758       // code, we need to reestablish a spilled frame at this block. | 
| 2759       frame_->SpillAll(); | 2759       frame_->SpillAll(); | 
| 2760 | 2760 | 
| 2761       // Reload sp from the top handler, because some statements that we | 2761       // Reload sp from the top handler, because some statements that we | 
| 2762       // break from (eg, for...in) may have left stuff on the stack. | 2762       // break from (eg, for...in) may have left stuff on the stack. | 
| 2763       __ mov(edx, Operand::StaticVariable(handler_address)); | 2763       __ mov(edx, Operand::StaticVariable(handler_address)); | 
| 2764       const int kNextOffset = StackHandlerConstants::kNextOffset + | 2764       const int kNextOffset = StackHandlerConstants::kNextOffset + | 
| 2765           StackHandlerConstants::kAddressDisplacement; | 2765           StackHandlerConstants::kAddressDisplacement; | 
| 2766       __ lea(esp, Operand(edx, kNextOffset)); | 2766       __ lea(esp, Operand(edx, kNextOffset)); | 
| 2767       frame_->Forget(frame_->height() - handler_height); | 2767       frame_->Forget(frame_->height() - handler_height); | 
| 2768 | 2768 | 
| 2769       frame_->EmitPop(Operand::StaticVariable(handler_address)); | 2769       frame_->EmitPop(Operand::StaticVariable(handler_address)); | 
| 2770       frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 2770       frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 
| 2771       // next_sp popped. | 2771       // next_sp popped. | 
| 2772 | 2772 | 
| 2773       if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { | 2773       if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { | 
| 2774         frame_->PrepareForReturn(); | 2774         frame_->PrepareForReturn(); | 
| 2775       } | 2775       } | 
| 2776       shadows[i]->other_target()->Jump(); | 2776       shadows[i]->other_target()->Jump(); | 
| 2777     } | 2777     } | 
|  | 2778     delete shadows[i]; | 
| 2778   } | 2779   } | 
| 2779 | 2780 | 
| 2780   exit.Bind(); | 2781   exit.Bind(); | 
| 2781 } | 2782 } | 
| 2782 | 2783 | 
| 2783 | 2784 | 
| 2784 void CodeGenerator::VisitTryFinally(TryFinally* node) { | 2785 void CodeGenerator::VisitTryFinally(TryFinally* node) { | 
| 2785   ASSERT(!in_spilled_code()); | 2786   ASSERT(!in_spilled_code()); | 
| 2786   VirtualFrame::SpilledScope spilled_scope(this); | 2787   VirtualFrame::SpilledScope spilled_scope(this); | 
| 2787   Comment cmnt(masm_, "[ TryFinally"); | 2788   Comment cmnt(masm_, "[ TryFinally"); | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2830     shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); | 2831     shadows.Add(new ShadowTarget(node->escaping_targets()->at(i))); | 
| 2831   } | 2832   } | 
| 2832 | 2833 | 
| 2833   // Generate code for the statements in the try block. | 2834   // Generate code for the statements in the try block. | 
| 2834   VisitStatementsAndSpill(node->try_block()->statements()); | 2835   VisitStatementsAndSpill(node->try_block()->statements()); | 
| 2835 | 2836 | 
| 2836   // Stop the introduced shadowing and count the number of required unlinks. | 2837   // Stop the introduced shadowing and count the number of required unlinks. | 
| 2837   // After shadowing stops, the original targets are unshadowed and the | 2838   // After shadowing stops, the original targets are unshadowed and the | 
| 2838   // ShadowTargets represent the formerly shadowing targets. | 2839   // ShadowTargets represent the formerly shadowing targets. | 
| 2839   int nof_unlinks = 0; | 2840   int nof_unlinks = 0; | 
| 2840   for (int i = 0; i <= nof_escapes; i++) { | 2841   for (int i = 0; i < shadows.length(); i++) { | 
| 2841     shadows[i]->StopShadowing(); | 2842     shadows[i]->StopShadowing(); | 
| 2842     if (shadows[i]->is_linked()) nof_unlinks++; | 2843     if (shadows[i]->is_linked()) nof_unlinks++; | 
| 2843   } | 2844   } | 
| 2844   function_return_is_shadowed_ = function_return_was_shadowed; | 2845   function_return_is_shadowed_ = function_return_was_shadowed; | 
| 2845 | 2846 | 
| 2846   // Get an external reference to the handler address. | 2847   // Get an external reference to the handler address. | 
| 2847   ExternalReference handler_address(Top::k_handler_address); | 2848   ExternalReference handler_address(Top::k_handler_address); | 
| 2848 | 2849 | 
| 2849   // If we can fall off the end of the try block, unlink from the try | 2850   // If we can fall off the end of the try block, unlink from the try | 
| 2850   // chain and set the state on the frame to FALLING. | 2851   // chain and set the state on the frame to FALLING. | 
| 2851   if (has_valid_frame()) { | 2852   if (has_valid_frame()) { | 
| 2852     // The next handler address is on top of the frame. | 2853     // The next handler address is on top of the frame. | 
| 2853     ASSERT(StackHandlerConstants::kNextOffset == 0); | 2854     ASSERT(StackHandlerConstants::kNextOffset == 0); | 
| 2854     frame_->EmitPop(eax); | 2855     frame_->EmitPop(eax); | 
| 2855     __ mov(Operand::StaticVariable(handler_address), eax); | 2856     __ mov(Operand::StaticVariable(handler_address), eax); | 
| 2856     frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 2857     frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); | 
| 2857 | 2858 | 
| 2858     // Fake a top of stack value (unneeded when FALLING) and set the | 2859     // Fake a top of stack value (unneeded when FALLING) and set the | 
| 2859     // state in ecx, then jump around the unlink blocks if any. | 2860     // state in ecx, then jump around the unlink blocks if any. | 
| 2860     frame_->EmitPush(Immediate(Factory::undefined_value())); | 2861     frame_->EmitPush(Immediate(Factory::undefined_value())); | 
| 2861     __ Set(ecx, Immediate(Smi::FromInt(FALLING))); | 2862     __ Set(ecx, Immediate(Smi::FromInt(FALLING))); | 
| 2862     if (nof_unlinks > 0) { | 2863     if (nof_unlinks > 0) { | 
| 2863       finally_block.Jump(); | 2864       finally_block.Jump(); | 
| 2864     } | 2865     } | 
| 2865   } | 2866   } | 
| 2866 | 2867 | 
| 2867   // Generate code to unlink and set the state for the (formerly) | 2868   // Generate code to unlink and set the state for the (formerly) | 
| 2868   // shadowing targets that have been jumped to. | 2869   // shadowing targets that have been jumped to. | 
| 2869   for (int i = 0; i <= nof_escapes; i++) { | 2870   for (int i = 0; i < shadows.length(); i++) { | 
| 2870     if (shadows[i]->is_linked()) { | 2871     if (shadows[i]->is_linked()) { | 
| 2871       // If we have come from the shadowed return, the return value is | 2872       // If we have come from the shadowed return, the return value is | 
| 2872       // in (a non-refcounted reference to) eax.  We must preserve it | 2873       // in (a non-refcounted reference to) eax.  We must preserve it | 
| 2873       // until it is pushed. | 2874       // until it is pushed. | 
| 2874       // | 2875       // | 
| 2875       // Because we can be jumping here (to spilled code) from | 2876       // Because we can be jumping here (to spilled code) from | 
| 2876       // unspilled code, we need to reestablish a spilled frame at | 2877       // unspilled code, we need to reestablish a spilled frame at | 
| 2877       // this block. | 2878       // this block. | 
| 2878       shadows[i]->Bind(); | 2879       shadows[i]->Bind(); | 
| 2879       frame_->SpillAll(); | 2880       frame_->SpillAll(); | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2919   // Generate code for the statements in the finally block. | 2920   // Generate code for the statements in the finally block. | 
| 2920   VisitStatementsAndSpill(node->finally_block()->statements()); | 2921   VisitStatementsAndSpill(node->finally_block()->statements()); | 
| 2921 | 2922 | 
| 2922   if (has_valid_frame()) { | 2923   if (has_valid_frame()) { | 
| 2923     JumpTarget exit(this); | 2924     JumpTarget exit(this); | 
| 2924     // Restore state and return value or faked TOS. | 2925     // Restore state and return value or faked TOS. | 
| 2925     frame_->EmitPop(ecx); | 2926     frame_->EmitPop(ecx); | 
| 2926     frame_->EmitPop(eax); | 2927     frame_->EmitPop(eax); | 
| 2927 | 2928 | 
| 2928     // Generate code to jump to the right destination for all used | 2929     // Generate code to jump to the right destination for all used | 
| 2929     // formerly shadowing targets. | 2930     // formerly shadowing targets.  Deallocate each shadow target. | 
| 2930     for (int i = 0; i <= nof_escapes; i++) { | 2931     for (int i = 0; i < shadows.length(); i++) { | 
| 2931       if (shadows[i]->is_bound()) { | 2932       if (shadows[i]->is_bound()) { | 
| 2932         JumpTarget* original = shadows[i]->other_target(); | 2933         JumpTarget* original = shadows[i]->other_target(); | 
| 2933         __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i))); | 2934         __ cmp(Operand(ecx), Immediate(Smi::FromInt(JUMPING + i))); | 
| 2934         if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { | 2935         if (!function_return_is_shadowed_ && i == kReturnShadowIndex) { | 
| 2935           JumpTarget skip(this); | 2936           JumpTarget skip(this); | 
| 2936           skip.Branch(not_equal); | 2937           skip.Branch(not_equal); | 
| 2937           frame_->PrepareForReturn(); | 2938           frame_->PrepareForReturn(); | 
| 2938           original->Jump(); | 2939           original->Jump(); | 
| 2939           skip.Bind(); | 2940           skip.Bind(); | 
| 2940         } else { | 2941         } else { | 
| 2941           original->Branch(equal); | 2942           original->Branch(equal); | 
| 2942         } | 2943         } | 
| 2943       } | 2944       } | 
|  | 2945       delete shadows[i]; | 
| 2944     } | 2946     } | 
| 2945 | 2947 | 
| 2946     // Check if we need to rethrow the exception. | 2948     // Check if we need to rethrow the exception. | 
| 2947     __ cmp(Operand(ecx), Immediate(Smi::FromInt(THROWING))); | 2949     __ cmp(Operand(ecx), Immediate(Smi::FromInt(THROWING))); | 
| 2948     exit.Branch(not_equal); | 2950     exit.Branch(not_equal); | 
| 2949 | 2951 | 
| 2950     // Rethrow exception. | 2952     // Rethrow exception. | 
| 2951     frame_->EmitPush(eax);  // undo pop from above | 2953     frame_->EmitPush(eax);  // undo pop from above | 
| 2952     frame_->CallRuntime(Runtime::kReThrow, 1); | 2954     frame_->CallRuntime(Runtime::kReThrow, 1); | 
| 2953 | 2955 | 
| (...skipping 3977 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6931 | 6933 | 
| 6932   // Slow-case: Go through the JavaScript implementation. | 6934   // Slow-case: Go through the JavaScript implementation. | 
| 6933   __ bind(&slow); | 6935   __ bind(&slow); | 
| 6934   __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 6936   __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 
| 6935 } | 6937 } | 
| 6936 | 6938 | 
| 6937 | 6939 | 
| 6938 #undef __ | 6940 #undef __ | 
| 6939 | 6941 | 
| 6940 } }  // namespace v8::internal | 6942 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|