| Index: src/builtins/builtins-promise.cc
|
| diff --git a/src/builtins/builtins-promise.cc b/src/builtins/builtins-promise.cc
|
| index c273a7e8606d387030dd0c696542c86983a5b7e9..e6034e7b6bf70299450ad972a518583b8f2b2557 100644
|
| --- a/src/builtins/builtins-promise.cc
|
| +++ b/src/builtins/builtins-promise.cc
|
| @@ -898,27 +898,36 @@ void PromiseBuiltinsAssembler::PromiseFulfill(
|
|
|
| // ES#sec-promise-reject-functions
|
| // Promise Reject Functions
|
| -BUILTIN(PromiseRejectClosure) {
|
| - HandleScope scope(isolate);
|
| +TF_BUILTIN(PromiseRejectClosure, PromiseBuiltinsAssembler) {
|
| + Node* const value = Parameter(1);
|
| + Node* const context = Parameter(4);
|
| +
|
| + Label out(this);
|
|
|
| - Handle<Context> context(isolate->context(), isolate);
|
| + // 3. Let alreadyResolved be F.[[AlreadyResolved]].
|
| + int has_already_visited_slot = PromiseUtils::kAlreadyVisitedSlot;
|
|
|
| - if (PromiseUtils::HasAlreadyVisited(context)) {
|
| - return isolate->heap()->undefined_value();
|
| - }
|
| + Node* const has_already_visited =
|
| + LoadContextElement(context, has_already_visited_slot);
|
| +
|
| + // 4. If alreadyResolved.[[Value]] is true, return undefined.
|
| + GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out);
|
| +
|
| + // 5.Set alreadyResolved.[[Value]] to true.
|
| + StoreContextElementNoWriteBarrier(context, has_already_visited_slot,
|
| + SmiConstant(1));
|
| +
|
| + // 2. Let promise be F.[[Promise]].
|
| + Node* const promise =
|
| + LoadContextElement(context, IntPtrConstant(PromiseUtils::kPromiseSlot));
|
| + Node* const debug_event = LoadContextElement(
|
| + context, IntPtrConstant(PromiseUtils::kDebugEventSlot));
|
|
|
| - PromiseUtils::SetAlreadyVisited(context);
|
| - Handle<Object> value = args.atOrUndefined(isolate, 1);
|
| - Handle<JSObject> promise = handle(PromiseUtils::GetPromise(context), isolate);
|
| - Handle<Object> debug_event =
|
| - handle(PromiseUtils::GetDebugEvent(context), isolate);
|
| - MaybeHandle<Object> maybe_result;
|
| - Handle<Object> argv[] = {promise, value, debug_event};
|
| - RETURN_FAILURE_ON_EXCEPTION(
|
| - isolate, Execution::Call(isolate, isolate->promise_internal_reject(),
|
| - isolate->factory()->undefined_value(),
|
| - arraysize(argv), argv));
|
| - return isolate->heap()->undefined_value();
|
| + CallRuntime(Runtime::kPromiseReject, context, promise, value, debug_event);
|
| + Return(UndefinedConstant());
|
| +
|
| + Bind(&out);
|
| + Return(UndefinedConstant());
|
| }
|
|
|
| TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
|
| @@ -1037,15 +1046,6 @@ TF_BUILTIN(PromiseInternalConstructor, PromiseBuiltinsAssembler) {
|
| Return(AllocateAndInitJSPromise(context, parent));
|
| }
|
|
|
| -TF_BUILTIN(PromiseCreateAndSet, PromiseBuiltinsAssembler) {
|
| - Node* const status = Parameter(1);
|
| - Node* const result = Parameter(2);
|
| - Node* const context = Parameter(5);
|
| -
|
| - Node* const instance = AllocateAndSetJSPromise(context, status, result);
|
| - Return(instance);
|
| -}
|
| -
|
| TF_BUILTIN(IsPromise, PromiseBuiltinsAssembler) {
|
| Node* const maybe_promise = Parameter(1);
|
| Label if_notpromise(this, Label::kDeferred);
|
| @@ -1100,21 +1100,21 @@ TF_BUILTIN(PromiseResolveClosure, PromiseBuiltinsAssembler) {
|
| Label out(this);
|
|
|
| // 3. Let alreadyResolved be F.[[AlreadyResolved]].
|
| - Node* const has_already_visited_slot =
|
| - IntPtrConstant(PromiseUtils::kAlreadyVisitedSlot);
|
| + int has_already_visited_slot = PromiseUtils::kAlreadyVisitedSlot;
|
|
|
| Node* const has_already_visited =
|
| - LoadFixedArrayElement(context, has_already_visited_slot);
|
| + LoadContextElement(context, has_already_visited_slot);
|
|
|
| // 4. If alreadyResolved.[[Value]] is true, return undefined.
|
| GotoIf(SmiEqual(has_already_visited, SmiConstant(1)), &out);
|
|
|
| // 5.Set alreadyResolved.[[Value]] to true.
|
| - StoreFixedArrayElement(context, has_already_visited_slot, SmiConstant(1));
|
| + StoreContextElementNoWriteBarrier(context, has_already_visited_slot,
|
| + SmiConstant(1));
|
|
|
| // 2. Let promise be F.[[Promise]].
|
| - Node* const promise = LoadFixedArrayElement(
|
| - context, IntPtrConstant(PromiseUtils::kPromiseSlot));
|
| + Node* const promise =
|
| + LoadContextElement(context, IntPtrConstant(PromiseUtils::kPromiseSlot));
|
|
|
| InternalResolvePromise(context, promise, value);
|
| Return(UndefinedConstant());
|
| @@ -1402,5 +1402,49 @@ TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) {
|
| Return(NewPromiseCapability(context, constructor, debug_event));
|
| }
|
|
|
| +TF_BUILTIN(PromiseReject, PromiseBuiltinsAssembler) {
|
| + // 1. Let C be the this value.
|
| + Node* const receiver = Parameter(0);
|
| + Node* const reason = Parameter(1);
|
| + Node* const context = Parameter(4);
|
| +
|
| + // 2. If Type(C) is not Object, throw a TypeError exception.
|
| + ThrowIfNotJSReceiver(context, receiver, MessageTemplate::kCalledOnNonObject,
|
| + "PromiseReject");
|
| +
|
| + Label if_nativepromise(this), if_custompromise(this, Label::kDeferred);
|
| + Node* const native_context = LoadNativeContext(context);
|
| + Node* const promise_fun =
|
| + LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
|
| + Branch(WordEqual(promise_fun, receiver), &if_nativepromise,
|
| + &if_custompromise);
|
| +
|
| + Bind(&if_nativepromise);
|
| + {
|
| + Node* const promise = AllocateAndSetJSPromise(
|
| + context, SmiConstant(v8::Promise::kRejected), reason);
|
| + CallRuntime(Runtime::kPromiseRejectEventFromStack, context, promise,
|
| + reason);
|
| + Return(promise);
|
| + }
|
| +
|
| + Bind(&if_custompromise);
|
| + {
|
| + // 3. Let promiseCapability be ? NewPromiseCapability(C).
|
| + Node* const capability = NewPromiseCapability(context, receiver);
|
| +
|
| + // 4. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »).
|
| + Node* const reject =
|
| + LoadObjectField(capability, JSPromiseCapability::kRejectOffset);
|
| + Callable call_callable = CodeFactory::Call(isolate());
|
| + CallJS(call_callable, context, reject, UndefinedConstant(), reason);
|
| +
|
| + // 5. Return promiseCapability.[[Promise]].
|
| + Node* const promise =
|
| + LoadObjectField(capability, JSPromiseCapability::kPromiseOffset);
|
| + Return(promise);
|
| + }
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace v8
|
|
|