Reviewers: rossberg,
Description:
Add v8::Promise::Then.
Blink needs v8::Promise::Then to implement ScriptPromise::then.
Blink-side CL: https://codereview.chromium.org/316453002
BUG=371288
LOG=Y
Please review this at https://codereview.chromium.org/314553002/
SVN Base: https://chromium.googlesource.com/external/v8.git@master
Affected files (+92, -1 lines):
M include/v8.h
M src/api.cc
M src/bootstrapper.cc
M src/contexts.h
M src/promise.js
M test/cctest/test-api.cc
Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index
7af4322b08a7ded0a760bbb3aeb2ab96420a5231..df27f71d194b90bd5fe878e996c0157734cb7fa6
100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -2634,6 +2634,7 @@ class V8_EXPORT Promise : public Object {
*/
Local<Promise> Chain(Handle<Function> handler);
Local<Promise> Catch(Handle<Function> handler);
+ Local<Promise> Then(Handle<Function> handler);
V8_INLINE static Promise* Cast(Value* obj);
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index
ca552fc60f6ba44140461666f730411a92de0fe4..b12534f91f55e2c92bd0af1da898f7440c93a0d6
100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -5910,6 +5910,26 @@ Local<Promise> Promise::Catch(Handle<Function>
handler) {
}
+Local<Promise> Promise::Then(Handle<Function> handler) {
+ i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
+ i::Isolate* isolate = promise->GetIsolate();
+ LOG_API(isolate, "Promise::Then");
+ ENTER_V8(isolate);
+ EXCEPTION_PREAMBLE(isolate);
+ i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
+ i::Handle<i::Object> result;
+ has_pending_exception = !i::Execution::Call(
+ isolate,
+ handle(isolate->context()->global_object()->native_context()->
+ promise_then()),
+ promise,
+ ARRAY_SIZE(argv), argv,
+ false).ToHandle(&result);
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
+ return Local<Promise>::Cast(Utils::ToLocal(result));
+}
+
+
bool v8::ArrayBuffer::IsExternal() const {
return Utils::OpenHandle(this)->is_external();
}
Index: src/bootstrapper.cc
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index
2f27b05a7b3999863e5a849474b18f734acd1806..19d03fbecade836100d584183fb9a7cae4098189
100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1587,6 +1587,7 @@ void Genesis::InstallNativeFunctions() {
INSTALL_NATIVE(JSFunction, "PromiseReject", promise_reject);
INSTALL_NATIVE(JSFunction, "PromiseChain", promise_chain);
INSTALL_NATIVE(JSFunction, "PromiseCatch", promise_catch);
+ INSTALL_NATIVE(JSFunction, "PromiseThen", promise_then);
INSTALL_NATIVE(JSFunction, "NotifyChange", observers_notify_change);
INSTALL_NATIVE(JSFunction, "EnqueueSpliceRecord",
observers_enqueue_splice);
Index: src/contexts.h
diff --git a/src/contexts.h b/src/contexts.h
index
2c173e1aec451823a1d567375d942ada66f1ba26..ef26e6648e094b9f5b0c429a675c27fda3208e45
100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -162,6 +162,7 @@ enum BindingFlags {
V(PROMISE_REJECT_INDEX, JSFunction, promise_reject) \
V(PROMISE_CHAIN_INDEX, JSFunction, promise_chain) \
V(PROMISE_CATCH_INDEX, JSFunction, promise_catch) \
+ V(PROMISE_THEN_INDEX, JSFunction, promise_then) \
V(TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX, JSFunction, \
to_complete_property_descriptor) \
V(DERIVED_HAS_TRAP_INDEX, JSFunction, derived_has_trap) \
@@ -340,6 +341,7 @@ class Context: public FixedArray {
PROMISE_REJECT_INDEX,
PROMISE_CHAIN_INDEX,
PROMISE_CATCH_INDEX,
+ PROMISE_THEN_INDEX,
TO_COMPLETE_PROPERTY_DESCRIPTOR_INDEX,
DERIVED_HAS_TRAP_INDEX,
DERIVED_GET_TRAP_INDEX,
Index: src/promise.js
diff --git a/src/promise.js b/src/promise.js
index
f7d6307f8be487b0e9c7fd06ae1dd8ae8c2f29f5..710abadbeb8a0517c5e49dde9646b29361d3d843
100644
--- a/src/promise.js
+++ b/src/promise.js
@@ -17,6 +17,7 @@ var PromiseResolve;
var PromiseReject;
var PromiseChain;
var PromiseCatch;
+var PromiseThen;
// mirror-debugger.js currently uses builtins.promiseStatus. It would be
nice
// if we could move these property names into the closure below.
@@ -220,7 +221,7 @@ var promiseRaw = GLOBAL_PRIVATE("Promise#raw");
// Multi-unwrapped chaining with thenable coercion.
- function PromiseThen(onResolve, onReject) {
+ PromiseThen = function PromiseThen(onResolve, onReject) {
onResolve = IS_SPEC_FUNCTION(onResolve) ? onResolve
: PromiseIdResolveHandler;
onReject = IS_SPEC_FUNCTION(onReject) ? onReject
Index: test/cctest/test-api.cc
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index
3a92f765c6c032e7d9a2ccbc8ea3dc87861a5dcf..3c0f8e24d6eff80b0babc7200858a91f47bb9344
100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -22592,6 +22592,72 @@ TEST(Promises) {
}
+TEST(PromiseThen) {
+ LocalContext context;
+ v8::Isolate* isolate = context->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Handle<Object> global = context->Global();
+
+ // Creation.
+ Handle<v8::Promise::Resolver> pr = v8::Promise::Resolver::New(isolate);
+ Handle<v8::Promise::Resolver> qr = v8::Promise::Resolver::New(isolate);
+ Handle<v8::Promise> p = pr->GetPromise();
+ Handle<v8::Promise> q = qr->GetPromise();
+
+ CHECK(p->IsPromise());
+ CHECK(q->IsPromise());
+
+ pr->Resolve(v8::Integer::New(isolate, 1));
+ qr->Resolve(p);
+
+ // Chaining non-pending promises.
+ CompileRun(
+ "var x1 = 0;\n"
+ "var x2 = 0;\n"
+ "function f1(x) { x1 = x; return x+1 };\n"
+ "function f2(x) { x2 = x; return x+1 };\n");
+ Handle<Function> f1 = Handle<Function>::Cast(global->Get(v8_str("f1")));
+ Handle<Function> f2 = Handle<Function>::Cast(global->Get(v8_str("f2")));
+
+ // Chain
+ q->Chain(f1);
+ CHECK(global->Get(v8_str("x1"))->IsNumber());
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK(!global->Get(v8_str("x1"))->IsNumber());
+ CHECK_EQ(p, global->Get(v8_str("x1")));
+
+ // Then
+ CompileRun("x1 = x2 = 0;");
+ q->Then(f1);
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(1, global->Get(v8_str("x1"))->Int32Value());
+
+ // Then
+ CompileRun("x1 = x2 = 0;");
+ pr = v8::Promise::Resolver::New(isolate);
+ qr = v8::Promise::Resolver::New(isolate);
+
+ qr->Resolve(pr);
+ qr->GetPromise()->Then(f1)->Then(f2);
+
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+
+ pr->Resolve(v8::Integer::New(isolate, 3));
+
+ CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value());
+ isolate->RunMicrotasks();
+ CHECK_EQ(3, global->Get(v8_str("x1"))->Int32Value());
+ CHECK_EQ(4, global->Get(v8_str("x2"))->Int32Value());
+}
+
+
TEST(DisallowJavascriptExecutionScope) {
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.