Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Unified Diff: src/builtins/builtins-promise.cc

Issue 2567333002: [promises] port NewPromiseCapability to TF (Closed)
Patch Set: Make gcmole happy Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/builtins/builtins-promise.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins/builtins-promise.cc
diff --git a/src/builtins/builtins-promise.cc b/src/builtins/builtins-promise.cc
index 9a6a8fe275a0783e8c253313b982898db83a50de..323bfea5b5a74268d4b4665b8de7b46a0516cbcf 100644
--- a/src/builtins/builtins-promise.cc
+++ b/src/builtins/builtins-promise.cc
@@ -31,14 +31,128 @@ Node* PromiseBuiltinsAssembler::AllocateAndInitPromise(Node* context,
return instance;
}
-Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext(
+std::pair<Node*, Node*>
+PromiseBuiltinsAssembler::CreatePromiseResolvingFunctions(
Node* promise, Node* debug_event, Node* native_context) {
- Node* const context =
- Allocate(FixedArray::SizeFor(PromiseUtils::kPromiseContextLength));
- StoreMapNoWriteBarrier(context, Heap::kFunctionContextMapRootIndex);
+ Node* const promise_context = CreatePromiseResolvingFunctionsContext(
+ promise, debug_event, native_context);
+ Node* const map = LoadContextElement(
+ native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
+ Node* const resolve_info =
+ LoadContextElement(native_context, Context::PROMISE_RESOLVE_SHARED_FUN);
+ Node* const resolve =
+ AllocateFunctionWithMapAndContext(map, resolve_info, promise_context);
+ Node* const reject_info =
+ LoadContextElement(native_context, Context::PROMISE_REJECT_SHARED_FUN);
+ Node* const reject =
+ AllocateFunctionWithMapAndContext(map, reject_info, promise_context);
+ return std::make_pair(resolve, reject);
+}
+
+Node* PromiseBuiltinsAssembler::NewPromiseCapability(Node* context,
+ Node* constructor,
+ Node* debug_event) {
+ if (debug_event == nullptr) {
+ debug_event = TrueConstant();
+ }
+
+ Node* native_context = LoadNativeContext(context);
+
+ Node* map = LoadRoot(Heap::kJSPromiseCapabilityMapRootIndex);
+ Node* capability = AllocateJSObjectFromMap(map);
+
+ StoreObjectFieldNoWriteBarrier(
+ capability, JSPromiseCapability::kPromiseOffset, UndefinedConstant());
StoreObjectFieldNoWriteBarrier(
- context, FixedArray::kLengthOffset,
- SmiConstant(PromiseUtils::kPromiseContextLength));
+ capability, JSPromiseCapability::kResolveOffset, UndefinedConstant());
+ StoreObjectFieldNoWriteBarrier(capability, JSPromiseCapability::kRejectOffset,
+ UndefinedConstant());
+
+ Variable var_result(this, MachineRepresentation::kTagged);
+ var_result.Bind(capability);
+
+ Label if_builtin_promise(this), if_custom_promise(this, Label::kDeferred),
+ out(this);
+ Branch(WordEqual(constructor,
+ LoadContextElement(native_context,
+ Context::PROMISE_FUNCTION_INDEX)),
+ &if_builtin_promise, &if_custom_promise);
+
+ Bind(&if_builtin_promise);
+ {
+ Node* promise = AllocateJSPromise(context);
+ PromiseInit(promise);
+ StoreObjectFieldNoWriteBarrier(
+ capability, JSPromiseCapability::kPromiseOffset, promise);
+
+ Node* resolve = nullptr;
+ Node* reject = nullptr;
+
+ std::tie(resolve, reject) =
+ CreatePromiseResolvingFunctions(promise, debug_event, native_context);
+ StoreObjectField(capability, JSPromiseCapability::kResolveOffset, resolve);
+ StoreObjectField(capability, JSPromiseCapability::kRejectOffset, reject);
+
+ GotoUnless(IsPromiseHookEnabled(), &out);
+ CallRuntime(Runtime::kPromiseHookInit, context, promise,
+ UndefinedConstant());
+ Goto(&out);
+ }
+
+ Bind(&if_custom_promise);
+ {
+ Label if_notcallable(this, Label::kDeferred);
+ Node* executor_context =
+ CreatePromiseGetCapabilitiesExecutorContext(capability, native_context);
+ Node* executor_info = LoadContextElement(
+ native_context, Context::PROMISE_GET_CAPABILITIES_EXECUTOR_SHARED_FUN);
+ Node* function_map = LoadContextElement(
+ native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
+ Node* executor = AllocateFunctionWithMapAndContext(
+ function_map, executor_info, executor_context);
+
+ Node* promise = ConstructJS(CodeFactory::Construct(isolate()), context,
+ constructor, executor);
+
+ Node* resolve =
+ LoadObjectField(capability, JSPromiseCapability::kResolveOffset);
+ GotoIf(TaggedIsSmi(resolve), &if_notcallable);
+ GotoUnless(IsCallableMap(LoadMap(resolve)), &if_notcallable);
+
+ Node* reject =
+ LoadObjectField(capability, JSPromiseCapability::kRejectOffset);
+ GotoIf(TaggedIsSmi(reject), &if_notcallable);
+ GotoUnless(IsCallableMap(LoadMap(reject)), &if_notcallable);
+
+ StoreObjectField(capability, JSPromiseCapability::kPromiseOffset, promise);
+
+ Goto(&out);
+
+ Bind(&if_notcallable);
+ Node* message = SmiConstant(MessageTemplate::kPromiseNonCallable);
+ StoreObjectField(capability, JSPromiseCapability::kPromiseOffset,
+ UndefinedConstant());
+ StoreObjectField(capability, JSPromiseCapability::kResolveOffset,
+ UndefinedConstant());
+ StoreObjectField(capability, JSPromiseCapability::kRejectOffset,
+ UndefinedConstant());
+ CallRuntime(Runtime::kThrowTypeError, context, message);
+ var_result.Bind(UndefinedConstant());
+ Goto(&out);
+ }
+
+ Bind(&out);
+ return var_result.value();
+}
+
+Node* PromiseBuiltinsAssembler::CreatePromiseContext(Node* native_context,
+ int slots) {
+ DCHECK_GE(slots, Context::MIN_CONTEXT_SLOTS);
+
+ Node* const context = Allocate(FixedArray::SizeFor(slots));
+ StoreMapNoWriteBarrier(context, Heap::kFunctionContextMapRootIndex);
+ StoreObjectFieldNoWriteBarrier(context, FixedArray::kLengthOffset,
+ SmiConstant(slots));
Node* const empty_fn =
LoadContextElement(native_context, Context::CLOSURE_INDEX);
@@ -49,6 +163,13 @@ Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext(
TheHoleConstant());
StoreContextElementNoWriteBarrier(context, Context::NATIVE_CONTEXT_INDEX,
native_context);
+ return context;
+}
+
+Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext(
+ Node* promise, Node* debug_event, Node* native_context) {
+ Node* const context =
+ CreatePromiseContext(native_context, PromiseUtils::kPromiseContextLength);
StoreContextElementNoWriteBarrier(context, PromiseUtils::kAlreadyVisitedSlot,
SmiConstant(0));
StoreContextElementNoWriteBarrier(context, PromiseUtils::kPromiseSlot,
@@ -58,23 +179,14 @@ Node* PromiseBuiltinsAssembler::CreatePromiseResolvingFunctionsContext(
return context;
}
-std::pair<Node*, Node*>
-PromiseBuiltinsAssembler::CreatePromiseResolvingFunctions(
- Node* promise, Node* debug_event, Node* native_context) {
- Node* const promise_context = CreatePromiseResolvingFunctionsContext(
- promise, debug_event, native_context);
- Node* const map = LoadContextElement(
- native_context, Context::STRICT_FUNCTION_WITHOUT_PROTOTYPE_MAP_INDEX);
- Node* const resolve_info =
- LoadContextElement(native_context, Context::PROMISE_RESOLVE_SHARED_FUN);
- Node* const resolve =
- AllocateFunctionWithMapAndContext(map, resolve_info, promise_context);
- Node* const reject_info =
- LoadContextElement(native_context, Context::PROMISE_REJECT_SHARED_FUN);
- Node* const reject =
- AllocateFunctionWithMapAndContext(map, reject_info, promise_context);
-
- return std::make_pair(resolve, reject);
+Node* PromiseBuiltinsAssembler::CreatePromiseGetCapabilitiesExecutorContext(
+ Node* promise_capability, Node* native_context) {
+ int kContextLength = GetPromiseCapabilityExecutor::kContextLength;
+ Node* context = CreatePromiseContext(native_context, kContextLength);
+ StoreContextElementNoWriteBarrier(
+ context, GetPromiseCapabilityExecutor::kCapabilitySlot,
+ promise_capability);
+ return context;
}
Node* PromiseBuiltinsAssembler::ThrowIfNotJSReceiver(
@@ -234,28 +346,13 @@ Node* PromiseBuiltinsAssembler::InternalPromiseThen(Node* context,
Bind(&promise_capability);
{
- // TODO(gsathya): Move this to TF.
- Node* const new_promise_capability = LoadContextElement(
- native_context, Context::NEW_PROMISE_CAPABILITY_INDEX);
- Node* const deferred =
- CallJS(call_callable, context, new_promise_capability,
- UndefinedConstant(), constructor);
- Callable getproperty_callable = CodeFactory::GetProperty(isolate);
- Node* key = HeapConstant(isolate->factory()->promise_string());
- Node* const deferred_promise =
- CallStub(getproperty_callable, context, deferred, key);
- var_deferred_promise.Bind(deferred_promise);
-
- key = HeapConstant(isolate->factory()->resolve_string());
- Node* const deferred_on_resolve =
- CallStub(getproperty_callable, context, deferred, key);
- var_deferred_on_resolve.Bind(deferred_on_resolve);
-
- key = HeapConstant(isolate->factory()->reject_string());
- Node* const deferred_on_reject =
- CallStub(getproperty_callable, context, deferred, key);
- var_deferred_on_reject.Bind(deferred_on_reject);
-
+ Node* const capability = NewPromiseCapability(context, constructor);
+ var_deferred_promise.Bind(
+ LoadObjectField(capability, JSPromiseCapability::kPromiseOffset));
+ var_deferred_on_resolve.Bind(
+ LoadObjectField(capability, JSPromiseCapability::kResolveOffset));
+ var_deferred_on_reject.Bind(
+ LoadObjectField(capability, JSPromiseCapability::kRejectOffset));
Goto(&perform_promise_then);
}
@@ -671,37 +768,6 @@ BUILTIN(PromiseRejectClosure) {
return isolate->heap()->undefined_value();
}
-// ES#sec-createresolvingfunctions
-// CreateResolvingFunctions ( promise )
-TF_BUILTIN(CreateResolvingFunctions, PromiseBuiltinsAssembler) {
- Node* const promise = Parameter(1);
- Node* const debug_event = Parameter(2);
- Node* const context = Parameter(5);
- Node* const native_context = LoadNativeContext(context);
-
- Node* resolve = nullptr;
- Node* reject = nullptr;
-
- std::tie(resolve, reject) =
- CreatePromiseResolvingFunctions(promise, debug_event, native_context);
-
- Node* const kSize = IntPtrConstant(2);
- const ElementsKind kind = FAST_ELEMENTS;
- const WriteBarrierMode barrier_mode = SKIP_WRITE_BARRIER;
- const ParameterMode parameter_mode = INTPTR_PARAMETERS;
- Node* const arr = AllocateFixedArray(kind, kSize, parameter_mode);
- StoreFixedArrayElement(arr, 0, resolve, barrier_mode);
- StoreFixedArrayElement(arr, 1, reject, barrier_mode);
-
- Node* const array_map = LoadJSArrayElementsMap(kind, native_context);
- Node* const length = SmiTag(kSize);
- Node* const result = AllocateUninitializedJSArrayWithoutElements(
- kind, array_map, length, nullptr);
-
- StoreObjectField(result, JSObject::kElementsOffset, arr);
- Return(result);
-}
-
TF_BUILTIN(PromiseConstructor, PromiseBuiltinsAssembler) {
Node* const executor = Parameter(1);
Node* const new_target = Parameter(2);
@@ -1069,5 +1135,43 @@ TF_BUILTIN(PromiseCatch, PromiseBuiltinsAssembler) {
}
}
+TF_BUILTIN(PromiseGetCapabilitiesExecutor, PromiseBuiltinsAssembler) {
+ Node* const resolve = Parameter(1);
+ Node* const reject = Parameter(2);
+ Node* const context = Parameter(5);
+
+ Node* const capability = LoadContextElement(
+ context, GetPromiseCapabilityExecutor::kCapabilitySlot);
+
+ Label if_alreadyinvoked(this, Label::kDeferred);
+ GotoIf(WordNotEqual(
+ LoadObjectField(capability, JSPromiseCapability::kResolveOffset),
+ UndefinedConstant()),
+ &if_alreadyinvoked);
+ GotoIf(WordNotEqual(
+ LoadObjectField(capability, JSPromiseCapability::kRejectOffset),
+ UndefinedConstant()),
+ &if_alreadyinvoked);
+
+ StoreObjectField(capability, JSPromiseCapability::kResolveOffset, resolve);
+ StoreObjectField(capability, JSPromiseCapability::kRejectOffset, reject);
+
+ Return(UndefinedConstant());
+
+ Bind(&if_alreadyinvoked);
+ Node* message = SmiConstant(MessageTemplate::kPromiseExecutorAlreadyInvoked);
+ Return(CallRuntime(Runtime::kThrowTypeError, context, message));
+}
+
+TF_BUILTIN(NewPromiseCapability, PromiseBuiltinsAssembler) {
+ Node* constructor = Parameter(1);
+ Node* debug_event = Parameter(2);
+ Node* context = Parameter(5);
+
+ CSA_ASSERT_JS_ARGC_EQ(this, 2);
+
+ Return(NewPromiseCapability(context, constructor, debug_event));
+}
+
} // namespace internal
} // namespace v8
« no previous file with comments | « src/builtins/builtins-promise.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698