Commit 0a2f4c86 authored by rossberg@chromium.org's avatar rossberg@chromium.org

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
parent dc458525
......@@ -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<Promise> New(Isolate* isolate);
class V8_EXPORT Resolver : public Object {
public:
/**
* Create a new resolver, along with an associated promise in pending state.
*/
static Local<Resolver> New(Isolate* isolate);
/**
* Resolve/reject a promise with a given value.
* Ignored if the promise is not unresolved.
*/
void Resolve(Handle<Value> value);
void Reject(Handle<Value> value);
/**
* Extract the associated promise.
*/
Local<Promise> GetPromise();
/**
* Resolve/reject the associated promise with a given value.
* Ignored if the promise is no longer pending.
*/
void Resolve(Handle<Value> value);
void Reject(Handle<Value> 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<Promise::Resolver*>(value);
}
ArrayBuffer* ArrayBuffer::Cast(v8::Value* value) {
#ifdef V8_ENABLE_CHECKS
CheckCast(value);
......
......@@ -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<i::Object> obj = Utils::OpenHandle(that);
Utils::ApiCheck(obj->IsJSArrayBuffer(),
......@@ -5800,9 +5807,9 @@ bool Value::IsPromise() const {
}
Local<Promise> Promise::New(Isolate* v8_isolate) {
Local<Promise::Resolver> Promise::Resolver::New(Isolate* v8_isolate) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
LOG_API(isolate, "Promise::New");
LOG_API(isolate, "Promise::Resolver::New");
ENTER_V8(isolate);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result = i::Execution::Call(
......@@ -5813,15 +5820,21 @@ Local<Promise> Promise::New(Isolate* v8_isolate) {
0, NULL,
&has_pending_exception,
false);
EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
return Local<Promise>::Cast(Utils::ToLocal(result));
EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise::Resolver>());
return Local<Promise::Resolver>::Cast(Utils::ToLocal(result));
}
Local<Promise> Promise::Resolver::GetPromise() {
i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
return Local<Promise>::Cast(Utils::ToLocal(promise));
}
void Promise::Resolve(Handle<Value> value) {
void Promise::Resolver::Resolve(Handle<Value> value) {
i::Handle<i::JSObject> 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<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
......@@ -5837,10 +5850,10 @@ void Promise::Resolve(Handle<Value> value) {
}
void Promise::Reject(Handle<Value> value) {
void Promise::Resolver::Reject(Handle<Value> value) {
i::Handle<i::JSObject> 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<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
......
......@@ -22254,8 +22254,10 @@ TEST(Promises) {
Handle<Object> global = context->Global();
// Creation.
Handle<v8::Promise> p = v8::Promise::New(isolate);
Handle<v8::Promise> r = v8::Promise::New(isolate);
Handle<v8::Promise::Resolver> pr = v8::Promise::Resolver::New(isolate);
Handle<v8::Promise::Resolver> rr = v8::Promise::Resolver::New(isolate);
Handle<v8::Promise> p = pr->GetPromise();
Handle<v8::Promise> 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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment