Commit 2886e391 authored by gsathya's avatar gsathya Committed by Commit bot

[promises] Refactor CreatePromise

BUG=v8:5343

Review-Url: https://codereview.chromium.org/2571663002
Cr-Commit-Position: refs/heads/master@{#41660}
parent 493d48d8
......@@ -57,14 +57,6 @@ BUILTIN(CreateResolvingFunctions) {
NOT_TENURED);
}
void PromiseInit(CodeStubAssembler* a, compiler::Node* promise,
compiler::Node* status, compiler::Node* result) {
CSA_ASSERT(a, a->TaggedIsSmi(status));
a->StoreObjectField(promise, JSPromise::kStatusOffset, status);
a->StoreObjectField(promise, JSPromise::kResultOffset, result);
a->StoreObjectField(promise, JSPromise::kFlagsOffset, a->SmiConstant(0));
}
void Builtins::Generate_PromiseConstructor(
compiler::CodeAssemblerState* state) {
CodeStubAssembler a(state);
......@@ -104,10 +96,7 @@ void Builtins::Generate_PromiseConstructor(
a.Bind(&if_targetisnotmodified);
{
Node* const initial_map = a.LoadObjectField(
promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
Node* const instance = a.AllocateJSObjectFromMap(initial_map);
Node* const instance = a.AllocateJSPromise(context);
var_result.Bind(instance);
a.Goto(&init);
}
......@@ -124,8 +113,7 @@ void Builtins::Generate_PromiseConstructor(
a.Bind(&init);
{
PromiseInit(&a, var_result.value(), a.SmiConstant(kPromisePending),
a.UndefinedConstant());
a.PromiseInit(var_result.value());
a.Branch(is_debug_active, &debug_push, &run_executor);
}
......@@ -196,15 +184,8 @@ void Builtins::Generate_PromiseInternalConstructor(
CodeStubAssembler a(state);
Node* const context = a.Parameter(3);
Node* const native_context = a.LoadNativeContext(context);
Node* const promise_fun =
a.LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
Node* const initial_map =
a.LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
Node* const instance = a.AllocateJSObjectFromMap(initial_map);
PromiseInit(&a, instance, a.SmiConstant(kPromisePending),
a.UndefinedConstant());
Node* const instance = a.AllocateJSPromise(context);
a.PromiseInit(instance);
a.Return(instance);
}
......@@ -216,15 +197,9 @@ void Builtins::Generate_PromiseCreateAndSet(
Node* const status = a.Parameter(1);
Node* const result = a.Parameter(2);
Node* const context = a.Parameter(5);
Node* const native_context = a.LoadNativeContext(context);
Node* const promise_fun =
a.LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
Node* const initial_map =
a.LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
Node* const instance = a.AllocateJSObjectFromMap(initial_map);
PromiseInit(&a, instance, status, result);
Node* const instance = a.AllocateJSPromise(context);
a.PromiseSet(instance, status, result);
a.Return(instance);
}
......
......@@ -8222,5 +8222,29 @@ Node* CodeStubAssembler::IsPromiseHookEnabled() {
return WordNotEqual(is_promisehook_enabled, Int32Constant(0));
}
Node* CodeStubAssembler::AllocateJSPromise(Node* context) {
Node* const native_context = LoadNativeContext(context);
Node* const promise_fun =
LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
Node* const initial_map =
LoadObjectField(promise_fun, JSFunction::kPrototypeOrInitialMapOffset);
Node* const instance = AllocateJSObjectFromMap(initial_map);
return instance;
}
void CodeStubAssembler::PromiseInit(Node* promise) {
StoreObjectField(promise, JSPromise::kStatusOffset,
SmiConstant(kPromisePending));
StoreObjectField(promise, JSPromise::kFlagsOffset, SmiConstant(0));
}
void CodeStubAssembler::PromiseSet(Node* promise, Node* status, Node* result) {
CSA_ASSERT(this, TaggedIsSmi(status));
StoreObjectField(promise, JSPromise::kStatusOffset, status);
StoreObjectField(promise, JSPromise::kResultOffset, result);
StoreObjectField(promise, JSPromise::kFlagsOffset, SmiConstant(0));
}
} // namespace internal
} // namespace v8
......@@ -1082,6 +1082,13 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
// Promise helpers
Node* IsPromiseHookEnabled();
Node* AllocateJSPromise(Node* context);
void PromiseInit(Node* promise);
// Other promise fields may also be need to set/reset. This only
// provides a helper for certain init patterns.
void PromiseSet(Node* promise, Node* status, Node* result);
protected:
void DescriptorLookupLinear(Node* unique_name, Node* descriptors, Node* nof,
Label* if_found, Variable* var_name_index,
......
......@@ -1999,5 +1999,75 @@ TEST(IsPromiseHookEnabled) {
CHECK_EQ(isolate->heap()->false_value(), *result);
}
TEST(AllocateJSPromise) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 1;
CodeAssemblerTester data(isolate, kNumParams);
CodeStubAssembler m(data.state());
Node* const context = m.Parameter(kNumParams + 2);
Node* const promise = m.AllocateJSPromise(context);
m.Return(promise);
Handle<Code> code = data.GenerateCode();
CHECK(!code.is_null());
FunctionTester ft(code, kNumParams);
Handle<Object> result =
ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
CHECK(result->IsJSPromise());
}
TEST(PromiseInit) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 1;
CodeAssemblerTester data(isolate, kNumParams);
CodeStubAssembler m(data.state());
Node* const context = m.Parameter(kNumParams + 2);
Node* const promise = m.AllocateJSPromise(context);
m.PromiseInit(promise);
m.Return(promise);
Handle<Code> code = data.GenerateCode();
CHECK(!code.is_null());
FunctionTester ft(code, kNumParams);
Handle<Object> result =
ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
CHECK(result->IsJSPromise());
Handle<JSPromise> js_promise = Handle<JSPromise>::cast(result);
CHECK_EQ(kPromisePending, js_promise->status());
CHECK_EQ(isolate->heap()->undefined_value(), js_promise->result());
CHECK(!js_promise->has_handler());
}
TEST(PromiseSet) {
Isolate* isolate(CcTest::InitIsolateOnce());
const int kNumParams = 1;
CodeAssemblerTester data(isolate, kNumParams);
CodeStubAssembler m(data.state());
Node* const context = m.Parameter(kNumParams + 2);
Node* const promise = m.AllocateJSPromise(context);
m.PromiseSet(promise, m.SmiConstant(kPromisePending), m.SmiConstant(1));
m.Return(promise);
Handle<Code> code = data.GenerateCode();
CHECK(!code.is_null());
FunctionTester ft(code, kNumParams);
Handle<Object> result =
ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
CHECK(result->IsJSPromise());
Handle<JSPromise> js_promise = Handle<JSPromise>::cast(result);
CHECK_EQ(kPromisePending, js_promise->status());
CHECK_EQ(Smi::FromInt(1), js_promise->result());
CHECK(!js_promise->has_handler());
}
} // namespace internal
} // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment