| 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 19 matching lines...) Expand all Loading... |
| 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 : has_break_points_(false), |
| 35 script_cache_(NULL), | 35 script_cache_(NULL), |
| 36 debug_info_list_(NULL), | 36 debug_info_list_(NULL), |
| 37 disable_break_(false), | 37 disable_break_(false), |
| 38 break_on_exception_(false), | 38 break_on_exception_(false), |
| 39 break_on_uncaught_exception_(false), | 39 break_on_uncaught_exception_(false), |
| 40 current_promise_catch_handler_(NULL), | |
| 41 debug_break_return_(NULL), | 40 debug_break_return_(NULL), |
| 42 debug_break_slot_(NULL), | 41 debug_break_slot_(NULL), |
| 43 isolate_(isolate) { | 42 isolate_(isolate) { |
| 44 memset(registers_, 0, sizeof(JSCallerSavedBuffer)); | 43 memset(registers_, 0, sizeof(JSCallerSavedBuffer)); |
| 45 } | 44 } |
| 46 | 45 |
| 47 | 46 |
| 48 Debug::~Debug() { | 47 Debug::~Debug() { |
| 49 } | 48 } |
| 50 | 49 |
| (...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 | 1311 |
| 1313 bool Debug::IsBreakOnException(ExceptionBreakType type) { | 1312 bool Debug::IsBreakOnException(ExceptionBreakType type) { |
| 1314 if (type == BreakUncaughtException) { | 1313 if (type == BreakUncaughtException) { |
| 1315 return break_on_uncaught_exception_; | 1314 return break_on_uncaught_exception_; |
| 1316 } else { | 1315 } else { |
| 1317 return break_on_exception_; | 1316 return break_on_exception_; |
| 1318 } | 1317 } |
| 1319 } | 1318 } |
| 1320 | 1319 |
| 1321 | 1320 |
| 1322 void Debug::PromiseHandlePrologue(Handle<JSFunction> promise_getter) { | |
| 1323 ASSERT(current_promise_getter_.is_null()); | |
| 1324 current_promise_getter_ = Handle<JSFunction>::cast( | |
| 1325 isolate_->global_handles()->Create(*promise_getter)); | |
| 1326 current_promise_catch_handler_ = | |
| 1327 StackHandler::FromAddress(Isolate::handler(isolate_->thread_local_top())); | |
| 1328 } | |
| 1329 | |
| 1330 | |
| 1331 void Debug::PromiseHandleEpilogue() { | |
| 1332 current_promise_catch_handler_ = NULL; | |
| 1333 Handle<Object> promise_getter; | |
| 1334 if (!current_promise_getter_.ToHandle(&promise_getter)) return; | |
| 1335 isolate_->global_handles()->Destroy(promise_getter.location()); | |
| 1336 current_promise_getter_ = MaybeHandle<JSFunction>(); | |
| 1337 } | |
| 1338 | |
| 1339 | |
| 1340 Handle<Object> Debug::GetPromiseForUncaughtException() { | |
| 1341 Handle<JSFunction> promise_getter; | |
| 1342 Handle<Object> undefined = isolate_->factory()->undefined_value(); | |
| 1343 if (current_promise_getter_.ToHandle(&promise_getter)) { | |
| 1344 // Find the top-most try-catch handler. | |
| 1345 StackHandler* handler = StackHandler::FromAddress( | |
| 1346 Isolate::handler(isolate_->thread_local_top())); | |
| 1347 while (handler != NULL && !handler->is_catch()) { | |
| 1348 handler = handler->next(); | |
| 1349 } | |
| 1350 #ifdef DEBUG | |
| 1351 // Make sure that our promise catch handler is in the list of handlers, | |
| 1352 // even if it's not the top-most try-catch handler. | |
| 1353 StackHandler* temp = handler; | |
| 1354 while (temp != current_promise_catch_handler_ && !temp->is_catch()) { | |
| 1355 temp = temp->next(); | |
| 1356 CHECK(temp != NULL); | |
| 1357 } | |
| 1358 #endif // DEBUG | |
| 1359 | |
| 1360 if (handler == current_promise_catch_handler_) { | |
| 1361 return Execution::Call( | |
| 1362 isolate_, promise_getter, undefined, 0, NULL).ToHandleChecked(); | |
| 1363 } | |
| 1364 } | |
| 1365 return undefined; | |
| 1366 } | |
| 1367 | |
| 1368 | |
| 1369 void Debug::PrepareStep(StepAction step_action, | 1321 void Debug::PrepareStep(StepAction step_action, |
| 1370 int step_count, | 1322 int step_count, |
| 1371 StackFrame::Id frame_id) { | 1323 StackFrame::Id frame_id) { |
| 1372 HandleScope scope(isolate_); | 1324 HandleScope scope(isolate_); |
| 1373 | 1325 |
| 1374 PrepareForBreakPoints(); | 1326 PrepareForBreakPoints(); |
| 1375 | 1327 |
| 1376 ASSERT(Debug::InDebugger()); | 1328 ASSERT(Debug::InDebugger()); |
| 1377 | 1329 |
| 1378 // Remember this step action and count. | 1330 // Remember this step action and count. |
| (...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2688 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); | 2640 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); |
| 2689 // Create the script collected event object. | 2641 // Create the script collected event object. |
| 2690 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); | 2642 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); |
| 2691 Handle<Object> argv[] = { exec_state, id_object }; | 2643 Handle<Object> argv[] = { exec_state, id_object }; |
| 2692 | 2644 |
| 2693 return MakeJSObject( | 2645 return MakeJSObject( |
| 2694 CStrVector("MakeScriptCollectedEvent"), ARRAY_SIZE(argv), argv); | 2646 CStrVector("MakeScriptCollectedEvent"), ARRAY_SIZE(argv), argv); |
| 2695 } | 2647 } |
| 2696 | 2648 |
| 2697 | 2649 |
| 2698 void Debugger::OnException(Handle<Object> exception, bool uncaught) { | 2650 void Debugger::OnException(Handle<Object> exception, |
| 2651 bool uncaught, |
| 2652 Handle<Object> promise) { |
| 2699 HandleScope scope(isolate_); | 2653 HandleScope scope(isolate_); |
| 2700 Debug* debug = isolate_->debug(); | 2654 Debug* debug = isolate_->debug(); |
| 2701 | 2655 |
| 2702 // Bail out based on state or if there is no listener for this event | 2656 // Bail out based on state or if there is no listener for this event |
| 2703 if (debug->InDebugger()) return; | 2657 if (debug->InDebugger()) return; |
| 2704 if (!Debugger::EventActive(v8::Exception)) return; | 2658 if (!Debugger::EventActive(v8::Exception)) return; |
| 2705 | 2659 |
| 2706 Handle<Object> promise = debug->GetPromiseForUncaughtException(); | |
| 2707 uncaught |= !promise->IsUndefined(); | |
| 2708 | |
| 2709 // Bail out if exception breaks are not active | 2660 // Bail out if exception breaks are not active |
| 2710 if (uncaught) { | 2661 if (uncaught) { |
| 2711 // Uncaught exceptions are reported by either flags. | 2662 // Uncaught exceptions are reported by either flags. |
| 2712 if (!(debug->break_on_uncaught_exception() || | 2663 if (!(debug->break_on_uncaught_exception() || |
| 2713 debug->break_on_exception())) return; | 2664 debug->break_on_exception())) return; |
| 2714 } else { | 2665 } else { |
| 2715 // Caught exceptions are reported is activated. | 2666 // Caught exceptions are reported is activated. |
| 2716 if (!debug->break_on_exception()) return; | 2667 if (!debug->break_on_exception()) return; |
| 2717 } | 2668 } |
| 2718 | 2669 |
| 2719 // Enter the debugger. | 2670 // Enter the debugger. |
| 2720 EnterDebugger debugger(isolate_); | 2671 EnterDebugger debugger(isolate_); |
| 2721 if (debugger.FailedToEnter()) return; | 2672 if (debugger.FailedToEnter()) return; |
| 2722 | 2673 |
| 2723 // Clear all current stepping setup. | 2674 // Clear all current stepping setup. |
| 2724 debug->ClearStepping(); | 2675 debug->ClearStepping(); |
| 2725 | 2676 |
| 2677 // Determine event; |
| 2678 DebugEvent event = promise->IsUndefined() |
| 2679 ? v8::Exception : v8::PendingExceptionInPromise; |
| 2680 |
| 2726 // Create the event data object. | 2681 // Create the event data object. |
| 2727 Handle<Object> event_data; | 2682 Handle<Object> event_data; |
| 2728 // Bail out and don't call debugger if exception. | 2683 // Bail out and don't call debugger if exception. |
| 2729 if (!MakeExceptionEvent( | 2684 if (!MakeExceptionEvent( |
| 2730 exception, uncaught, promise).ToHandle(&event_data)) { | 2685 exception, uncaught, promise).ToHandle(&event_data)) { |
| 2731 return; | 2686 return; |
| 2732 } | 2687 } |
| 2733 | 2688 |
| 2734 // Process debug event. | 2689 // Process debug event. |
| 2735 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); | 2690 ProcessDebugEvent(event, Handle<JSObject>::cast(event_data), false); |
| 2736 // Return to continue execution from where the exception was thrown. | 2691 // Return to continue execution from where the exception was thrown. |
| 2737 } | 2692 } |
| 2738 | 2693 |
| 2739 | 2694 |
| 2740 void Debugger::OnDebugBreak(Handle<Object> break_points_hit, | 2695 void Debugger::OnDebugBreak(Handle<Object> break_points_hit, |
| 2741 bool auto_continue) { | 2696 bool auto_continue) { |
| 2742 HandleScope scope(isolate_); | 2697 HandleScope scope(isolate_); |
| 2743 | 2698 |
| 2744 // Debugger has already been entered by caller. | 2699 // Debugger has already been entered by caller. |
| 2745 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); | 2700 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3207 // Send an empty command to the debugger if in a break to make JavaScript | 3162 // Send an empty command to the debugger if in a break to make JavaScript |
| 3208 // run again if the debugger is closed. | 3163 // run again if the debugger is closed. |
| 3209 if (isolate_->debug()->InDebugger()) { | 3164 if (isolate_->debug()->InDebugger()) { |
| 3210 ProcessCommand(Vector<const uint16_t>::empty()); | 3165 ProcessCommand(Vector<const uint16_t>::empty()); |
| 3211 } | 3166 } |
| 3212 } | 3167 } |
| 3213 } | 3168 } |
| 3214 | 3169 |
| 3215 | 3170 |
| 3216 void Debugger::ListenersChanged() { | 3171 void Debugger::ListenersChanged() { |
| 3217 bool active = IsDebuggerActive(); | 3172 if (IsDebuggerActive()) { |
| 3218 if (active) { | |
| 3219 // Disable the compilation cache when the debugger is active. | 3173 // Disable the compilation cache when the debugger is active. |
| 3220 isolate_->compilation_cache()->Disable(); | 3174 isolate_->compilation_cache()->Disable(); |
| 3221 debugger_unload_pending_ = false; | 3175 debugger_unload_pending_ = false; |
| 3222 } else { | 3176 } else { |
| 3223 isolate_->compilation_cache()->Enable(); | 3177 isolate_->compilation_cache()->Enable(); |
| 3224 // Unload the debugger if event listener and message handler cleared. | 3178 // Unload the debugger if event listener and message handler cleared. |
| 3225 // Schedule this for later, because we may be in non-V8 thread. | 3179 // Schedule this for later, because we may be in non-V8 thread. |
| 3226 debugger_unload_pending_ = true; | 3180 debugger_unload_pending_ = true; |
| 3227 } | 3181 } |
| 3228 } | 3182 } |
| (...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3773 already_signalled_ = false; | 3727 already_signalled_ = false; |
| 3774 } | 3728 } |
| 3775 { | 3729 { |
| 3776 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); | 3730 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); |
| 3777 isolate_->debugger()->CallMessageDispatchHandler(); | 3731 isolate_->debugger()->CallMessageDispatchHandler(); |
| 3778 } | 3732 } |
| 3779 } | 3733 } |
| 3780 } | 3734 } |
| 3781 | 3735 |
| 3782 } } // namespace v8::internal | 3736 } } // namespace v8::internal |
| OLD | NEW |