OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "api.h" | 7 #include "api.h" |
8 #include "arguments.h" | 8 #include "arguments.h" |
9 #include "bootstrapper.h" | 9 #include "bootstrapper.h" |
10 #include "code-stubs.h" | 10 #include "code-stubs.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "natives.h" | 24 #include "natives.h" |
25 #include "stub-cache.h" | 25 #include "stub-cache.h" |
26 #include "log.h" | 26 #include "log.h" |
27 | 27 |
28 #include "../include/v8-debug.h" | 28 #include "../include/v8-debug.h" |
29 | 29 |
30 namespace v8 { | 30 namespace v8 { |
31 namespace internal { | 31 namespace internal { |
32 | 32 |
33 Debug::Debug(Isolate* isolate) | 33 Debug::Debug(Isolate* isolate) |
34 : has_break_points_(false), | 34 : debug_context_(Handle<Context>()), |
35 script_cache_(NULL), | 35 event_listener_(Handle<Object>()), |
36 debug_info_list_(NULL), | 36 event_listener_data_(Handle<Object>()), |
| 37 message_handler_(NULL), |
| 38 command_received_(0), |
| 39 command_queue_(isolate->logger(), kQueueInitialSize), |
| 40 event_command_queue_(isolate->logger(), kQueueInitialSize), |
| 41 is_active_(false), |
| 42 ignore_debugger_(false), |
| 43 live_edit_enabled_(true), // TODO(yangguo): set to false by default. |
| 44 has_break_points_(false), |
37 disable_break_(false), | 45 disable_break_(false), |
38 break_on_exception_(false), | 46 break_on_exception_(false), |
39 break_on_uncaught_exception_(false), | 47 break_on_uncaught_exception_(false), |
| 48 script_cache_(NULL), |
| 49 debug_info_list_(NULL), |
40 isolate_(isolate) { | 50 isolate_(isolate) { |
41 ThreadInit(); | 51 ThreadInit(); |
42 } | 52 } |
43 | 53 |
44 | 54 |
45 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) { | 55 static v8::Handle<v8::Context> GetDebugEventContext(Isolate* isolate) { |
46 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); | 56 Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); |
47 // Isolate::context() may have been NULL when "script collected" event | 57 // Isolate::context() may have been NULL when "script collected" event |
48 // occured. | 58 // occured. |
49 if (context.is_null()) return v8::Local<v8::Context>(); | 59 if (context.is_null()) return v8::Local<v8::Context>(); |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 if (entry->value != NULL) { | 599 if (entry->value != NULL) { |
590 instances->set(count, *reinterpret_cast<Script**>(entry->value)); | 600 instances->set(count, *reinterpret_cast<Script**>(entry->value)); |
591 count++; | 601 count++; |
592 } | 602 } |
593 } | 603 } |
594 return instances; | 604 return instances; |
595 } | 605 } |
596 | 606 |
597 | 607 |
598 void ScriptCache::ProcessCollectedScripts() { | 608 void ScriptCache::ProcessCollectedScripts() { |
599 Debugger* debugger = isolate_->debugger(); | 609 Debug* debug = isolate_->debug(); |
600 for (int i = 0; i < collected_scripts_.length(); i++) { | 610 for (int i = 0; i < collected_scripts_.length(); i++) { |
601 debugger->OnScriptCollected(collected_scripts_[i]); | 611 debug->OnScriptCollected(collected_scripts_[i]); |
602 } | 612 } |
603 collected_scripts_.Clear(); | 613 collected_scripts_.Clear(); |
604 } | 614 } |
605 | 615 |
606 | 616 |
607 void ScriptCache::Clear() { | 617 void ScriptCache::Clear() { |
608 // Iterate the script cache to get rid of all the weak handles. | 618 // Iterate the script cache to get rid of all the weak handles. |
609 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { | 619 for (HashMap::Entry* entry = Start(); entry != NULL; entry = Next(entry)) { |
610 ASSERT(entry != NULL); | 620 ASSERT(entry != NULL); |
611 Object** location = reinterpret_cast<Object**>(entry->value); | 621 Object** location = reinterpret_cast<Object**>(entry->value); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 return true; | 752 return true; |
743 } | 753 } |
744 | 754 |
745 | 755 |
746 bool Debug::Load() { | 756 bool Debug::Load() { |
747 // Return if debugger is already loaded. | 757 // Return if debugger is already loaded. |
748 if (IsLoaded()) return true; | 758 if (IsLoaded()) return true; |
749 | 759 |
750 // Bail out if we're already in the process of compiling the native | 760 // Bail out if we're already in the process of compiling the native |
751 // JavaScript source code for the debugger. | 761 // JavaScript source code for the debugger. |
752 if (isolate_->debugger()->ignore_debugger()) return false; | 762 if (isolate_->debug()->ignore_debugger()) return false; |
753 Debugger::IgnoreScope during_create(isolate_->debugger()); | 763 Debug::IgnoreScope during_create(isolate_->debug()); |
754 | 764 |
755 // Disable breakpoints and interrupts while compiling and running the | 765 // Disable breakpoints and interrupts while compiling and running the |
756 // debugger scripts including the context creation code. | 766 // debugger scripts including the context creation code. |
757 DisableBreak disable(isolate_, true); | 767 DisableBreak disable(isolate_, true); |
758 PostponeInterruptsScope postpone(isolate_); | 768 PostponeInterruptsScope postpone(isolate_); |
759 | 769 |
760 // Create the debugger context. | 770 // Create the debugger context. |
761 HandleScope scope(isolate_); | 771 HandleScope scope(isolate_); |
762 ExtensionConfiguration no_extensions; | 772 ExtensionConfiguration no_extensions; |
763 Handle<Context> context = | 773 Handle<Context> context = |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
894 if (thread_local_.queued_step_count_ > 0) { | 904 if (thread_local_.queued_step_count_ > 0) { |
895 // Perform queued steps | 905 // Perform queued steps |
896 int step_count = thread_local_.queued_step_count_; | 906 int step_count = thread_local_.queued_step_count_; |
897 | 907 |
898 // Clear queue | 908 // Clear queue |
899 thread_local_.queued_step_count_ = 0; | 909 thread_local_.queued_step_count_ = 0; |
900 | 910 |
901 PrepareStep(StepNext, step_count, StackFrame::NO_ID); | 911 PrepareStep(StepNext, step_count, StackFrame::NO_ID); |
902 } else { | 912 } else { |
903 // Notify the debug event listeners. | 913 // Notify the debug event listeners. |
904 isolate_->debugger()->OnDebugBreak(break_points_hit, false); | 914 OnDebugBreak(break_points_hit, false); |
905 } | 915 } |
906 } else if (thread_local_.last_step_action_ != StepNone) { | 916 } else if (thread_local_.last_step_action_ != StepNone) { |
907 // Hold on to last step action as it is cleared by the call to | 917 // Hold on to last step action as it is cleared by the call to |
908 // ClearStepping. | 918 // ClearStepping. |
909 StepAction step_action = thread_local_.last_step_action_; | 919 StepAction step_action = thread_local_.last_step_action_; |
910 int step_count = thread_local_.step_count_; | 920 int step_count = thread_local_.step_count_; |
911 | 921 |
912 // If StepNext goes deeper in code, StepOut until original frame | 922 // If StepNext goes deeper in code, StepOut until original frame |
913 // and keep step count queued up in the meantime. | 923 // and keep step count queued up in the meantime. |
914 if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) { | 924 if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) { |
(...skipping 1688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2603 | 2613 |
2604 | 2614 |
2605 void Debug::AfterGarbageCollection() { | 2615 void Debug::AfterGarbageCollection() { |
2606 // Generate events for collected scripts. | 2616 // Generate events for collected scripts. |
2607 if (script_cache_ != NULL) { | 2617 if (script_cache_ != NULL) { |
2608 script_cache_->ProcessCollectedScripts(); | 2618 script_cache_->ProcessCollectedScripts(); |
2609 } | 2619 } |
2610 } | 2620 } |
2611 | 2621 |
2612 | 2622 |
2613 Debugger::Debugger(Isolate* isolate) | 2623 MaybeHandle<Object> Debug::MakeJSObject( |
2614 : event_listener_(Handle<Object>()), | |
2615 event_listener_data_(Handle<Object>()), | |
2616 is_active_(false), | |
2617 ignore_debugger_(false), | |
2618 live_edit_enabled_(true), | |
2619 message_handler_(NULL), | |
2620 command_queue_(isolate->logger(), kQueueInitialSize), | |
2621 command_received_(0), | |
2622 event_command_queue_(isolate->logger(), kQueueInitialSize), | |
2623 isolate_(isolate) { | |
2624 } | |
2625 | |
2626 | |
2627 Debugger::~Debugger() {} | |
2628 | |
2629 | |
2630 MaybeHandle<Object> Debugger::MakeJSObject( | |
2631 Vector<const char> constructor_name, | 2624 Vector<const char> constructor_name, |
2632 int argc, | 2625 int argc, |
2633 Handle<Object> argv[]) { | 2626 Handle<Object> argv[]) { |
2634 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); | 2627 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); |
2635 | 2628 |
2636 // Create the execution state object. | 2629 // Create the execution state object. |
2637 Handle<String> constructor_str = | 2630 Handle<String> constructor_str = |
2638 isolate_->factory()->InternalizeUtf8String(constructor_name); | 2631 isolate_->factory()->InternalizeUtf8String(constructor_name); |
2639 ASSERT(!constructor_str.is_null()); | 2632 ASSERT(!constructor_str.is_null()); |
2640 Handle<Object> constructor = Object::GetProperty( | 2633 Handle<Object> constructor = Object::GetProperty( |
2641 isolate_->global_object(), constructor_str).ToHandleChecked(); | 2634 isolate_->global_object(), constructor_str).ToHandleChecked(); |
2642 ASSERT(constructor->IsJSFunction()); | 2635 ASSERT(constructor->IsJSFunction()); |
2643 if (!constructor->IsJSFunction()) return MaybeHandle<Object>(); | 2636 if (!constructor->IsJSFunction()) return MaybeHandle<Object>(); |
2644 return Execution::TryCall( | 2637 return Execution::TryCall( |
2645 Handle<JSFunction>::cast(constructor), | 2638 Handle<JSFunction>::cast(constructor), |
2646 Handle<JSObject>(isolate_->debug()->debug_context()->global_object()), | 2639 Handle<JSObject>(isolate_->debug()->debug_context()->global_object()), |
2647 argc, | 2640 argc, |
2648 argv); | 2641 argv); |
2649 } | 2642 } |
2650 | 2643 |
2651 | 2644 |
2652 MaybeHandle<Object> Debugger::MakeExecutionState() { | 2645 MaybeHandle<Object> Debug::MakeExecutionState() { |
2653 // Create the execution state object. | 2646 // Create the execution state object. |
2654 Handle<Object> break_id = isolate_->factory()->NewNumberFromInt( | 2647 Handle<Object> break_id = isolate_->factory()->NewNumberFromInt( |
2655 isolate_->debug()->break_id()); | 2648 isolate_->debug()->break_id()); |
2656 Handle<Object> argv[] = { break_id }; | 2649 Handle<Object> argv[] = { break_id }; |
2657 return MakeJSObject(CStrVector("MakeExecutionState"), ARRAY_SIZE(argv), argv); | 2650 return MakeJSObject(CStrVector("MakeExecutionState"), ARRAY_SIZE(argv), argv); |
2658 } | 2651 } |
2659 | 2652 |
2660 | 2653 |
2661 MaybeHandle<Object> Debugger::MakeBreakEvent(Handle<Object> break_points_hit) { | 2654 MaybeHandle<Object> Debug::MakeBreakEvent(Handle<Object> break_points_hit) { |
2662 Handle<Object> exec_state; | 2655 Handle<Object> exec_state; |
2663 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); | 2656 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); |
2664 // Create the new break event object. | 2657 // Create the new break event object. |
2665 Handle<Object> argv[] = { exec_state, break_points_hit }; | 2658 Handle<Object> argv[] = { exec_state, break_points_hit }; |
2666 return MakeJSObject(CStrVector("MakeBreakEvent"), ARRAY_SIZE(argv), argv); | 2659 return MakeJSObject(CStrVector("MakeBreakEvent"), ARRAY_SIZE(argv), argv); |
2667 } | 2660 } |
2668 | 2661 |
2669 | 2662 |
2670 MaybeHandle<Object> Debugger::MakeExceptionEvent(Handle<Object> exception, | 2663 MaybeHandle<Object> Debug::MakeExceptionEvent(Handle<Object> exception, |
2671 bool uncaught, | 2664 bool uncaught, |
2672 Handle<Object> promise) { | 2665 Handle<Object> promise) { |
2673 Handle<Object> exec_state; | 2666 Handle<Object> exec_state; |
2674 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); | 2667 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); |
2675 // Create the new exception event object. | 2668 // Create the new exception event object. |
2676 Handle<Object> argv[] = { exec_state, | 2669 Handle<Object> argv[] = { exec_state, |
2677 exception, | 2670 exception, |
2678 isolate_->factory()->ToBoolean(uncaught), | 2671 isolate_->factory()->ToBoolean(uncaught), |
2679 promise }; | 2672 promise }; |
2680 return MakeJSObject(CStrVector("MakeExceptionEvent"), ARRAY_SIZE(argv), argv); | 2673 return MakeJSObject(CStrVector("MakeExceptionEvent"), ARRAY_SIZE(argv), argv); |
2681 } | 2674 } |
2682 | 2675 |
2683 | 2676 |
2684 MaybeHandle<Object> Debugger::MakeCompileEvent(Handle<Script> script, | 2677 MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script, |
2685 bool before) { | 2678 bool before) { |
2686 Handle<Object> exec_state; | 2679 Handle<Object> exec_state; |
2687 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); | 2680 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); |
2688 // Create the compile event object. | 2681 // Create the compile event object. |
2689 Handle<Object> script_wrapper = Script::GetWrapper(script); | 2682 Handle<Object> script_wrapper = Script::GetWrapper(script); |
2690 Handle<Object> argv[] = { exec_state, | 2683 Handle<Object> argv[] = { exec_state, |
2691 script_wrapper, | 2684 script_wrapper, |
2692 isolate_->factory()->ToBoolean(before) }; | 2685 isolate_->factory()->ToBoolean(before) }; |
2693 return MakeJSObject(CStrVector("MakeCompileEvent"), ARRAY_SIZE(argv), argv); | 2686 return MakeJSObject(CStrVector("MakeCompileEvent"), ARRAY_SIZE(argv), argv); |
2694 } | 2687 } |
2695 | 2688 |
2696 | 2689 |
2697 MaybeHandle<Object> Debugger::MakeScriptCollectedEvent(int id) { | 2690 MaybeHandle<Object> Debug::MakeScriptCollectedEvent(int id) { |
2698 Handle<Object> exec_state; | 2691 Handle<Object> exec_state; |
2699 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); | 2692 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); |
2700 // Create the script collected event object. | 2693 // Create the script collected event object. |
2701 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); | 2694 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); |
2702 Handle<Object> argv[] = { exec_state, id_object }; | 2695 Handle<Object> argv[] = { exec_state, id_object }; |
2703 | 2696 |
2704 return MakeJSObject( | 2697 return MakeJSObject( |
2705 CStrVector("MakeScriptCollectedEvent"), ARRAY_SIZE(argv), argv); | 2698 CStrVector("MakeScriptCollectedEvent"), ARRAY_SIZE(argv), argv); |
2706 } | 2699 } |
2707 | 2700 |
2708 | 2701 |
2709 void Debugger::OnException(Handle<Object> exception, bool uncaught) { | 2702 void Debug::OnException(Handle<Object> exception, bool uncaught) { |
2710 HandleScope scope(isolate_); | 2703 HandleScope scope(isolate_); |
2711 Debug* debug = isolate_->debug(); | 2704 Debug* debug = isolate_->debug(); |
2712 | 2705 |
2713 // Bail out based on state or if there is no listener for this event | 2706 // Bail out based on state or if there is no listener for this event |
2714 if (debug->InDebugger()) return; | 2707 if (debug->InDebugger()) return; |
2715 if (!Debugger::EventActive()) return; | 2708 if (!EventActive()) return; |
2716 | 2709 |
2717 Handle<Object> promise = debug->GetPromiseForUncaughtException(); | 2710 Handle<Object> promise = debug->GetPromiseForUncaughtException(); |
2718 uncaught |= !promise->IsUndefined(); | 2711 uncaught |= !promise->IsUndefined(); |
2719 | 2712 |
2720 // Bail out if exception breaks are not active | 2713 // Bail out if exception breaks are not active |
2721 if (uncaught) { | 2714 if (uncaught) { |
2722 // Uncaught exceptions are reported by either flags. | 2715 // Uncaught exceptions are reported by either flags. |
2723 if (!(debug->break_on_uncaught_exception() || | 2716 if (!(debug->break_on_uncaught_exception() || |
2724 debug->break_on_exception())) return; | 2717 debug->break_on_exception())) return; |
2725 } else { | 2718 } else { |
(...skipping 15 matching lines...) Expand all Loading... |
2741 exception, uncaught, promise).ToHandle(&event_data)) { | 2734 exception, uncaught, promise).ToHandle(&event_data)) { |
2742 return; | 2735 return; |
2743 } | 2736 } |
2744 | 2737 |
2745 // Process debug event. | 2738 // Process debug event. |
2746 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); | 2739 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); |
2747 // Return to continue execution from where the exception was thrown. | 2740 // Return to continue execution from where the exception was thrown. |
2748 } | 2741 } |
2749 | 2742 |
2750 | 2743 |
2751 void Debugger::OnDebugBreak(Handle<Object> break_points_hit, | 2744 void Debug::OnDebugBreak(Handle<Object> break_points_hit, |
2752 bool auto_continue) { | 2745 bool auto_continue) { |
2753 HandleScope scope(isolate_); | 2746 HandleScope scope(isolate_); |
2754 | 2747 |
2755 // Debugger has already been entered by caller. | 2748 // Debugger has already been entered by caller. |
2756 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); | 2749 ASSERT(isolate_->context() == *debug_context()); |
2757 | 2750 |
2758 // Bail out if there is no listener for this event | 2751 // Bail out if there is no listener for this event |
2759 if (!Debugger::EventActive()) return; | 2752 if (!EventActive()) return; |
2760 | |
2761 // Debugger must be entered in advance. | |
2762 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); | |
2763 | 2753 |
2764 // Create the event data object. | 2754 // Create the event data object. |
2765 Handle<Object> event_data; | 2755 Handle<Object> event_data; |
2766 // Bail out and don't call debugger if exception. | 2756 // Bail out and don't call debugger if exception. |
2767 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return; | 2757 if (!MakeBreakEvent(break_points_hit).ToHandle(&event_data)) return; |
2768 | 2758 |
2769 // Process debug event. | 2759 // Process debug event. |
2770 ProcessDebugEvent(v8::Break, | 2760 ProcessDebugEvent(v8::Break, |
2771 Handle<JSObject>::cast(event_data), | 2761 Handle<JSObject>::cast(event_data), |
2772 auto_continue); | 2762 auto_continue); |
2773 } | 2763 } |
2774 | 2764 |
2775 | 2765 |
2776 void Debugger::OnBeforeCompile(Handle<Script> script) { | 2766 void Debug::OnBeforeCompile(Handle<Script> script) { |
2777 HandleScope scope(isolate_); | 2767 HandleScope scope(isolate_); |
2778 | 2768 |
2779 // Bail out based on state or if there is no listener for this event | 2769 // Bail out based on state or if there is no listener for this event |
2780 if (isolate_->debug()->InDebugger()) return; | 2770 if (InDebugger()) return; |
2781 if (!EventActive()) return; | 2771 if (!EventActive()) return; |
2782 | 2772 |
2783 // Enter the debugger. | 2773 // Enter the debugger. |
2784 EnterDebugger debugger(isolate_); | 2774 EnterDebugger debugger(isolate_); |
2785 if (debugger.FailedToEnter()) return; | 2775 if (debugger.FailedToEnter()) return; |
2786 | 2776 |
2787 // Create the event data object. | 2777 // Create the event data object. |
2788 Handle<Object> event_data; | 2778 Handle<Object> event_data; |
2789 // Bail out and don't call debugger if exception. | 2779 // Bail out and don't call debugger if exception. |
2790 if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return; | 2780 if (!MakeCompileEvent(script, true).ToHandle(&event_data)) return; |
2791 | 2781 |
2792 // Process debug event. | 2782 // Process debug event. |
2793 ProcessDebugEvent(v8::BeforeCompile, | 2783 ProcessDebugEvent(v8::BeforeCompile, |
2794 Handle<JSObject>::cast(event_data), | 2784 Handle<JSObject>::cast(event_data), |
2795 true); | 2785 true); |
2796 } | 2786 } |
2797 | 2787 |
2798 | 2788 |
2799 // Handle debugger actions when a new script is compiled. | 2789 // Handle debugger actions when a new script is compiled. |
2800 void Debugger::OnAfterCompile(Handle<Script> script, | 2790 void Debug::OnAfterCompile(Handle<Script> script, |
2801 AfterCompileFlags after_compile_flags) { | 2791 AfterCompileFlags after_compile_flags) { |
2802 HandleScope scope(isolate_); | 2792 HandleScope scope(isolate_); |
2803 Debug* debug = isolate_->debug(); | |
2804 | 2793 |
2805 // Add the newly compiled script to the script cache. | 2794 // Add the newly compiled script to the script cache. |
2806 debug->AddScriptToScriptCache(script); | 2795 AddScriptToScriptCache(script); |
2807 | 2796 |
2808 // No more to do if not debugging. | 2797 // No more to do if not debugging. |
2809 if (!Debugger::EventActive()) return; | 2798 if (!EventActive()) return; |
2810 | 2799 |
2811 // Store whether in debugger before entering debugger. | 2800 // Store whether in debugger before entering debugger. |
2812 bool in_debugger = debug->InDebugger(); | 2801 bool in_debugger = InDebugger(); |
2813 | 2802 |
2814 // Enter the debugger. | 2803 // Enter the debugger. |
2815 EnterDebugger debugger(isolate_); | 2804 EnterDebugger debugger(isolate_); |
2816 if (debugger.FailedToEnter()) return; | 2805 if (debugger.FailedToEnter()) return; |
2817 | 2806 |
2818 // If debugging there might be script break points registered for this | 2807 // If debugging there might be script break points registered for this |
2819 // script. Make sure that these break points are set. | 2808 // script. Make sure that these break points are set. |
2820 | 2809 |
2821 // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js). | 2810 // Get the function UpdateScriptBreakPoints (defined in debug-debugger.js). |
2822 Handle<String> update_script_break_points_string = | 2811 Handle<String> update_script_break_points_string = |
2823 isolate_->factory()->InternalizeOneByteString( | 2812 isolate_->factory()->InternalizeOneByteString( |
2824 STATIC_ASCII_VECTOR("UpdateScriptBreakPoints")); | 2813 STATIC_ASCII_VECTOR("UpdateScriptBreakPoints")); |
2825 Handle<GlobalObject> debug_global(debug->debug_context()->global_object()); | 2814 Handle<GlobalObject> debug_global(debug_context()->global_object()); |
2826 Handle<Object> update_script_break_points = | 2815 Handle<Object> update_script_break_points = |
2827 Object::GetProperty( | 2816 Object::GetProperty( |
2828 debug_global, update_script_break_points_string).ToHandleChecked(); | 2817 debug_global, update_script_break_points_string).ToHandleChecked(); |
2829 if (!update_script_break_points->IsJSFunction()) { | 2818 if (!update_script_break_points->IsJSFunction()) { |
2830 return; | 2819 return; |
2831 } | 2820 } |
2832 ASSERT(update_script_break_points->IsJSFunction()); | 2821 ASSERT(update_script_break_points->IsJSFunction()); |
2833 | 2822 |
2834 // Wrap the script object in a proper JS object before passing it | 2823 // Wrap the script object in a proper JS object before passing it |
2835 // to JavaScript. | 2824 // to JavaScript. |
(...skipping 13 matching lines...) Expand all Loading... |
2849 // Create the compile state object. | 2838 // Create the compile state object. |
2850 Handle<Object> event_data; | 2839 Handle<Object> event_data; |
2851 // Bail out and don't call debugger if exception. | 2840 // Bail out and don't call debugger if exception. |
2852 if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return; | 2841 if (!MakeCompileEvent(script, false).ToHandle(&event_data)) return; |
2853 | 2842 |
2854 // Process debug event. | 2843 // Process debug event. |
2855 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true); | 2844 ProcessDebugEvent(v8::AfterCompile, Handle<JSObject>::cast(event_data), true); |
2856 } | 2845 } |
2857 | 2846 |
2858 | 2847 |
2859 void Debugger::OnScriptCollected(int id) { | 2848 void Debug::OnScriptCollected(int id) { |
2860 HandleScope scope(isolate_); | 2849 HandleScope scope(isolate_); |
2861 | 2850 |
2862 // No more to do if not debugging. | 2851 // No more to do if not debugging. |
2863 if (isolate_->debug()->InDebugger()) return; | 2852 if (InDebugger()) return; |
2864 if (!Debugger::EventActive()) return; | 2853 if (!EventActive()) return; |
2865 | 2854 |
2866 // Enter the debugger. | 2855 // Enter the debugger. |
2867 EnterDebugger debugger(isolate_); | 2856 EnterDebugger debugger(isolate_); |
2868 if (debugger.FailedToEnter()) return; | 2857 if (debugger.FailedToEnter()) return; |
2869 | 2858 |
2870 // Create the script collected state object. | 2859 // Create the script collected state object. |
2871 Handle<Object> event_data; | 2860 Handle<Object> event_data; |
2872 // Bail out and don't call debugger if exception. | 2861 // Bail out and don't call debugger if exception. |
2873 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return; | 2862 if (!MakeScriptCollectedEvent(id).ToHandle(&event_data)) return; |
2874 | 2863 |
2875 // Process debug event. | 2864 // Process debug event. |
2876 ProcessDebugEvent(v8::ScriptCollected, | 2865 ProcessDebugEvent(v8::ScriptCollected, |
2877 Handle<JSObject>::cast(event_data), | 2866 Handle<JSObject>::cast(event_data), |
2878 true); | 2867 true); |
2879 } | 2868 } |
2880 | 2869 |
2881 | 2870 |
2882 void Debugger::ProcessDebugEvent(v8::DebugEvent event, | 2871 void Debug::ProcessDebugEvent(v8::DebugEvent event, |
2883 Handle<JSObject> event_data, | 2872 Handle<JSObject> event_data, |
2884 bool auto_continue) { | 2873 bool auto_continue) { |
2885 HandleScope scope(isolate_); | 2874 HandleScope scope(isolate_); |
2886 | 2875 |
2887 // Clear any pending debug break if this is a real break. | 2876 // Clear any pending debug break if this is a real break. |
2888 if (!auto_continue) { | 2877 if (!auto_continue) set_has_pending_interrupt(false); |
2889 isolate_->debug()->set_has_pending_interrupt(false); | |
2890 } | |
2891 | 2878 |
2892 // Create the execution state. | 2879 // Create the execution state. |
2893 Handle<Object> exec_state; | 2880 Handle<Object> exec_state; |
2894 // Bail out and don't call debugger if exception. | 2881 // Bail out and don't call debugger if exception. |
2895 if (!MakeExecutionState().ToHandle(&exec_state)) return; | 2882 if (!MakeExecutionState().ToHandle(&exec_state)) return; |
2896 | 2883 |
2897 // First notify the message handler if any. | 2884 // First notify the message handler if any. |
2898 if (message_handler_ != NULL) { | 2885 if (message_handler_ != NULL) { |
2899 NotifyMessageHandler(event, | 2886 NotifyMessageHandler(event, |
2900 Handle<JSObject>::cast(exec_state), | 2887 Handle<JSObject>::cast(exec_state), |
(...skipping 15 matching lines...) Expand all Loading... |
2916 exec_state, | 2903 exec_state, |
2917 event_data, | 2904 event_data, |
2918 command.client_data()); | 2905 command.client_data()); |
2919 } | 2906 } |
2920 command.Dispose(); | 2907 command.Dispose(); |
2921 } | 2908 } |
2922 } | 2909 } |
2923 } | 2910 } |
2924 | 2911 |
2925 | 2912 |
2926 void Debugger::CallEventCallback(v8::DebugEvent event, | 2913 void Debug::CallEventCallback(v8::DebugEvent event, |
2927 Handle<Object> exec_state, | 2914 Handle<Object> exec_state, |
2928 Handle<Object> event_data, | 2915 Handle<Object> event_data, |
2929 v8::Debug::ClientData* client_data) { | 2916 v8::Debug::ClientData* client_data) { |
2930 if (event_listener_->IsForeign()) { | 2917 if (event_listener_->IsForeign()) { |
2931 CallCEventCallback(event, exec_state, event_data, client_data); | 2918 CallCEventCallback(event, exec_state, event_data, client_data); |
2932 } else { | 2919 } else { |
2933 CallJSEventCallback(event, exec_state, event_data); | 2920 CallJSEventCallback(event, exec_state, event_data); |
2934 } | 2921 } |
2935 } | 2922 } |
2936 | 2923 |
2937 | 2924 |
2938 void Debugger::CallCEventCallback(v8::DebugEvent event, | 2925 void Debug::CallCEventCallback(v8::DebugEvent event, |
2939 Handle<Object> exec_state, | 2926 Handle<Object> exec_state, |
2940 Handle<Object> event_data, | 2927 Handle<Object> event_data, |
2941 v8::Debug::ClientData* client_data) { | 2928 v8::Debug::ClientData* client_data) { |
2942 Handle<Foreign> callback_obj(Handle<Foreign>::cast(event_listener_)); | 2929 Handle<Foreign> callback_obj(Handle<Foreign>::cast(event_listener_)); |
2943 v8::Debug::EventCallback2 callback = | 2930 v8::Debug::EventCallback2 callback = |
2944 FUNCTION_CAST<v8::Debug::EventCallback2>( | 2931 FUNCTION_CAST<v8::Debug::EventCallback2>( |
2945 callback_obj->foreign_address()); | 2932 callback_obj->foreign_address()); |
2946 EventDetailsImpl event_details( | 2933 EventDetailsImpl event_details( |
2947 event, | 2934 event, |
2948 Handle<JSObject>::cast(exec_state), | 2935 Handle<JSObject>::cast(exec_state), |
2949 Handle<JSObject>::cast(event_data), | 2936 Handle<JSObject>::cast(event_data), |
2950 event_listener_data_, | 2937 event_listener_data_, |
2951 client_data); | 2938 client_data); |
2952 callback(event_details); | 2939 callback(event_details); |
2953 } | 2940 } |
2954 | 2941 |
2955 | 2942 |
2956 void Debugger::CallJSEventCallback(v8::DebugEvent event, | 2943 void Debug::CallJSEventCallback(v8::DebugEvent event, |
2957 Handle<Object> exec_state, | 2944 Handle<Object> exec_state, |
2958 Handle<Object> event_data) { | 2945 Handle<Object> event_data) { |
2959 ASSERT(event_listener_->IsJSFunction()); | 2946 ASSERT(event_listener_->IsJSFunction()); |
2960 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); | 2947 Handle<JSFunction> fun(Handle<JSFunction>::cast(event_listener_)); |
2961 | 2948 |
2962 // Invoke the JavaScript debug event listener. | 2949 // Invoke the JavaScript debug event listener. |
2963 Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_), | 2950 Handle<Object> argv[] = { Handle<Object>(Smi::FromInt(event), isolate_), |
2964 exec_state, | 2951 exec_state, |
2965 event_data, | 2952 event_data, |
2966 event_listener_data_ }; | 2953 event_listener_data_ }; |
2967 Execution::TryCall(fun, | 2954 Execution::TryCall(fun, |
2968 isolate_->global_object(), | 2955 isolate_->global_object(), |
2969 ARRAY_SIZE(argv), | 2956 ARRAY_SIZE(argv), |
2970 argv); | 2957 argv); |
2971 // Silently ignore exceptions from debug event listeners. | 2958 // Silently ignore exceptions from debug event listeners. |
2972 } | 2959 } |
2973 | 2960 |
2974 | 2961 |
2975 Handle<Context> Debugger::GetDebugContext() { | 2962 Handle<Context> Debug::GetDebugContext() { |
2976 EnterDebugger debugger(isolate_); | 2963 EnterDebugger debugger(isolate_); |
2977 // The global handle may be destroyed soon after. Return it reboxed. | 2964 // The global handle may be destroyed soon after. Return it reboxed. |
2978 return handle(*isolate_->debug()->debug_context(), isolate_); | 2965 return handle(*debug_context(), isolate_); |
2979 } | 2966 } |
2980 | 2967 |
2981 | 2968 |
2982 void Debugger::NotifyMessageHandler(v8::DebugEvent event, | 2969 void Debug::NotifyMessageHandler(v8::DebugEvent event, |
2983 Handle<JSObject> exec_state, | 2970 Handle<JSObject> exec_state, |
2984 Handle<JSObject> event_data, | 2971 Handle<JSObject> event_data, |
2985 bool auto_continue) { | 2972 bool auto_continue) { |
2986 ASSERT(is_active_); | 2973 ASSERT(is_active_); |
2987 HandleScope scope(isolate_); | 2974 HandleScope scope(isolate_); |
2988 // Process the individual events. | 2975 // Process the individual events. |
2989 bool sendEventMessage = false; | 2976 bool sendEventMessage = false; |
2990 switch (event) { | 2977 switch (event) { |
2991 case v8::Break: | 2978 case v8::Break: |
2992 case v8::BreakForCommand: | 2979 case v8::BreakForCommand: |
2993 sendEventMessage = !auto_continue; | 2980 sendEventMessage = !auto_continue; |
2994 break; | 2981 break; |
2995 case v8::Exception: | 2982 case v8::Exception: |
2996 sendEventMessage = true; | 2983 sendEventMessage = true; |
2997 break; | 2984 break; |
2998 case v8::BeforeCompile: | 2985 case v8::BeforeCompile: |
2999 break; | 2986 break; |
3000 case v8::AfterCompile: | 2987 case v8::AfterCompile: |
3001 sendEventMessage = true; | 2988 sendEventMessage = true; |
3002 break; | 2989 break; |
3003 case v8::ScriptCollected: | 2990 case v8::ScriptCollected: |
3004 sendEventMessage = true; | 2991 sendEventMessage = true; |
3005 break; | 2992 break; |
3006 case v8::NewFunction: | 2993 case v8::NewFunction: |
3007 break; | 2994 break; |
3008 default: | 2995 default: |
3009 UNREACHABLE(); | 2996 UNREACHABLE(); |
3010 } | 2997 } |
3011 | 2998 |
3012 // The debug command interrupt flag might have been set when the command was | 2999 // The debug command interrupt flag might have been set when the command was |
3013 // added. It should be enough to clear the flag only once while we are in the | 3000 // added. It should be enough to clear the flag only once while we are in the |
3014 // debugger. | 3001 // debugger. |
3015 ASSERT(isolate_->debug()->InDebugger()); | 3002 ASSERT(InDebugger()); |
3016 isolate_->stack_guard()->ClearDebugCommand(); | 3003 isolate_->stack_guard()->ClearDebugCommand(); |
3017 | 3004 |
3018 // Notify the debugger that a debug event has occurred unless auto continue is | 3005 // Notify the debugger that a debug event has occurred unless auto continue is |
3019 // active in which case no event is send. | 3006 // active in which case no event is send. |
3020 if (sendEventMessage) { | 3007 if (sendEventMessage) { |
3021 MessageImpl message = MessageImpl::NewEvent( | 3008 MessageImpl message = MessageImpl::NewEvent( |
3022 event, | 3009 event, |
3023 auto_continue, | 3010 auto_continue, |
3024 Handle<JSObject>::cast(exec_state), | 3011 Handle<JSObject>::cast(exec_state), |
3025 Handle<JSObject>::cast(event_data)); | 3012 Handle<JSObject>::cast(event_data)); |
(...skipping 24 matching lines...) Expand all Loading... |
3050 | 3037 |
3051 // Process requests from the debugger. | 3038 // Process requests from the debugger. |
3052 do { | 3039 do { |
3053 // Wait for new command in the queue. | 3040 // Wait for new command in the queue. |
3054 command_received_.Wait(); | 3041 command_received_.Wait(); |
3055 | 3042 |
3056 // Get the command from the queue. | 3043 // Get the command from the queue. |
3057 CommandMessage command = command_queue_.Get(); | 3044 CommandMessage command = command_queue_.Get(); |
3058 isolate_->logger()->DebugTag( | 3045 isolate_->logger()->DebugTag( |
3059 "Got request from command queue, in interactive loop."); | 3046 "Got request from command queue, in interactive loop."); |
3060 if (!Debugger::is_active()) { | 3047 if (!is_active()) { |
3061 // Delete command text and user data. | 3048 // Delete command text and user data. |
3062 command.Dispose(); | 3049 command.Dispose(); |
3063 return; | 3050 return; |
3064 } | 3051 } |
3065 | 3052 |
3066 Vector<const uc16> command_text( | 3053 Vector<const uc16> command_text( |
3067 const_cast<const uc16*>(command.text().start()), | 3054 const_cast<const uc16*>(command.text().start()), |
3068 command.text().length()); | 3055 command.text().length()); |
3069 Handle<String> request_text = isolate_->factory()->NewStringFromTwoByte( | 3056 Handle<String> request_text = isolate_->factory()->NewStringFromTwoByte( |
3070 command_text).ToHandleChecked(); | 3057 command_text).ToHandleChecked(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3103 InvokeMessageHandler(message); | 3090 InvokeMessageHandler(message); |
3104 command.Dispose(); | 3091 command.Dispose(); |
3105 | 3092 |
3106 // Return from debug event processing if either the VM is put into the | 3093 // Return from debug event processing if either the VM is put into the |
3107 // running state (through a continue command) or auto continue is active | 3094 // running state (through a continue command) or auto continue is active |
3108 // and there are no more commands queued. | 3095 // and there are no more commands queued. |
3109 } while (!running || HasCommands()); | 3096 } while (!running || HasCommands()); |
3110 } | 3097 } |
3111 | 3098 |
3112 | 3099 |
3113 void Debugger::SetEventListener(Handle<Object> callback, | 3100 void Debug::SetEventListener(Handle<Object> callback, |
3114 Handle<Object> data) { | 3101 Handle<Object> data) { |
3115 GlobalHandles* global_handles = isolate_->global_handles(); | 3102 GlobalHandles* global_handles = isolate_->global_handles(); |
3116 | 3103 |
3117 // Remove existing entry. | 3104 // Remove existing entry. |
3118 GlobalHandles::Destroy(event_listener_.location()); | 3105 GlobalHandles::Destroy(event_listener_.location()); |
3119 event_listener_ = Handle<Object>(); | 3106 event_listener_ = Handle<Object>(); |
3120 GlobalHandles::Destroy(event_listener_data_.location()); | 3107 GlobalHandles::Destroy(event_listener_data_.location()); |
3121 event_listener_data_ = Handle<Object>(); | 3108 event_listener_data_ = Handle<Object>(); |
3122 | 3109 |
3123 // Set new entry. | 3110 // Set new entry. |
3124 if (!callback->IsUndefined() && !callback->IsNull()) { | 3111 if (!callback->IsUndefined() && !callback->IsNull()) { |
3125 event_listener_ = global_handles->Create(*callback); | 3112 event_listener_ = global_handles->Create(*callback); |
3126 if (data.is_null()) data = isolate_->factory()->undefined_value(); | 3113 if (data.is_null()) data = isolate_->factory()->undefined_value(); |
3127 event_listener_data_ = global_handles->Create(*data); | 3114 event_listener_data_ = global_handles->Create(*data); |
3128 } | 3115 } |
3129 | 3116 |
3130 UpdateState(); | 3117 UpdateState(); |
3131 } | 3118 } |
3132 | 3119 |
3133 | 3120 |
3134 void Debugger::SetMessageHandler(v8::Debug::MessageHandler handler) { | 3121 void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) { |
3135 message_handler_ = handler; | 3122 message_handler_ = handler; |
3136 UpdateState(); | 3123 UpdateState(); |
3137 if (handler == NULL && isolate_->debug()->InDebugger()) { | 3124 if (handler == NULL && InDebugger()) { |
3138 // Send an empty command to the debugger if in a break to make JavaScript | 3125 // Send an empty command to the debugger if in a break to make JavaScript |
3139 // run again if the debugger is closed. | 3126 // run again if the debugger is closed. |
3140 EnqueueCommandMessage(Vector<const uint16_t>::empty()); | 3127 EnqueueCommandMessage(Vector<const uint16_t>::empty()); |
3141 } | 3128 } |
3142 } | 3129 } |
3143 | 3130 |
3144 | 3131 |
3145 void Debugger::UpdateState() { | 3132 |
3146 Debug* debug = isolate_->debug(); | 3133 void Debug::UpdateState() { |
3147 bool activate = message_handler_ != NULL || | 3134 bool activate = message_handler_ != NULL || |
3148 !event_listener_.is_null() || | 3135 !event_listener_.is_null() || |
3149 debug->InDebugger(); | 3136 InDebugger(); |
3150 if (!is_active_ && activate) { | 3137 if (!is_active_ && activate) { |
3151 // Note that the debug context could have already been loaded to | 3138 // Note that the debug context could have already been loaded to |
3152 // bootstrap test cases. | 3139 // bootstrap test cases. |
3153 isolate_->compilation_cache()->Disable(); | 3140 isolate_->compilation_cache()->Disable(); |
3154 activate = debug->Load(); | 3141 activate = Load(); |
3155 } else if (debug->IsLoaded() && !activate) { | 3142 } else if (IsLoaded() && !activate) { |
3156 isolate_->compilation_cache()->Enable(); | 3143 isolate_->compilation_cache()->Enable(); |
3157 debug->Unload(); | 3144 Unload(); |
3158 } | 3145 } |
3159 is_active_ = activate; | 3146 is_active_ = activate; |
3160 // At this point the debug context is loaded iff the debugger is active. | 3147 // At this point the debug context is loaded iff the debugger is active. |
3161 ASSERT(debug->IsLoaded() == is_active_); | 3148 ASSERT(IsLoaded() == is_active_); |
3162 } | 3149 } |
3163 | 3150 |
3164 | 3151 |
3165 // Calls the registered debug message handler. This callback is part of the | 3152 // Calls the registered debug message handler. This callback is part of the |
3166 // public API. | 3153 // public API. |
3167 void Debugger::InvokeMessageHandler(MessageImpl message) { | 3154 void Debug::InvokeMessageHandler(MessageImpl message) { |
3168 if (message_handler_ != NULL) message_handler_(message); | 3155 if (message_handler_ != NULL) message_handler_(message); |
3169 } | 3156 } |
3170 | 3157 |
3171 | 3158 |
3172 // Puts a command coming from the public API on the queue. Creates | 3159 // Puts a command coming from the public API on the queue. Creates |
3173 // a copy of the command string managed by the debugger. Up to this | 3160 // a copy of the command string managed by the debugger. Up to this |
3174 // point, the command data was managed by the API client. Called | 3161 // point, the command data was managed by the API client. Called |
3175 // by the API client thread. | 3162 // by the API client thread. |
3176 void Debugger::EnqueueCommandMessage(Vector<const uint16_t> command, | 3163 void Debug::EnqueueCommandMessage(Vector<const uint16_t> command, |
3177 v8::Debug::ClientData* client_data) { | 3164 v8::Debug::ClientData* client_data) { |
3178 // Need to cast away const. | 3165 // Need to cast away const. |
3179 CommandMessage message = CommandMessage::New( | 3166 CommandMessage message = CommandMessage::New( |
3180 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), | 3167 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), |
3181 command.length()), | 3168 command.length()), |
3182 client_data); | 3169 client_data); |
3183 isolate_->logger()->DebugTag("Put command on command_queue."); | 3170 isolate_->logger()->DebugTag("Put command on command_queue."); |
3184 command_queue_.Put(message); | 3171 command_queue_.Put(message); |
3185 command_received_.Signal(); | 3172 command_received_.Signal(); |
3186 | 3173 |
3187 // Set the debug command break flag to have the command processed. | 3174 // Set the debug command break flag to have the command processed. |
3188 if (!isolate_->debug()->InDebugger()) { | 3175 if (!isolate_->debug()->InDebugger()) { |
3189 isolate_->stack_guard()->RequestDebugCommand(); | 3176 isolate_->stack_guard()->RequestDebugCommand(); |
3190 } | 3177 } |
3191 } | 3178 } |
3192 | 3179 |
3193 | 3180 |
3194 bool Debugger::HasCommands() { | 3181 bool Debug::HasCommands() { |
3195 return !command_queue_.IsEmpty(); | 3182 return !command_queue_.IsEmpty(); |
3196 } | 3183 } |
3197 | 3184 |
3198 | 3185 |
3199 void Debugger::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { | 3186 void Debug::EnqueueDebugCommand(v8::Debug::ClientData* client_data) { |
3200 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); | 3187 CommandMessage message = CommandMessage::New(Vector<uint16_t>(), client_data); |
3201 event_command_queue_.Put(message); | 3188 event_command_queue_.Put(message); |
3202 | 3189 |
3203 // Set the debug command break flag to have the command processed. | 3190 // Set the debug command break flag to have the command processed. |
3204 if (!isolate_->debug()->InDebugger()) { | 3191 if (!InDebugger()) isolate_->stack_guard()->RequestDebugCommand(); |
3205 isolate_->stack_guard()->RequestDebugCommand(); | |
3206 } | |
3207 } | 3192 } |
3208 | 3193 |
3209 | 3194 |
3210 MaybeHandle<Object> Debugger::Call(Handle<JSFunction> fun, | 3195 MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) { |
3211 Handle<Object> data) { | |
3212 // Enter the debugger. | 3196 // Enter the debugger. |
3213 EnterDebugger debugger(isolate_); | 3197 EnterDebugger debugger(isolate_); |
3214 if (debugger.FailedToEnter()) { | 3198 if (debugger.FailedToEnter()) { |
3215 return isolate_->factory()->undefined_value(); | 3199 return isolate_->factory()->undefined_value(); |
3216 } | 3200 } |
3217 | 3201 |
3218 // Create the execution state. | 3202 // Create the execution state. |
3219 Handle<Object> exec_state; | 3203 Handle<Object> exec_state; |
3220 if (!MakeExecutionState().ToHandle(&exec_state)) { | 3204 if (!MakeExecutionState().ToHandle(&exec_state)) { |
3221 return isolate_->factory()->undefined_value(); | 3205 return isolate_->factory()->undefined_value(); |
3222 } | 3206 } |
3223 | 3207 |
3224 Handle<Object> argv[] = { exec_state, data }; | 3208 Handle<Object> argv[] = { exec_state, data }; |
3225 return Execution::Call( | 3209 return Execution::Call( |
3226 isolate_, | 3210 isolate_, |
3227 fun, | 3211 fun, |
3228 Handle<Object>(isolate_->debug()->debug_context_->global_proxy(), | 3212 Handle<Object>(debug_context()->global_proxy(), isolate_), |
3229 isolate_), | |
3230 ARRAY_SIZE(argv), | 3213 ARRAY_SIZE(argv), |
3231 argv); | 3214 argv); |
3232 } | 3215 } |
3233 | 3216 |
3234 | 3217 |
3235 EnterDebugger::EnterDebugger(Isolate* isolate) | 3218 EnterDebugger::EnterDebugger(Isolate* isolate) |
3236 : isolate_(isolate), | 3219 : isolate_(isolate), |
3237 prev_(isolate_->debug()->debugger_entry()), | 3220 prev_(isolate_->debug()->debugger_entry()), |
3238 save_(isolate_) { | 3221 save_(isolate_) { |
3239 Debug* debug = isolate_->debug(); | 3222 Debug* debug = isolate_->debug(); |
3240 | 3223 |
3241 // Link recursive debugger entry. | 3224 // Link recursive debugger entry. |
3242 debug->set_debugger_entry(this); | 3225 debug->set_debugger_entry(this); |
3243 | 3226 |
3244 // Store the previous break id and frame id. | 3227 // Store the previous break id and frame id. |
3245 break_id_ = debug->break_id(); | 3228 break_id_ = debug->break_id(); |
3246 break_frame_id_ = debug->break_frame_id(); | 3229 break_frame_id_ = debug->break_frame_id(); |
3247 | 3230 |
3248 // Create the new break info. If there is no JavaScript frames there is no | 3231 // Create the new break info. If there is no JavaScript frames there is no |
3249 // break frame id. | 3232 // break frame id. |
3250 JavaScriptFrameIterator it(isolate_); | 3233 JavaScriptFrameIterator it(isolate_); |
3251 has_js_frames_ = !it.done(); | 3234 has_js_frames_ = !it.done(); |
3252 debug->NewBreak(has_js_frames_ ? it.frame()->id() : StackFrame::NO_ID); | 3235 debug->NewBreak(has_js_frames_ ? it.frame()->id() : StackFrame::NO_ID); |
3253 | 3236 |
3254 isolate_->debugger()->UpdateState(); | 3237 debug->UpdateState(); |
3255 // Make sure that debugger is loaded and enter the debugger context. | 3238 // Make sure that debugger is loaded and enter the debugger context. |
3256 // The previous context is kept in save_. | 3239 // The previous context is kept in save_. |
3257 load_failed_ = !debug->IsLoaded(); | 3240 load_failed_ = !debug->IsLoaded(); |
3258 if (!load_failed_) isolate_->set_context(*debug->debug_context()); | 3241 if (!load_failed_) isolate_->set_context(*debug->debug_context()); |
3259 } | 3242 } |
3260 | 3243 |
3261 | 3244 |
3262 EnterDebugger::~EnterDebugger() { | 3245 EnterDebugger::~EnterDebugger() { |
3263 Debug* debug = isolate_->debug(); | 3246 Debug* debug = isolate_->debug(); |
3264 | 3247 |
3265 // Restore to the previous break state. | 3248 // Restore to the previous break state. |
3266 debug->SetBreak(break_frame_id_, break_id_); | 3249 debug->SetBreak(break_frame_id_, break_id_); |
3267 | 3250 |
3268 // Check for leaving the debugger. | 3251 // Check for leaving the debugger. |
3269 if (!load_failed_ && prev_ == NULL) { | 3252 if (!load_failed_ && prev_ == NULL) { |
3270 // Clear mirror cache when leaving the debugger. Skip this if there is a | 3253 // Clear mirror cache when leaving the debugger. Skip this if there is a |
3271 // pending exception as clearing the mirror cache calls back into | 3254 // pending exception as clearing the mirror cache calls back into |
3272 // JavaScript. This can happen if the v8::Debug::Call is used in which | 3255 // JavaScript. This can happen if the v8::Debug::Call is used in which |
3273 // case the exception should end up in the calling code. | 3256 // case the exception should end up in the calling code. |
3274 if (!isolate_->has_pending_exception()) { | 3257 if (!isolate_->has_pending_exception()) { |
3275 debug->ClearMirrorCache(); | 3258 debug->ClearMirrorCache(); |
3276 } | 3259 } |
3277 | 3260 |
3278 // If there are commands in the queue when leaving the debugger request | 3261 // If there are commands in the queue when leaving the debugger request |
3279 // that these commands are processed. | 3262 // that these commands are processed. |
3280 if (isolate_->debugger()->HasCommands()) { | 3263 if (debug->HasCommands()) { |
3281 isolate_->stack_guard()->RequestDebugCommand(); | 3264 isolate_->stack_guard()->RequestDebugCommand(); |
3282 } | 3265 } |
3283 } | 3266 } |
3284 | 3267 |
3285 // Leaving this debugger entry. | 3268 // Leaving this debugger entry. |
3286 debug->set_debugger_entry(prev_); | 3269 debug->set_debugger_entry(prev_); |
3287 | 3270 |
3288 isolate_->debugger()->UpdateState(); | 3271 debug->UpdateState(); |
3289 } | 3272 } |
3290 | 3273 |
3291 | 3274 |
3292 MessageImpl MessageImpl::NewEvent(DebugEvent event, | 3275 MessageImpl MessageImpl::NewEvent(DebugEvent event, |
3293 bool running, | 3276 bool running, |
3294 Handle<JSObject> exec_state, | 3277 Handle<JSObject> exec_state, |
3295 Handle<JSObject> event_data) { | 3278 Handle<JSObject> event_data) { |
3296 MessageImpl message(true, event, running, | 3279 MessageImpl message(true, event, running, |
3297 exec_state, event_data, Handle<String>(), NULL); | 3280 exec_state, event_data, Handle<String>(), NULL); |
3298 return message; | 3281 return message; |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3542 logger_->DebugEvent("Put", message.text()); | 3525 logger_->DebugEvent("Put", message.text()); |
3543 } | 3526 } |
3544 | 3527 |
3545 | 3528 |
3546 void LockingCommandMessageQueue::Clear() { | 3529 void LockingCommandMessageQueue::Clear() { |
3547 LockGuard<Mutex> lock_guard(&mutex_); | 3530 LockGuard<Mutex> lock_guard(&mutex_); |
3548 queue_.Clear(); | 3531 queue_.Clear(); |
3549 } | 3532 } |
3550 | 3533 |
3551 } } // namespace v8::internal | 3534 } } // namespace v8::internal |
OLD | NEW |