Revision: 21805
Author:   [email protected]
Date:     Thu Jun 12 11:33:30 2014 UTC
Log:      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
[email protected]

Review URL: https://codereview.chromium.org/314553002
http://code.google.com/p/v8/source/detail?r=21805

Modified:
 /branches/bleeding_edge/include/v8.h
 /branches/bleeding_edge/src/api.cc
 /branches/bleeding_edge/src/bootstrapper.cc
 /branches/bleeding_edge/src/contexts.h
 /branches/bleeding_edge/src/promise.js
 /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/include/v8.h        Tue Jun 10 10:51:33 2014 UTC
+++ /branches/bleeding_edge/include/v8.h        Thu Jun 12 11:33:30 2014 UTC
@@ -2614,6 +2614,7 @@
    */
   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);

=======================================
--- /branches/bleeding_edge/src/api.cc  Thu Jun 12 09:55:25 2014 UTC
+++ /branches/bleeding_edge/src/api.cc  Thu Jun 12 11:33:30 2014 UTC
@@ -5908,6 +5908,26 @@
   EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
   return Local<Promise>::Cast(Utils::ToLocal(result));
 }
+
+
+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 {
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Tue Jun 10 14:01:08 2014 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Thu Jun 12 11:33:30 2014 UTC
@@ -1598,6 +1598,7 @@
   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);
=======================================
--- /branches/bleeding_edge/src/contexts.h      Tue Jun  3 08:12:43 2014 UTC
+++ /branches/bleeding_edge/src/contexts.h      Thu Jun 12 11:33:30 2014 UTC
@@ -162,6 +162,7 @@
   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 @@
     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,
=======================================
--- /branches/bleeding_edge/src/promise.js      Thu May 22 15:27:57 2014 UTC
+++ /branches/bleeding_edge/src/promise.js      Thu Jun 12 11:33:30 2014 UTC
@@ -17,6 +17,7 @@
 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 @@

   // 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
=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc Thu Jun 12 08:28:19 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-api.cc Thu Jun 12 11:33:30 2014 UTC
@@ -22601,6 +22601,72 @@
   CHECK_EQ(3, global->Get(v8_str("x1"))->Int32Value());
   CHECK_EQ(4, global->Get(v8_str("x2"))->Int32Value());
 }
+
+
+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) {

--
--
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.

Reply via email to