Skip to content

Commit 06a6c03

Browse files
Matt Loringofrobots
Matt Loring
authored andcommitted
deps: revert removal of V8::PromiseEvent
The removal of the promise debug event is an API/ABI breaking change. Ref: https://codereview.chromium.org/1833563002 Ref: ofrobots#23 PR-URL: #7016 Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
1 parent dcd0655 commit 06a6c03

File tree

11 files changed

+299
-3
lines changed

11 files changed

+299
-3
lines changed

deps/v8/include/v8-debug.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ enum DebugEvent {
1818
Exception = 2,
1919
NewFunction = 3,
2020
BeforeCompile = 4,
21-
AfterCompile = 5,
21+
AfterCompile = 5,
2222
CompileError = 6,
23-
AsyncTaskEvent = 7,
23+
PromiseEvent = 7,
24+
AsyncTaskEvent = 8,
2425
};
2526

27+
2628
class V8_EXPORT Debug {
2729
public:
2830
/**

deps/v8/src/debug/debug.cc

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1708,6 +1708,13 @@ MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
17081708
}
17091709

17101710

1711+
MaybeHandle<Object> Debug::MakePromiseEvent(Handle<JSObject> event_data) {
1712+
// Create the promise event object.
1713+
Handle<Object> argv[] = { event_data };
1714+
return CallFunction("MakePromiseEvent", arraysize(argv), argv);
1715+
}
1716+
1717+
17111718
MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<JSObject> task_event) {
17121719
// Create the async task event object.
17131720
Handle<Object> argv[] = { task_event };
@@ -1838,6 +1845,25 @@ void Debug::OnAfterCompile(Handle<Script> script) {
18381845
}
18391846

18401847

1848+
void Debug::OnPromiseEvent(Handle<JSObject> data) {
1849+
if (in_debug_scope() || ignore_events()) return;
1850+
1851+
HandleScope scope(isolate_);
1852+
DebugScope debug_scope(this);
1853+
if (debug_scope.failed()) return;
1854+
1855+
// Create the script collected state object.
1856+
Handle<Object> event_data;
1857+
// Bail out and don't call debugger if exception.
1858+
if (!MakePromiseEvent(data).ToHandle(&event_data)) return;
1859+
1860+
// Process debug event.
1861+
ProcessDebugEvent(v8::PromiseEvent,
1862+
Handle<JSObject>::cast(event_data),
1863+
true);
1864+
}
1865+
1866+
18411867
void Debug::OnAsyncTaskEvent(Handle<JSObject> data) {
18421868
if (in_debug_scope() || ignore_events()) return;
18431869

@@ -1987,6 +2013,7 @@ void Debug::NotifyMessageHandler(v8::DebugEvent event,
19872013
case v8::NewFunction:
19882014
case v8::BeforeCompile:
19892015
case v8::CompileError:
2016+
case v8::PromiseEvent:
19902017
case v8::AsyncTaskEvent:
19912018
break;
19922019
case v8::Exception:

deps/v8/src/debug/debug.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ class Debug {
417417
void OnCompileError(Handle<Script> script);
418418
void OnBeforeCompile(Handle<Script> script);
419419
void OnAfterCompile(Handle<Script> script);
420+
void OnPromiseEvent(Handle<JSObject> data);
420421
void OnAsyncTaskEvent(Handle<JSObject> data);
421422

422423
// API facing.
@@ -579,6 +580,8 @@ class Debug {
579580
Handle<Object> promise);
580581
MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
581582
Handle<Script> script, v8::DebugEvent type);
583+
MUST_USE_RESULT MaybeHandle<Object> MakePromiseEvent(
584+
Handle<JSObject> promise_event);
582585
MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(
583586
Handle<JSObject> task_event);
584587

deps/v8/src/debug/debug.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ Debug.DebugEvent = { Break: 1,
5151
BeforeCompile: 4,
5252
AfterCompile: 5,
5353
CompileError: 6,
54-
AsyncTaskEvent: 7 };
54+
PromiseEvent: 7,
55+
AsyncTaskEvent: 8 };
5556

5657
// Types of exceptions that can be broken upon.
5758
Debug.ExceptionBreak = { Caught : 0,
@@ -1140,6 +1141,39 @@ function MakeScriptObject_(script, include_source) {
11401141
}
11411142

11421143

1144+
function MakePromiseEvent(event_data) {
1145+
return new PromiseEvent(event_data);
1146+
}
1147+
1148+
1149+
function PromiseEvent(event_data) {
1150+
this.promise_ = event_data.promise;
1151+
this.parentPromise_ = event_data.parentPromise;
1152+
this.status_ = event_data.status;
1153+
this.value_ = event_data.value;
1154+
}
1155+
1156+
1157+
PromiseEvent.prototype.promise = function() {
1158+
return MakeMirror(this.promise_);
1159+
}
1160+
1161+
1162+
PromiseEvent.prototype.parentPromise = function() {
1163+
return MakeMirror(this.parentPromise_);
1164+
}
1165+
1166+
1167+
PromiseEvent.prototype.status = function() {
1168+
return this.status_;
1169+
}
1170+
1171+
1172+
PromiseEvent.prototype.value = function() {
1173+
return MakeMirror(this.value_);
1174+
}
1175+
1176+
11431177
function MakeAsyncTaskEvent(event_data) {
11441178
return new AsyncTaskEvent(event_data);
11451179
}
@@ -2483,6 +2517,7 @@ utils.InstallFunctions(utils, DONT_ENUM, [
24832517
"MakeExceptionEvent", MakeExceptionEvent,
24842518
"MakeBreakEvent", MakeBreakEvent,
24852519
"MakeCompileEvent", MakeCompileEvent,
2520+
"MakePromiseEvent", MakePromiseEvent,
24862521
"MakeAsyncTaskEvent", MakeAsyncTaskEvent,
24872522
"IsBreakPointTriggered", IsBreakPointTriggered,
24882523
"UpdateScriptBreakPoints", UpdateScriptBreakPoints,

deps/v8/src/js/promise.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ function PromiseSet(promise, status, value, onResolve, onReject) {
8989
SET_PRIVATE(promise, promiseValueSymbol, value);
9090
SET_PRIVATE(promise, promiseOnResolveSymbol, onResolve);
9191
SET_PRIVATE(promise, promiseOnRejectSymbol, onReject);
92+
if (DEBUG_IS_ACTIVE) {
93+
%DebugPromiseEvent({ promise: promise, status: status, value: value });
94+
}
9295
return promise;
9396
}
9497

@@ -303,6 +306,9 @@ function PromiseThen(onResolve, onReject) {
303306
}
304307
// Mark this promise as having handler.
305308
SET_PRIVATE(this, promiseHasHandlerSymbol, true);
309+
if (DEBUG_IS_ACTIVE) {
310+
%DebugPromiseEvent({ promise: deferred.promise, parentPromise: this });
311+
}
306312
return deferred.promise;
307313
}
308314

deps/v8/src/runtime/runtime-debug.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1635,6 +1635,15 @@ RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
16351635
}
16361636

16371637

1638+
RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
1639+
DCHECK(args.length() == 1);
1640+
HandleScope scope(isolate);
1641+
CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
1642+
isolate->debug()->OnPromiseEvent(data);
1643+
return isolate->heap()->undefined_value();
1644+
}
1645+
1646+
16381647
RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
16391648
DCHECK(args.length() == 1);
16401649
HandleScope scope(isolate);

deps/v8/src/runtime/runtime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ namespace internal {
190190
F(DebugPrepareStepInIfStepping, 1, 1) \
191191
F(DebugPushPromise, 2, 1) \
192192
F(DebugPopPromise, 0, 1) \
193+
F(DebugPromiseEvent, 1, 1) \
193194
F(DebugAsyncTaskEvent, 1, 1) \
194195
F(DebugIsActive, 0, 1) \
195196
F(DebugBreakInOptimizedCode, 0, 1)
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Copyright 2014 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flags: --allow-natives-syntax --expose-debug-as debug
6+
7+
Debug = debug.Debug;
8+
9+
var eventsExpected = 16;
10+
var exception = null;
11+
var result = [];
12+
13+
function updatePromise(promise, parentPromise, status, value) {
14+
var i;
15+
for (i = 0; i < result.length; ++i) {
16+
if (result[i].promise === promise) {
17+
result[i].parentPromise = parentPromise || result[i].parentPromise;
18+
result[i].status = status || result[i].status;
19+
result[i].value = value || result[i].value;
20+
break;
21+
}
22+
}
23+
assertTrue(i < result.length);
24+
}
25+
26+
function listener(event, exec_state, event_data, data) {
27+
if (event != Debug.DebugEvent.PromiseEvent) return;
28+
try {
29+
eventsExpected--;
30+
assertTrue(event_data.promise().isPromise());
31+
if (event_data.status() === 0) {
32+
// New promise.
33+
assertEquals("pending", event_data.promise().status());
34+
result.push({ promise: event_data.promise().value(), status: 0 });
35+
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
36+
} else if (event_data.status() !== undefined) {
37+
// Resolve/reject promise.
38+
updatePromise(event_data.promise().value(),
39+
undefined,
40+
event_data.status(),
41+
event_data.value().value());
42+
} else {
43+
// Chain promises.
44+
assertTrue(event_data.parentPromise().isPromise());
45+
updatePromise(event_data.promise().value(),
46+
event_data.parentPromise().value());
47+
assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
48+
}
49+
} catch (e) {
50+
print(e + e.stack)
51+
exception = e;
52+
}
53+
}
54+
55+
Debug.setListener(listener);
56+
57+
function resolver(resolve, reject) { resolve(); }
58+
59+
var p1 = new Promise(resolver); // event
60+
var p2 = p1.then().then(); // event
61+
var p3 = new Promise(function(resolve, reject) { // event
62+
reject("rejected");
63+
});
64+
var p4 = p3.then(); // event
65+
var p5 = p1.then(); // event
66+
67+
function assertAsync(b, s) {
68+
if (b) {
69+
print(s, "succeeded");
70+
} else {
71+
%AbortJS(s + " FAILED!");
72+
}
73+
}
74+
75+
function testDone(iteration) {
76+
function checkResult() {
77+
if (eventsExpected === 0) {
78+
assertAsync(result.length === 6, "result.length");
79+
80+
assertAsync(result[0].promise === p1, "result[0].promise");
81+
assertAsync(result[0].parentPromise === undefined,
82+
"result[0].parentPromise");
83+
assertAsync(result[0].status === 1, "result[0].status");
84+
assertAsync(result[0].value === undefined, "result[0].value");
85+
86+
assertAsync(result[1].parentPromise === p1,
87+
"result[1].parentPromise");
88+
assertAsync(result[1].status === 1, "result[1].status");
89+
90+
assertAsync(result[2].promise === p2, "result[2].promise");
91+
92+
assertAsync(result[3].promise === p3, "result[3].promise");
93+
assertAsync(result[3].parentPromise === undefined,
94+
"result[3].parentPromise");
95+
assertAsync(result[3].status === -1, "result[3].status");
96+
assertAsync(result[3].value === "rejected", "result[3].value");
97+
98+
assertAsync(result[4].promise === p4, "result[4].promise");
99+
assertAsync(result[4].parentPromise === p3,
100+
"result[4].parentPromise");
101+
assertAsync(result[4].status === -1, "result[4].status");
102+
assertAsync(result[4].value === "rejected", "result[4].value");
103+
104+
assertAsync(result[5].promise === p5, "result[5].promise");
105+
assertAsync(result[5].parentPromise === p1,
106+
"result[5].parentPromise");
107+
assertAsync(result[5].status === 1, "result[5].status");
108+
109+
assertAsync(exception === null, "exception === null");
110+
Debug.setListener(null);
111+
} else if (iteration > 10) {
112+
%AbortJS("Not all events were received!");
113+
} else {
114+
testDone(iteration + 1);
115+
}
116+
}
117+
118+
var iteration = iteration || 0;
119+
%EnqueueMicrotask(checkResult);
120+
}
121+
122+
testDone();
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2014 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flags: --expose-debug-as debug --allow-natives-syntax
6+
7+
// Test debug events when we listen to all exceptions and
8+
// there is a catch handler for the exception thrown in a Promise.
9+
// We expect a normal Exception debug event to be triggered.
10+
11+
Debug = debug.Debug;
12+
13+
var events = [];
14+
15+
function listener(event, exec_state, event_data, data) {
16+
if (event == Debug.DebugEvent.PromiseEvent) events.push(event_data.status());
17+
}
18+
19+
Debug.setListener(listener);
20+
21+
var p = new Promise(function(resolve, reject) {
22+
do {
23+
try {
24+
throw new Error("reject");
25+
} finally {
26+
break; // No rethrow.
27+
}
28+
} while (false);
29+
resolve();
30+
});
31+
32+
assertEquals([0 /* create */, 1 /* resolve */], events);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2014 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flags: --expose-debug-as debug --allow-natives-syntax
6+
7+
// Test debug events when we listen to all exceptions and
8+
// there is a catch handler for the exception thrown in a Promise.
9+
// We expect a normal Exception debug event to be triggered.
10+
11+
Debug = debug.Debug;
12+
13+
var events = [];
14+
15+
function listener(event, exec_state, event_data, data) {
16+
if (event == Debug.DebugEvent.PromiseEvent) events.push(event_data.status());
17+
}
18+
19+
Debug.setListener(listener);
20+
21+
var p = new Promise(function (resolve, reject) {
22+
try {
23+
throw new Error("reject");
24+
} catch (e) {
25+
}
26+
resolve();
27+
});
28+
29+
assertEquals([0 /* create */, 1 /* resolve */], events);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2014 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Flags: --expose-debug-as debug --allow-natives-syntax
6+
7+
// Test debug events when we listen to all exceptions and
8+
// there is a catch handler for the exception thrown in a Promise.
9+
// We expect a normal Exception debug event to be triggered.
10+
11+
Debug = debug.Debug;
12+
13+
var events = [];
14+
15+
function listener(event, exec_state, event_data, data) {
16+
if (event == Debug.DebugEvent.PromiseEvent) events.push(event_data.status());
17+
}
18+
19+
Debug.setListener(listener);
20+
21+
var p = new Promise(function(resolve, reject) {
22+
try {
23+
throw new Error("reject");
24+
} finally {
25+
// Implicit rethrow.
26+
}
27+
resolve();
28+
});
29+
30+
assertEquals([0 /* create */, -1 /* rethrown */], events);

0 commit comments

Comments
 (0)