| Index: src/builtins/builtins-promise.cc
|
| diff --git a/src/builtins/builtins-promise.cc b/src/builtins/builtins-promise.cc
|
| index aa38002218e744fd87a221fe753230a78487f337..8b0ef4c1c9d99427dbadb1ae8590104d5322bfa8 100644
|
| --- a/src/builtins/builtins-promise.cc
|
| +++ b/src/builtins/builtins-promise.cc
|
| @@ -892,5 +892,127 @@ void Builtins::Generate_ResolvePromise(compiler::CodeAssemblerState* state) {
|
| a.Return(a.UndefinedConstant());
|
| }
|
|
|
| +void Builtins::Generate_PromiseHandleReject(
|
| + compiler::CodeAssemblerState* state) {
|
| + CodeStubAssembler a(state);
|
| + typedef compiler::Node Node;
|
| + typedef CodeStubAssembler::Label Label;
|
| + typedef CodeStubAssembler::Variable Variable;
|
| + typedef PromiseHandleRejectDescriptor Descriptor;
|
| +
|
| + Node* const promise = a.Parameter(Descriptor::kPromise);
|
| + Node* const on_reject = a.Parameter(Descriptor::kOnReject);
|
| + Node* const exception = a.Parameter(Descriptor::kException);
|
| + Node* const context = a.Parameter(Descriptor::kContext);
|
| + Isolate* isolate = a.isolate();
|
| +
|
| + Callable call_callable = CodeFactory::Call(isolate);
|
| + Variable var_unused(&a, MachineRepresentation::kTagged);
|
| +
|
| + Label if_internalhandler(&a), if_customhandler(&a, Label::kDeferred);
|
| + a.Branch(a.IsUndefined(on_reject), &if_internalhandler, &if_customhandler);
|
| +
|
| + a.Bind(&if_internalhandler);
|
| + {
|
| + a.CallRuntime(Runtime::kPromiseReject, context, promise, exception,
|
| + a.FalseConstant());
|
| + a.Return(a.UndefinedConstant());
|
| + }
|
| +
|
| + a.Bind(&if_customhandler);
|
| + {
|
| + a.CallJS(call_callable, context, on_reject, a.UndefinedConstant(),
|
| + exception);
|
| + a.Return(a.UndefinedConstant());
|
| + }
|
| +}
|
| +
|
| +void Builtins::Generate_PromiseHandle(compiler::CodeAssemblerState* state) {
|
| + CodeStubAssembler a(state);
|
| + typedef compiler::Node Node;
|
| + typedef CodeStubAssembler::Label Label;
|
| + typedef CodeStubAssembler::Variable Variable;
|
| +
|
| + Node* const value = a.Parameter(1);
|
| + Node* const handler = a.Parameter(2);
|
| + Node* const deferred = a.Parameter(3);
|
| + Node* const context = a.Parameter(6);
|
| + Isolate* isolate = a.isolate();
|
| +
|
| + // Get promise from deferred
|
| + // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
|
| + Callable getproperty_callable = CodeFactory::GetProperty(isolate);
|
| + Node* const key = a.HeapConstant(isolate->factory()->promise_string());
|
| + Node* const promise =
|
| + a.CallStub(getproperty_callable, context, deferred, key);
|
| +
|
| + Variable var_reason(&a, MachineRepresentation::kTagged);
|
| +
|
| + Node* const is_debug_active = a.IsDebugActive();
|
| + Label run_handler(&a), if_rejectpromise(&a), debug_push(&a, Label::kDeferred),
|
| + debug_pop(&a, Label::kDeferred);
|
| + a.Branch(is_debug_active, &debug_push, &run_handler);
|
| +
|
| + a.Bind(&debug_push);
|
| + {
|
| + a.CallRuntime(Runtime::kDebugPushPromise, context, promise);
|
| + a.Goto(&run_handler);
|
| + }
|
| +
|
| + a.Bind(&run_handler);
|
| + {
|
| + Callable call_callable = CodeFactory::Call(isolate);
|
| +
|
| + Node* const result =
|
| + a.CallJS(call_callable, context, handler, a.UndefinedConstant(), value);
|
| +
|
| + a.GotoIfException(result, &if_rejectpromise, &var_reason);
|
| +
|
| + // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
|
| + Node* const key = a.HeapConstant(isolate->factory()->resolve_string());
|
| + Node* const on_resolve =
|
| + a.CallStub(getproperty_callable, context, deferred, key);
|
| +
|
| + Label if_internalhandler(&a), if_customhandler(&a, Label::kDeferred);
|
| + a.Branch(a.IsUndefined(on_resolve), &if_internalhandler, &if_customhandler);
|
| +
|
| + a.Bind(&if_internalhandler);
|
| + InternalResolvePromise(&a, context, promise, result, &debug_pop);
|
| +
|
| + a.Bind(&if_customhandler);
|
| + {
|
| + Node* const maybe_exception = a.CallJS(call_callable, context, on_resolve,
|
| + a.UndefinedConstant(), result);
|
| + a.GotoIfException(maybe_exception, &if_rejectpromise, &var_reason);
|
| + a.Goto(&debug_pop);
|
| + }
|
| + }
|
| +
|
| + a.Bind(&if_rejectpromise);
|
| + {
|
| + // TODO(gsathya): Remove this lookup by getting rid of the deferred object.
|
| + Node* const key = a.HeapConstant(isolate->factory()->reject_string());
|
| + Node* const on_reject =
|
| + a.CallStub(getproperty_callable, context, deferred, key);
|
| +
|
| + Callable promise_handle_reject = CodeFactory::PromiseHandleReject(isolate);
|
| + a.CallStub(promise_handle_reject, context, promise, on_reject,
|
| + var_reason.value());
|
| + a.Goto(&debug_pop);
|
| + }
|
| +
|
| + a.Bind(&debug_pop);
|
| + {
|
| + Label out(&a);
|
| +
|
| + a.GotoUnless(is_debug_active, &out);
|
| + a.CallRuntime(Runtime::kDebugPopPromise, context);
|
| + a.Goto(&out);
|
| +
|
| + a.Bind(&out);
|
| + a.Return(a.UndefinedConstant());
|
| + }
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace v8
|
|
|