summaryrefslogtreecommitdiff
path: root/deps
diff options
context:
space:
mode:
authorMatt Loring <mattloring@google.com>2016-06-06 12:02:28 -0700
committerMichaƫl Zasso <targos@protonmail.com>2016-06-29 10:44:32 +0200
commitd894648450b3000f758097d91f619c285132ea80 (patch)
treeba906a359f6c2e323a83843001e93385087dc7c2 /deps
parentfbfe6c70e139d52db8377adbea4dfe6134a67370 (diff)
downloadandroid-node-v8-d894648450b3000f758097d91f619c285132ea80.tar.gz
android-node-v8-d894648450b3000f758097d91f619c285132ea80.tar.bz2
android-node-v8-d894648450b3000f758097d91f619c285132ea80.zip
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: https://github.com/ofrobots/node/pull/23 PR-URL: https://github.com/nodejs/node/pull/7016 Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps')
-rw-r--r--deps/v8/include/v8-debug.h6
-rw-r--r--deps/v8/src/debug/debug.cc27
-rw-r--r--deps/v8/src/debug/debug.h3
-rw-r--r--deps/v8/src/debug/debug.js37
-rw-r--r--deps/v8/src/js/promise.js6
-rw-r--r--deps/v8/src/runtime/runtime-debug.cc9
-rw-r--r--deps/v8/src/runtime/runtime.h1
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/events.js122
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/resolve-after-aborted-try-finally.js32
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/resolve-after-try-catch.js29
-rw-r--r--deps/v8/test/mjsunit/es6/debug-promises/rethrow-in-try-finally.js30
11 files changed, 299 insertions, 3 deletions
diff --git a/deps/v8/include/v8-debug.h b/deps/v8/include/v8-debug.h
index e41df29ad0..50314501e3 100644
--- a/deps/v8/include/v8-debug.h
+++ b/deps/v8/include/v8-debug.h
@@ -18,11 +18,13 @@ enum DebugEvent {
Exception = 2,
NewFunction = 3,
BeforeCompile = 4,
- AfterCompile = 5,
+ AfterCompile = 5,
CompileError = 6,
- AsyncTaskEvent = 7,
+ PromiseEvent = 7,
+ AsyncTaskEvent = 8,
};
+
class V8_EXPORT Debug {
public:
/**
diff --git a/deps/v8/src/debug/debug.cc b/deps/v8/src/debug/debug.cc
index 6e94012579..7c76742bb9 100644
--- a/deps/v8/src/debug/debug.cc
+++ b/deps/v8/src/debug/debug.cc
@@ -1708,6 +1708,13 @@ MaybeHandle<Object> Debug::MakeCompileEvent(Handle<Script> script,
}
+MaybeHandle<Object> Debug::MakePromiseEvent(Handle<JSObject> event_data) {
+ // Create the promise event object.
+ Handle<Object> argv[] = { event_data };
+ return CallFunction("MakePromiseEvent", arraysize(argv), argv);
+}
+
+
MaybeHandle<Object> Debug::MakeAsyncTaskEvent(Handle<JSObject> task_event) {
// Create the async task event object.
Handle<Object> argv[] = { task_event };
@@ -1838,6 +1845,25 @@ void Debug::OnAfterCompile(Handle<Script> script) {
}
+void Debug::OnPromiseEvent(Handle<JSObject> data) {
+ if (in_debug_scope() || ignore_events()) return;
+
+ HandleScope scope(isolate_);
+ DebugScope debug_scope(this);
+ if (debug_scope.failed()) return;
+
+ // Create the script collected state object.
+ Handle<Object> event_data;
+ // Bail out and don't call debugger if exception.
+ if (!MakePromiseEvent(data).ToHandle(&event_data)) return;
+
+ // Process debug event.
+ ProcessDebugEvent(v8::PromiseEvent,
+ Handle<JSObject>::cast(event_data),
+ true);
+}
+
+
void Debug::OnAsyncTaskEvent(Handle<JSObject> data) {
if (in_debug_scope() || ignore_events()) return;
@@ -1987,6 +2013,7 @@ void Debug::NotifyMessageHandler(v8::DebugEvent event,
case v8::NewFunction:
case v8::BeforeCompile:
case v8::CompileError:
+ case v8::PromiseEvent:
case v8::AsyncTaskEvent:
break;
case v8::Exception:
diff --git a/deps/v8/src/debug/debug.h b/deps/v8/src/debug/debug.h
index 501de63181..35aa8db049 100644
--- a/deps/v8/src/debug/debug.h
+++ b/deps/v8/src/debug/debug.h
@@ -417,6 +417,7 @@ class Debug {
void OnCompileError(Handle<Script> script);
void OnBeforeCompile(Handle<Script> script);
void OnAfterCompile(Handle<Script> script);
+ void OnPromiseEvent(Handle<JSObject> data);
void OnAsyncTaskEvent(Handle<JSObject> data);
// API facing.
@@ -579,6 +580,8 @@ class Debug {
Handle<Object> promise);
MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
Handle<Script> script, v8::DebugEvent type);
+ MUST_USE_RESULT MaybeHandle<Object> MakePromiseEvent(
+ Handle<JSObject> promise_event);
MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(
Handle<JSObject> task_event);
diff --git a/deps/v8/src/debug/debug.js b/deps/v8/src/debug/debug.js
index 7f06ca1be1..6849bf5345 100644
--- a/deps/v8/src/debug/debug.js
+++ b/deps/v8/src/debug/debug.js
@@ -51,7 +51,8 @@ Debug.DebugEvent = { Break: 1,
BeforeCompile: 4,
AfterCompile: 5,
CompileError: 6,
- AsyncTaskEvent: 7 };
+ PromiseEvent: 7,
+ AsyncTaskEvent: 8 };
// Types of exceptions that can be broken upon.
Debug.ExceptionBreak = { Caught : 0,
@@ -1140,6 +1141,39 @@ function MakeScriptObject_(script, include_source) {
}
+function MakePromiseEvent(event_data) {
+ return new PromiseEvent(event_data);
+}
+
+
+function PromiseEvent(event_data) {
+ this.promise_ = event_data.promise;
+ this.parentPromise_ = event_data.parentPromise;
+ this.status_ = event_data.status;
+ this.value_ = event_data.value;
+}
+
+
+PromiseEvent.prototype.promise = function() {
+ return MakeMirror(this.promise_);
+}
+
+
+PromiseEvent.prototype.parentPromise = function() {
+ return MakeMirror(this.parentPromise_);
+}
+
+
+PromiseEvent.prototype.status = function() {
+ return this.status_;
+}
+
+
+PromiseEvent.prototype.value = function() {
+ return MakeMirror(this.value_);
+}
+
+
function MakeAsyncTaskEvent(event_data) {
return new AsyncTaskEvent(event_data);
}
@@ -2483,6 +2517,7 @@ utils.InstallFunctions(utils, DONT_ENUM, [
"MakeExceptionEvent", MakeExceptionEvent,
"MakeBreakEvent", MakeBreakEvent,
"MakeCompileEvent", MakeCompileEvent,
+ "MakePromiseEvent", MakePromiseEvent,
"MakeAsyncTaskEvent", MakeAsyncTaskEvent,
"IsBreakPointTriggered", IsBreakPointTriggered,
"UpdateScriptBreakPoints", UpdateScriptBreakPoints,
diff --git a/deps/v8/src/js/promise.js b/deps/v8/src/js/promise.js
index bcf826a101..201a06ca08 100644
--- a/deps/v8/src/js/promise.js
+++ b/deps/v8/src/js/promise.js
@@ -89,6 +89,9 @@ function PromiseSet(promise, status, value, onResolve, onReject) {
SET_PRIVATE(promise, promiseValueSymbol, value);
SET_PRIVATE(promise, promiseOnResolveSymbol, onResolve);
SET_PRIVATE(promise, promiseOnRejectSymbol, onReject);
+ if (DEBUG_IS_ACTIVE) {
+ %DebugPromiseEvent({ promise: promise, status: status, value: value });
+ }
return promise;
}
@@ -303,6 +306,9 @@ function PromiseThen(onResolve, onReject) {
}
// Mark this promise as having handler.
SET_PRIVATE(this, promiseHasHandlerSymbol, true);
+ if (DEBUG_IS_ACTIVE) {
+ %DebugPromiseEvent({ promise: deferred.promise, parentPromise: this });
+ }
return deferred.promise;
}
diff --git a/deps/v8/src/runtime/runtime-debug.cc b/deps/v8/src/runtime/runtime-debug.cc
index ad8375a8d4..3263a89809 100644
--- a/deps/v8/src/runtime/runtime-debug.cc
+++ b/deps/v8/src/runtime/runtime-debug.cc
@@ -1635,6 +1635,15 @@ RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
}
+RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
+ DCHECK(args.length() == 1);
+ HandleScope scope(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
+ isolate->debug()->OnPromiseEvent(data);
+ return isolate->heap()->undefined_value();
+}
+
+
RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
DCHECK(args.length() == 1);
HandleScope scope(isolate);
diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h
index dc1678bb73..704145462b 100644
--- a/deps/v8/src/runtime/runtime.h
+++ b/deps/v8/src/runtime/runtime.h
@@ -190,6 +190,7 @@ namespace internal {
F(DebugPrepareStepInIfStepping, 1, 1) \
F(DebugPushPromise, 2, 1) \
F(DebugPopPromise, 0, 1) \
+ F(DebugPromiseEvent, 1, 1) \
F(DebugAsyncTaskEvent, 1, 1) \
F(DebugIsActive, 0, 1) \
F(DebugBreakInOptimizedCode, 0, 1)
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/events.js b/deps/v8/test/mjsunit/es6/debug-promises/events.js
new file mode 100644
index 0000000000..3fcb22ff27
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/events.js
@@ -0,0 +1,122 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --expose-debug-as debug
+
+Debug = debug.Debug;
+
+var eventsExpected = 16;
+var exception = null;
+var result = [];
+
+function updatePromise(promise, parentPromise, status, value) {
+ var i;
+ for (i = 0; i < result.length; ++i) {
+ if (result[i].promise === promise) {
+ result[i].parentPromise = parentPromise || result[i].parentPromise;
+ result[i].status = status || result[i].status;
+ result[i].value = value || result[i].value;
+ break;
+ }
+ }
+ assertTrue(i < result.length);
+}
+
+function listener(event, exec_state, event_data, data) {
+ if (event != Debug.DebugEvent.PromiseEvent) return;
+ try {
+ eventsExpected--;
+ assertTrue(event_data.promise().isPromise());
+ if (event_data.status() === 0) {
+ // New promise.
+ assertEquals("pending", event_data.promise().status());
+ result.push({ promise: event_data.promise().value(), status: 0 });
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
+ } else if (event_data.status() !== undefined) {
+ // Resolve/reject promise.
+ updatePromise(event_data.promise().value(),
+ undefined,
+ event_data.status(),
+ event_data.value().value());
+ } else {
+ // Chain promises.
+ assertTrue(event_data.parentPromise().isPromise());
+ updatePromise(event_data.promise().value(),
+ event_data.parentPromise().value());
+ assertTrue(exec_state.frame(0).sourceLineText().indexOf("// event") > 0);
+ }
+ } catch (e) {
+ print(e + e.stack)
+ exception = e;
+ }
+}
+
+Debug.setListener(listener);
+
+function resolver(resolve, reject) { resolve(); }
+
+var p1 = new Promise(resolver); // event
+var p2 = p1.then().then(); // event
+var p3 = new Promise(function(resolve, reject) { // event
+ reject("rejected");
+});
+var p4 = p3.then(); // event
+var p5 = p1.then(); // event
+
+function assertAsync(b, s) {
+ if (b) {
+ print(s, "succeeded");
+ } else {
+ %AbortJS(s + " FAILED!");
+ }
+}
+
+function testDone(iteration) {
+ function checkResult() {
+ if (eventsExpected === 0) {
+ assertAsync(result.length === 6, "result.length");
+
+ assertAsync(result[0].promise === p1, "result[0].promise");
+ assertAsync(result[0].parentPromise === undefined,
+ "result[0].parentPromise");
+ assertAsync(result[0].status === 1, "result[0].status");
+ assertAsync(result[0].value === undefined, "result[0].value");
+
+ assertAsync(result[1].parentPromise === p1,
+ "result[1].parentPromise");
+ assertAsync(result[1].status === 1, "result[1].status");
+
+ assertAsync(result[2].promise === p2, "result[2].promise");
+
+ assertAsync(result[3].promise === p3, "result[3].promise");
+ assertAsync(result[3].parentPromise === undefined,
+ "result[3].parentPromise");
+ assertAsync(result[3].status === -1, "result[3].status");
+ assertAsync(result[3].value === "rejected", "result[3].value");
+
+ assertAsync(result[4].promise === p4, "result[4].promise");
+ assertAsync(result[4].parentPromise === p3,
+ "result[4].parentPromise");
+ assertAsync(result[4].status === -1, "result[4].status");
+ assertAsync(result[4].value === "rejected", "result[4].value");
+
+ assertAsync(result[5].promise === p5, "result[5].promise");
+ assertAsync(result[5].parentPromise === p1,
+ "result[5].parentPromise");
+ assertAsync(result[5].status === 1, "result[5].status");
+
+ assertAsync(exception === null, "exception === null");
+ Debug.setListener(null);
+ } else if (iteration > 10) {
+ %AbortJS("Not all events were received!");
+ } else {
+ testDone(iteration + 1);
+ }
+ }
+
+ var iteration = iteration || 0;
+ %EnqueueMicrotask(checkResult);
+}
+
+testDone();
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/resolve-after-aborted-try-finally.js b/deps/v8/test/mjsunit/es6/debug-promises/resolve-after-aborted-try-finally.js
new file mode 100644
index 0000000000..918ae2a2e8
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/resolve-after-aborted-try-finally.js
@@ -0,0 +1,32 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we listen to all exceptions and
+// there is a catch handler for the exception thrown in a Promise.
+// We expect a normal Exception debug event to be triggered.
+
+Debug = debug.Debug;
+
+var events = [];
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.PromiseEvent) events.push(event_data.status());
+}
+
+Debug.setListener(listener);
+
+var p = new Promise(function(resolve, reject) {
+ do {
+ try {
+ throw new Error("reject");
+ } finally {
+ break; // No rethrow.
+ }
+ } while (false);
+ resolve();
+});
+
+assertEquals([0 /* create */, 1 /* resolve */], events);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/resolve-after-try-catch.js b/deps/v8/test/mjsunit/es6/debug-promises/resolve-after-try-catch.js
new file mode 100644
index 0000000000..298201f103
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/resolve-after-try-catch.js
@@ -0,0 +1,29 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we listen to all exceptions and
+// there is a catch handler for the exception thrown in a Promise.
+// We expect a normal Exception debug event to be triggered.
+
+Debug = debug.Debug;
+
+var events = [];
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.PromiseEvent) events.push(event_data.status());
+}
+
+Debug.setListener(listener);
+
+var p = new Promise(function (resolve, reject) {
+ try {
+ throw new Error("reject");
+ } catch (e) {
+ }
+ resolve();
+});
+
+assertEquals([0 /* create */, 1 /* resolve */], events);
diff --git a/deps/v8/test/mjsunit/es6/debug-promises/rethrow-in-try-finally.js b/deps/v8/test/mjsunit/es6/debug-promises/rethrow-in-try-finally.js
new file mode 100644
index 0000000000..b1e2ff98e1
--- /dev/null
+++ b/deps/v8/test/mjsunit/es6/debug-promises/rethrow-in-try-finally.js
@@ -0,0 +1,30 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --allow-natives-syntax
+
+// Test debug events when we listen to all exceptions and
+// there is a catch handler for the exception thrown in a Promise.
+// We expect a normal Exception debug event to be triggered.
+
+Debug = debug.Debug;
+
+var events = [];
+
+function listener(event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.PromiseEvent) events.push(event_data.status());
+}
+
+Debug.setListener(listener);
+
+var p = new Promise(function(resolve, reject) {
+ try {
+ throw new Error("reject");
+ } finally {
+ // Implicit rethrow.
+ }
+ resolve();
+});
+
+assertEquals([0 /* create */, -1 /* rethrown */], events);