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

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: comments addressed 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
« no previous file with comments | « src/debug.h ('k') | src/debug-debugger.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 ASSERT(current_promise_getter_.is_null());
1323 current_promise_getter_ = Handle<JSFunction>::cast(
1324 isolate_->global_handles()->Create(*promise_getter));
1325 current_promise_catch_handler_ =
1326 StackHandler::FromAddress(Isolate::handler(isolate_->thread_local_top()));
1327 }
1328
1329
1330 void Debug::PromiseHandleEpilogue() {
1331 current_promise_catch_handler_ = NULL;
aandrey 2014/04/30 13:58:26 maybe add ASSERT(!current_promise_getter_.is_null(
Yang 2014/04/30 14:14:58 would make sense, but some runtime fuzzing tests w
1332 Handle<Object> promise_getter;
1333 if (!current_promise_getter_.ToHandle(&promise_getter)) return;
1334 isolate_->global_handles()->Destroy(promise_getter.location());
1335 current_promise_getter_ = MaybeHandle<JSFunction>();
1336 }
1337
1338
1339 Handle<Object> Debug::GetPromiseForUncaughtException() {
1340 Handle<JSFunction> promise_getter;
1341 Handle<Object> undefined = isolate_->factory()->undefined_value();
1342 if (current_promise_getter_.ToHandle(&promise_getter)) {
1343 // Find the top-most try-catch handler.
1344 StackHandler* handler = StackHandler::FromAddress(
1345 Isolate::handler(isolate_->thread_local_top()));
1346 while (handler != NULL && !handler->is_catch()) {
1347 handler = handler->next();
1348 }
1349 #ifdef DEBUG
1350 // Make sure that our promise catch handler is in the list of handlers,
1351 // even if it's not the top-most try-catch handler.
1352 StackHandler* temp = handler;
1353 while (temp != current_promise_catch_handler_ && !temp->is_catch()) {
1354 temp = temp->next();
1355 CHECK(temp != NULL);
1356 }
1357 #endif // DEBUG
1358
1359 if (handler == current_promise_catch_handler_) {
1360 return Execution::Call(
1361 isolate_, promise_getter, undefined, 0, NULL).ToHandleChecked();
1362 }
1363 }
1364 return undefined;
1365 }
1366
1367
1320 void Debug::PrepareStep(StepAction step_action, 1368 void Debug::PrepareStep(StepAction step_action,
1321 int step_count, 1369 int step_count,
1322 StackFrame::Id frame_id) { 1370 StackFrame::Id frame_id) {
1323 HandleScope scope(isolate_); 1371 HandleScope scope(isolate_);
1324 1372
1325 PrepareForBreakPoints(); 1373 PrepareForBreakPoints();
1326 1374
1327 ASSERT(Debug::InDebugger()); 1375 ASSERT(Debug::InDebugger());
1328 1376
1329 // Remember this step action and count. 1377 // 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>(); 2681 if (!MakeExecutionState().ToHandle(&exec_state)) return MaybeHandle<Object>();
2634 // Create the script collected event object. 2682 // Create the script collected event object.
2635 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_); 2683 Handle<Object> id_object = Handle<Smi>(Smi::FromInt(id), isolate_);
2636 Handle<Object> argv[] = { exec_state, id_object }; 2684 Handle<Object> argv[] = { exec_state, id_object };
2637 2685
2638 return MakeJSObject( 2686 return MakeJSObject(
2639 CStrVector("MakeScriptCollectedEvent"), ARRAY_SIZE(argv), argv); 2687 CStrVector("MakeScriptCollectedEvent"), ARRAY_SIZE(argv), argv);
2640 } 2688 }
2641 2689
2642 2690
2643 void Debugger::OnException(Handle<Object> exception, 2691 void Debugger::OnException(Handle<Object> exception, bool uncaught) {
2644 bool uncaught,
2645 Handle<Object> promise) {
2646 HandleScope scope(isolate_); 2692 HandleScope scope(isolate_);
2647 Debug* debug = isolate_->debug(); 2693 Debug* debug = isolate_->debug();
2648 2694
2649 // Bail out based on state or if there is no listener for this event 2695 // Bail out based on state or if there is no listener for this event
2650 if (debug->InDebugger()) return; 2696 if (debug->InDebugger()) return;
2651 if (!Debugger::EventActive(v8::Exception)) return; 2697 if (!Debugger::EventActive(v8::Exception)) return;
2652 2698
2699 Handle<Object> promise = debug->GetPromiseForUncaughtException();
2700 uncaught |= !promise->IsUndefined();
2701
2653 // Bail out if exception breaks are not active 2702 // Bail out if exception breaks are not active
2654 if (uncaught) { 2703 if (uncaught) {
2655 // Uncaught exceptions are reported by either flags. 2704 // Uncaught exceptions are reported by either flags.
2656 if (!(debug->break_on_uncaught_exception() || 2705 if (!(debug->break_on_uncaught_exception() ||
2657 debug->break_on_exception())) return; 2706 debug->break_on_exception())) return;
2658 } else { 2707 } else {
2659 // Caught exceptions are reported is activated. 2708 // Caught exceptions are reported is activated.
2660 if (!debug->break_on_exception()) return; 2709 if (!debug->break_on_exception()) return;
2661 } 2710 }
2662 2711
2663 // Enter the debugger. 2712 // Enter the debugger.
2664 EnterDebugger debugger(isolate_); 2713 EnterDebugger debugger(isolate_);
2665 if (debugger.FailedToEnter()) return; 2714 if (debugger.FailedToEnter()) return;
2666 2715
2667 // Clear all current stepping setup. 2716 // Clear all current stepping setup.
2668 debug->ClearStepping(); 2717 debug->ClearStepping();
2669 2718
2670 // Determine event;
2671 DebugEvent event = promise->IsUndefined()
2672 ? v8::Exception : v8::PendingExceptionInPromise;
2673
2674 // Create the event data object. 2719 // Create the event data object.
2675 Handle<Object> event_data; 2720 Handle<Object> event_data;
2676 // Bail out and don't call debugger if exception. 2721 // Bail out and don't call debugger if exception.
2677 if (!MakeExceptionEvent( 2722 if (!MakeExceptionEvent(
2678 exception, uncaught, promise).ToHandle(&event_data)) { 2723 exception, uncaught, promise).ToHandle(&event_data)) {
2679 return; 2724 return;
2680 } 2725 }
2681 2726
2682 // Process debug event. 2727 // Process debug event.
2683 ProcessDebugEvent(event, Handle<JSObject>::cast(event_data), false); 2728 ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false);
2684 // Return to continue execution from where the exception was thrown. 2729 // Return to continue execution from where the exception was thrown.
2685 } 2730 }
2686 2731
2687 2732
2688 void Debugger::OnDebugBreak(Handle<Object> break_points_hit, 2733 void Debugger::OnDebugBreak(Handle<Object> break_points_hit,
2689 bool auto_continue) { 2734 bool auto_continue) {
2690 HandleScope scope(isolate_); 2735 HandleScope scope(isolate_);
2691 2736
2692 // Debugger has already been entered by caller. 2737 // Debugger has already been entered by caller.
2693 ASSERT(isolate_->context() == *isolate_->debug()->debug_context()); 2738 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 3200 // Send an empty command to the debugger if in a break to make JavaScript
3156 // run again if the debugger is closed. 3201 // run again if the debugger is closed.
3157 if (isolate_->debug()->InDebugger()) { 3202 if (isolate_->debug()->InDebugger()) {
3158 ProcessCommand(Vector<const uint16_t>::empty()); 3203 ProcessCommand(Vector<const uint16_t>::empty());
3159 } 3204 }
3160 } 3205 }
3161 } 3206 }
3162 3207
3163 3208
3164 void Debugger::ListenersChanged() { 3209 void Debugger::ListenersChanged() {
3165 if (IsDebuggerActive()) { 3210 bool active = IsDebuggerActive();
3211 if (active) {
3166 // Disable the compilation cache when the debugger is active. 3212 // Disable the compilation cache when the debugger is active.
3167 isolate_->compilation_cache()->Disable(); 3213 isolate_->compilation_cache()->Disable();
3168 debugger_unload_pending_ = false; 3214 debugger_unload_pending_ = false;
3169 } else { 3215 } else {
3170 isolate_->compilation_cache()->Enable(); 3216 isolate_->compilation_cache()->Enable();
3171 // Unload the debugger if event listener and message handler cleared. 3217 // Unload the debugger if event listener and message handler cleared.
3172 // Schedule this for later, because we may be in non-V8 thread. 3218 // Schedule this for later, because we may be in non-V8 thread.
3173 debugger_unload_pending_ = true; 3219 debugger_unload_pending_ = true;
3174 } 3220 }
3175 } 3221 }
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
3720 already_signalled_ = false; 3766 already_signalled_ = false;
3721 } 3767 }
3722 { 3768 {
3723 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_)); 3769 Locker locker(reinterpret_cast<v8::Isolate*>(isolate_));
3724 isolate_->debugger()->CallMessageDispatchHandler(); 3770 isolate_->debugger()->CallMessageDispatchHandler();
3725 } 3771 }
3726 } 3772 }
3727 } 3773 }
3728 3774
3729 } } // namespace v8::internal 3775 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/debug-debugger.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698