Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: src/debug.cc

Issue 260723002: Trigger exception debug event for promises at the throw site. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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),
40 debug_break_return_(NULL), 41 debug_break_return_(NULL),
41 debug_break_slot_(NULL), 42 debug_break_slot_(NULL),
42 isolate_(isolate) { 43 isolate_(isolate) {
43 memset(registers_, 0, sizeof(JSCallerSavedBuffer)); 44 memset(registers_, 0, sizeof(JSCallerSavedBuffer));
44 } 45 }
45 46
46 47
47 Debug::~Debug() { 48 Debug::~Debug() {
48 } 49 }
49 50
(...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 1311
1311 bool Debug::IsBreakOnException(ExceptionBreakType type) { 1312 bool Debug::IsBreakOnException(ExceptionBreakType type) {
1312 if (type == BreakUncaughtException) { 1313 if (type == BreakUncaughtException) {
1313 return break_on_uncaught_exception_; 1314 return break_on_uncaught_exception_;
1314 } else { 1315 } else {
1315 return break_on_exception_; 1316 return break_on_exception_;
1316 } 1317 }
1317 } 1318 }
1318 1319
1319 1320
1321 void Debug::PromiseHandlePrologue(Handle<JSFunction> promise_getter) {
1322 Handle<Object> current_promise_getter;
1323 if (current_promise_getter_.ToHandle(&current_promise_getter)) {
1324 isolate_->global_handles()->Destroy(current_promise_getter.location());
1325 }
1326 current_promise_getter_ = Handle<JSFunction>::cast(
1327 isolate_->global_handles()->Create(*promise_getter));
1328 current_promise_catch_handler_ =
1329 StackHandler::FromAddress(Isolate::handler(isolate_->thread_local_top()));
1330 }
1331
1332
1333 void Debug::PromiseHandleEpilogue() {
1334 current_promise_catch_handler_ = NULL;
rossberg 2014/04/30 12:55:17 Are we sure that PromiseHandle can never be reente
Yang 2014/04/30 13:20:14 I'm asserting now that the prologue always gets th
1335 Handle<Object> promise_getter;
1336 if (!current_promise_getter_.ToHandle(&promise_getter)) return;
1337 isolate_->global_handles()->Destroy(promise_getter.location());
1338 current_promise_getter_ = MaybeHandle<JSFunction>();
1339 }
1340
1341
1342 Handle<Object> Debug::GetPromiseForUncaughtException() {
1343 Handle<JSFunction> promise_getter;
1344 Handle<Object> undefined = isolate_->factory()->undefined_value();
1345 if (current_promise_getter_.ToHandle(&promise_getter)) {
1346 // Find the top-most try-catch handler.
1347 StackHandler* handler = StackHandler::FromAddress(
1348 Isolate::handler(isolate_->thread_local_top()));
1349 while (handler != NULL && !handler->is_catch()) {
1350 handler = handler->next();
1351 }
1352 #ifdef DEBUG
1353 // Make sure that our promise catch handler is in the list of handlers,
1354 // even if it's not the top-most try-catch handler.
1355 StackHandler* temp = handler;
1356 while (temp != current_promise_catch_handler_ && !temp->is_catch()) {
1357 temp = temp->next();
1358 CHECK(temp != NULL);
1359 }
1360 #endif // DEBUG
1361
1362 if (handler == current_promise_catch_handler_) {
1363 return Execution::Call(
1364 isolate_, promise_getter, undefined, 0, NULL).ToHandleChecked();
1365 }
1366 }
1367 return undefined;
1368 }
1369
1370
1320 void Debug::PrepareStep(StepAction step_action, 1371 void Debug::PrepareStep(StepAction step_action,
1321 int step_count, 1372 int step_count,
1322 StackFrame::Id frame_id) { 1373 StackFrame::Id frame_id) {
1323 HandleScope scope(isolate_); 1374 HandleScope scope(isolate_);
1324 1375
1325 PrepareForBreakPoints(); 1376 PrepareForBreakPoints();
1326 1377
1327 ASSERT(Debug::InDebugger()); 1378 ASSERT(Debug::InDebugger());
1328 1379
1329 // Remember this step action and count. 1380 // Remember this step action and count.
(...skipping 1303 matching lines...) Expand 10 before | Expand all | Expand 10 after
2633 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>(); 2684 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2634 // Create the script collected event object. 2685 // Create the script collected event object.
2635 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); 2686 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_);
2636 Handle<Object> argv[] = { exec_state, id_object }; 2687 Handle<Object> argv[] = { exec_state, id_object };
2637 2688
2638 return MakeJSObject( 2689 return MakeJSObject(
2639 CStrVector("MakeScriptCollectedEvent"), ARRAY_SIZE(argv), argv); 2690 CStrVector("MakeScriptCollectedEvent"), ARRAY_SIZE(argv), argv);
2640 } 2691 }
2641 2692
2642 2693
2643 void Debugger::OnException(Handle<Object> exception, 2694 void Debugger::OnException(Handle<Object> exception, bool uncaught) {
2644 bool uncaught,
2645 Handle<Object> promise) {
2646 HandleScope scope(isolate_); 2695 HandleScope scope(isolate_);
2647 Debug* debug = isolate_->debug(); 2696 Debug* debug = isolate_->debug();
2648 2697
2649 // Bail out based on state or if there is no listener for this event 2698 // Bail out based on state or if there is no listener for this event
2650 if (debug->InDebugger()) return; 2699 if (debug->InDebugger()) return;
2651 if (!Debugger::EventActive(v8::Exception)) return; 2700 if (!Debugger::EventActive(v8::Exception)) return;
2652 2701
2702 Handle<Object> promise = debug->GetPromiseForUncaughtException();
2703 uncaught |= !promise->IsUndefined();
2704
2653 // Bail out if exception breaks are not active 2705 // Bail out if exception breaks are not active
2654 if (uncaught) { 2706 if (uncaught) {
2655 // Uncaught exceptions are reported by either flags. 2707 // Uncaught exceptions are reported by either flags.
2656 if (!(debug->break_on_uncaught_exception() || 2708 if (!(debug->break_on_uncaught_exception() ||
2657 debug->break_on_exception())) return; 2709 debug->break_on_exception())) return;
2658 } else { 2710 } else {
2659 // Caught exceptions are reported is activated. 2711 // Caught exceptions are reported is activated.
2660 if (!debug->break_on_exception()) return; 2712 if (!debug->break_on_exception()) return;
2661 } 2713 }
2662 2714
2663 // Enter the debugger. 2715 // Enter the debugger.
2664 EnterDebugger debugger(isolate_); 2716 EnterDebugger debugger(isolate_);
2665 if (debugger.FailedToEnter()) return; 2717 if (debugger.FailedToEnter()) return;
2666 2718
2667 // Clear all current stepping setup. 2719 // Clear all current stepping setup.
2668 debug->ClearStepping(); 2720 debug->ClearStepping();
2669 2721
2670 // Determine event;
2671 DebugEvent event = promise->IsUndefined()
2672 ? v8::Exception : v8::PendingExceptionInPromise;
2673
2674 // Create the event data object. 2722 // Create the event data object.
2675 Handle<Object> event_data; 2723 Handle<Object> event_data;
2676 // Bail out and don't call debugger if exception. 2724 // Bail out and don't call debugger if exception.
2677 if (!MakeExceptionEvent( 2725 if (!MakeExceptionEvent(
2678 exception, uncaught, promise).ToHandle(&event_data)) { 2726 exception, uncaught, promise).ToHandle(&event_data)) {
2679 return; 2727 return;
2680 } 2728 }
2681 2729
2682 // Process debug event. 2730 // Process debug event.
2683 ProcessDebugEvent(event, Handle<JSObject>::cast(event_data), false); 2731 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
2684 // Return to continue execution from where the exception was thrown. 2732 // Return to continue execution from where the exception was thrown.
2685 } 2733 }
2686 2734
2687 2735
2688 void Debugger::OnDebugBreak(Handle<Object> break_points_hit, 2736 void Debugger::OnDebugBreak(Handle<Object> break_points_hit,
2689 bool auto_continue) { 2737 bool auto_continue) {
2690 HandleScope scope(isolate_); 2738 HandleScope scope(isolate_);
2691 2739
2692 // Debugger has already been entered by caller. 2740 // Debugger has already been entered by caller.
2693 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); 2741 ASSERT(isolate_->context() == *isolate_->debug()->debug_context());
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
3155 // Send an empty command to the debugger if in a break to make JavaScript 3203 // Send an empty command to the debugger if in a break to make JavaScript
3156 // run again if the debugger is closed. 3204 // run again if the debugger is closed.
3157 if (isolate_->debug()->InDebugger()) { 3205 if (isolate_->debug()->InDebugger()) {
3158 ProcessCommand(Vector<const uint16_t>::empty()); 3206 ProcessCommand(Vector<const uint16_t>::empty());
3159 } 3207 }
3160 } 3208 }
3161 } 3209 }
3162 3210
3163 3211
3164 void Debugger::ListenersChanged() { 3212 void Debugger::ListenersChanged() {
3165 if (IsDebuggerActive()) { 3213 bool active = IsDebuggerActive();
3214 if (active) {
3166 // Disable the compilation cache when the debugger is active. 3215 // Disable the compilation cache when the debugger is active.
3167 isolate_->compilation_cache()->Disable(); 3216 isolate_->compilation_cache()->Disable();
3168 debugger_unload_pending_ = false; 3217 debugger_unload_pending_ = false;
3169 } else { 3218 } else {
3170 isolate_->compilation_cache()->Enable(); 3219 isolate_->compilation_cache()->Enable();
3171 // Unload the debugger if event listener and message handler cleared. 3220 // Unload the debugger if event listener and message handler cleared.
3172 // Schedule this for later, because we may be in non-V8 thread. 3221 // Schedule this for later, because we may be in non-V8 thread.
3173 debugger_unload_pending_ = true; 3222 debugger_unload_pending_ = true;
3174 } 3223 }
3175 } 3224 }
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
3720 already_signalled_ = false; 3769 already_signalled_ = false;
3721 } 3770 }
3722 { 3771 {
3723 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); 3772 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_));
3724 isolate_->debugger()->CallMessageDispatchHandler(); 3773 isolate_->debugger()->CallMessageDispatchHandler();
3725 } 3774 }
3726 } 3775 }
3727 } 3776 }
3728 3777
3729 } } // namespace v8::internal 3778 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698