From 0a2f4c86bd9fa97d376a012400270132b4d7051a Mon Sep 17 00:00:00 2001 From: "rossberg@chromium.org" Date: Mon, 17 Mar 2014 09:57:25 +0000 Subject: [PATCH] Split Promise API into Promise/Resolver R=svenpanne@chromium.org BUG= LOG=Y Review URL: https://codereview.chromium.org/196943014 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19972 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- include/v8.h | 42 ++++++++++++++++++++++++++++++++---------- src/api.cc | 29 +++++++++++++++++++++-------- test/cctest/test-api.cc | 34 ++++++++++++++++++---------------- 3 files changed, 71 insertions(+), 34 deletions(-) diff --git a/include/v8.h b/include/v8.h index e32a898..80b8c49 100644 --- a/include/v8.h +++ b/include/v8.h @@ -2621,17 +2621,31 @@ class V8_EXPORT Function : public Object { */ class V8_EXPORT Promise : public Object { public: - /** - * Create a new Promise in pending state. - */ - static Local New(Isolate* isolate); + class V8_EXPORT Resolver : public Object { + public: + /** + * Create a new resolver, along with an associated promise in pending state. + */ + static Local New(Isolate* isolate); - /** - * Resolve/reject a promise with a given value. - * Ignored if the promise is not unresolved. - */ - void Resolve(Handle value); - void Reject(Handle value); + /** + * Extract the associated promise. + */ + Local GetPromise(); + + /** + * Resolve/reject the associated promise with a given value. + * Ignored if the promise is no longer pending. + */ + void Resolve(Handle value); + void Reject(Handle value); + + V8_INLINE static Resolver* Cast(Value* obj); + + private: + Resolver(); + static void CheckCast(Value* obj); + }; /** * Register a resolution/rejection handler with a promise. @@ -6254,6 +6268,14 @@ Promise* Promise::Cast(v8::Value* value) { } +Promise::Resolver* Promise::Resolver::Cast(v8::Value* value) { +#ifdef V8_ENABLE_CHECKS + CheckCast(value); +#endif + return static_cast(value); +} + + ArrayBuffer* ArrayBuffer::Cast(v8::Value* value) { #ifdef V8_ENABLE_CHECKS CheckCast(value); diff --git a/src/api.cc b/src/api.cc index c5e71c9..c5241ec 100644 --- a/src/api.cc +++ b/src/api.cc @@ -2695,6 +2695,13 @@ void v8::Promise::CheckCast(Value* that) { } +void v8::Promise::Resolver::CheckCast(Value* that) { + Utils::ApiCheck(that->IsPromise(), + "v8::Promise::Resolver::Cast()", + "Could not convert to promise resolver"); +} + + void v8::ArrayBuffer::CheckCast(Value* that) { i::Handle obj = Utils::OpenHandle(that); Utils::ApiCheck(obj->IsJSArrayBuffer(), @@ -5800,9 +5807,9 @@ bool Value::IsPromise() const { } -Local Promise::New(Isolate* v8_isolate) { +Local Promise::Resolver::New(Isolate* v8_isolate) { i::Isolate* isolate = reinterpret_cast(v8_isolate); - LOG_API(isolate, "Promise::New"); + LOG_API(isolate, "Promise::Resolver::New"); ENTER_V8(isolate); EXCEPTION_PREAMBLE(isolate); i::Handle result = i::Execution::Call( @@ -5813,15 +5820,21 @@ Local Promise::New(Isolate* v8_isolate) { 0, NULL, &has_pending_exception, false); - EXCEPTION_BAILOUT_CHECK(isolate, Local()); - return Local::Cast(Utils::ToLocal(result)); + EXCEPTION_BAILOUT_CHECK(isolate, Local()); + return Local::Cast(Utils::ToLocal(result)); +} + + +Local Promise::Resolver::GetPromise() { + i::Handle promise = Utils::OpenHandle(this); + return Local::Cast(Utils::ToLocal(promise)); } -void Promise::Resolve(Handle value) { +void Promise::Resolver::Resolve(Handle value) { i::Handle promise = Utils::OpenHandle(this); i::Isolate* isolate = promise->GetIsolate(); - LOG_API(isolate, "Promise::Resolve"); + LOG_API(isolate, "Promise::Resolver::Resolve"); ENTER_V8(isolate); EXCEPTION_PREAMBLE(isolate); i::Handle argv[] = { promise, Utils::OpenHandle(*value) }; @@ -5837,10 +5850,10 @@ void Promise::Resolve(Handle value) { } -void Promise::Reject(Handle value) { +void Promise::Resolver::Reject(Handle value) { i::Handle promise = Utils::OpenHandle(this); i::Isolate* isolate = promise->GetIsolate(); - LOG_API(isolate, "Promise::Reject"); + LOG_API(isolate, "Promise::Resolver::Reject"); ENTER_V8(isolate); EXCEPTION_PREAMBLE(isolate); i::Handle argv[] = { promise, Utils::OpenHandle(*value) }; diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc index 5f4bc53..26d4701 100644 --- a/test/cctest/test-api.cc +++ b/test/cctest/test-api.cc @@ -22254,8 +22254,10 @@ TEST(Promises) { Handle global = context->Global(); // Creation. - Handle p = v8::Promise::New(isolate); - Handle r = v8::Promise::New(isolate); + Handle pr = v8::Promise::Resolver::New(isolate); + Handle rr = v8::Promise::Resolver::New(isolate); + Handle p = pr->GetPromise(); + Handle r = rr->GetPromise(); // IsPromise predicate. CHECK(p->IsPromise()); @@ -22264,9 +22266,9 @@ TEST(Promises) { CHECK(!o->IsPromise()); // Resolution and rejection. - p->Resolve(v8::Integer::New(isolate, 1)); + pr->Resolve(v8::Integer::New(isolate, 1)); CHECK(p->IsPromise()); - r->Reject(v8::Integer::New(isolate, 2)); + rr->Reject(v8::Integer::New(isolate, 2)); CHECK(r->IsPromise()); // Chaining non-pending promises. @@ -22298,17 +22300,17 @@ TEST(Promises) { // Chaining pending promises. CompileRun("x1 = x2 = 0;"); - p = v8::Promise::New(isolate); - r = v8::Promise::New(isolate); + pr = v8::Promise::Resolver::New(isolate); + rr = v8::Promise::Resolver::New(isolate); - p->Chain(f1); - r->Catch(f2); + pr->GetPromise()->Chain(f1); + rr->GetPromise()->Catch(f2); V8::RunMicrotasks(isolate); CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value()); - p->Resolve(v8::Integer::New(isolate, 1)); - r->Reject(v8::Integer::New(isolate, 2)); + pr->Resolve(v8::Integer::New(isolate, 1)); + rr->Reject(v8::Integer::New(isolate, 2)); CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value()); @@ -22318,9 +22320,9 @@ TEST(Promises) { // Multi-chaining. CompileRun("x1 = x2 = 0;"); - p = v8::Promise::New(isolate); - p->Chain(f1)->Chain(f2); - p->Resolve(v8::Integer::New(isolate, 3)); + pr = v8::Promise::Resolver::New(isolate); + pr->GetPromise()->Chain(f1)->Chain(f2); + 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()); V8::RunMicrotasks(isolate); @@ -22328,9 +22330,9 @@ TEST(Promises) { CHECK_EQ(4, global->Get(v8_str("x2"))->Int32Value()); CompileRun("x1 = x2 = 0;"); - r = v8::Promise::New(isolate); - r->Catch(f1)->Chain(f2); - r->Reject(v8::Integer::New(isolate, 3)); + rr = v8::Promise::Resolver::New(isolate); + rr->GetPromise()->Catch(f1)->Chain(f2); + rr->Reject(v8::Integer::New(isolate, 3)); CHECK_EQ(0, global->Get(v8_str("x1"))->Int32Value()); CHECK_EQ(0, global->Get(v8_str("x2"))->Int32Value()); V8::RunMicrotasks(isolate); -- 2.7.4