| Index: src/isolate.cc | 
| diff --git a/src/isolate.cc b/src/isolate.cc | 
| index 768d91b6d938a5ee205679b0de0fc4c60e19d090..cbbfeb9d9e1fed44556ff2abd7b05deaf1bf7201 100644 | 
| --- a/src/isolate.cc | 
| +++ b/src/isolate.cc | 
| @@ -2968,9 +2968,44 @@ void Isolate::ReportPromiseReject(Handle<JSObject> promise, | 
| v8::Utils::StackTraceToLocal(stack_trace))); | 
| } | 
|  | 
| +void Isolate::PromiseResolveThenableJob(Handle<PromiseContainer> container, | 
| +                                        MaybeHandle<Object>* result, | 
| +                                        MaybeHandle<Object>* maybe_exception) { | 
| +  if (debug()->is_active()) { | 
| +    Handle<Object> before_debug_event(container->before_debug_event(), this); | 
| +    if (before_debug_event->IsJSObject()) { | 
| +      debug()->OnAsyncTaskEvent(Handle<JSObject>::cast(before_debug_event)); | 
| +    } | 
| +  } | 
| + | 
| +  Handle<JSReceiver> thenable(container->thenable(), this); | 
| +  Handle<JSFunction> resolve(container->resolve(), this); | 
| +  Handle<JSFunction> reject(container->reject(), this); | 
| +  Handle<JSFunction> then(container->then(), this); | 
| +  Handle<Object> argv[] = {resolve, reject}; | 
| +  *result = Execution::TryCall(this, then, thenable, arraysize(argv), argv, | 
| +                               maybe_exception); | 
| + | 
| +  Handle<Object> reason; | 
| +  if (maybe_exception->ToHandle(&reason)) { | 
| +    DCHECK(result->is_null()); | 
| +    Handle<Object> reason_arg[] = {reason}; | 
| +    *result = | 
| +        Execution::TryCall(this, reject, factory()->undefined_value(), | 
| +                           arraysize(reason_arg), reason_arg, maybe_exception); | 
| +  } | 
| + | 
| +  if (debug()->is_active()) { | 
| +    Handle<Object> after_debug_event(container->after_debug_event(), this); | 
| +    if (after_debug_event->IsJSObject()) { | 
| +      debug()->OnAsyncTaskEvent(Handle<JSObject>::cast(after_debug_event)); | 
| +    } | 
| +  } | 
| +} | 
|  | 
| void Isolate::EnqueueMicrotask(Handle<Object> microtask) { | 
| -  DCHECK(microtask->IsJSFunction() || microtask->IsCallHandlerInfo()); | 
| +  DCHECK(microtask->IsJSFunction() || microtask->IsCallHandlerInfo() || | 
| +         microtask->IsPromiseContainer()); | 
| Handle<FixedArray> queue(heap()->microtask_queue(), this); | 
| int num_tasks = pending_microtask_count(); | 
| DCHECK(num_tasks <= queue->length()); | 
| @@ -3012,18 +3047,40 @@ void Isolate::RunMicrotasksInternal() { | 
| Isolate* isolate = this; | 
| FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < num_tasks, i++, { | 
| Handle<Object> microtask(queue->get(i), this); | 
| -      if (microtask->IsJSFunction()) { | 
| -        Handle<JSFunction> microtask_function = | 
| -            Handle<JSFunction>::cast(microtask); | 
| + | 
| +      if (microtask->IsCallHandlerInfo()) { | 
| +        Handle<CallHandlerInfo> callback_info = | 
| +            Handle<CallHandlerInfo>::cast(microtask); | 
| +        v8::MicrotaskCallback callback = | 
| +            v8::ToCData<v8::MicrotaskCallback>(callback_info->callback()); | 
| +        void* data = v8::ToCData<void*>(callback_info->data()); | 
| +        callback(data); | 
| +      } else { | 
| SaveContext save(this); | 
| -        set_context(microtask_function->context()->native_context()); | 
| +        Context* context = | 
| +            microtask->IsJSFunction() | 
| +                ? Handle<JSFunction>::cast(microtask)->context() | 
| +                : Handle<PromiseContainer>::cast(microtask)->then()->context(); | 
| +        set_context(context->native_context()); | 
| handle_scope_implementer_->EnterMicrotaskContext( | 
| -            handle(microtask_function->context(), this)); | 
| +            Handle<Context>(context, this)); | 
| + | 
| +        MaybeHandle<Object> result; | 
| MaybeHandle<Object> maybe_exception; | 
| -        MaybeHandle<Object> result = Execution::TryCall( | 
| -            this, microtask_function, factory()->undefined_value(), 0, NULL, | 
| -            &maybe_exception); | 
| + | 
| +        if (microtask->IsJSFunction()) { | 
| +          Handle<JSFunction> microtask_function = | 
| +              Handle<JSFunction>::cast(microtask); | 
| +          result = Execution::TryCall(this, microtask_function, | 
| +                                      factory()->undefined_value(), 0, NULL, | 
| +                                      &maybe_exception); | 
| +        } else { | 
| +          PromiseResolveThenableJob(Handle<PromiseContainer>::cast(microtask), | 
| +                                    &result, &maybe_exception); | 
| +        } | 
| + | 
| handle_scope_implementer_->LeaveMicrotaskContext(); | 
| + | 
| // If execution is terminating, just bail out. | 
| if (result.is_null() && maybe_exception.is_null()) { | 
| // Clear out any remaining callbacks in the queue. | 
| @@ -3031,13 +3088,6 @@ void Isolate::RunMicrotasksInternal() { | 
| set_pending_microtask_count(0); | 
| return; | 
| } | 
| -      } else { | 
| -        Handle<CallHandlerInfo> callback_info = | 
| -            Handle<CallHandlerInfo>::cast(microtask); | 
| -        v8::MicrotaskCallback callback = | 
| -            v8::ToCData<v8::MicrotaskCallback>(callback_info->callback()); | 
| -        void* data = v8::ToCData<void*>(callback_info->data()); | 
| -        callback(data); | 
| } | 
| }); | 
| } | 
|  |