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