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

Side by Side Diff: src/debug.cc

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