| Index: test/cctest/test-code-stub-assembler.cc
|
| diff --git a/test/cctest/test-code-stub-assembler.cc b/test/cctest/test-code-stub-assembler.cc
|
| index 8b5a8b965d9631acb80fd7d65e2324fc1dc3b9f0..d0bae923aefda7f6d8f7be7609d243b28242afc3 100644
|
| --- a/test/cctest/test-code-stub-assembler.cc
|
| +++ b/test/cctest/test-code-stub-assembler.cc
|
| @@ -2070,5 +2070,154 @@ TEST(AllocateFunctionWithMapAndContext) {
|
| CHECK_EQ(isolate->heap()->undefined_value(), fun->next_function_link());
|
| }
|
|
|
| +TEST(CreatePromiseGetCapabilitiesExecutorContext) {
|
| + Isolate* isolate(CcTest::InitIsolateOnce());
|
| +
|
| + const int kNumParams = 1;
|
| + CodeAssemblerTester data(isolate, kNumParams);
|
| + PromiseBuiltinsAssembler m(data.state());
|
| +
|
| + Node* const context = m.Parameter(kNumParams + 2);
|
| + Node* const native_context = m.LoadNativeContext(context);
|
| +
|
| + Node* const map = m.LoadRoot(Heap::kJSPromiseCapabilityMapRootIndex);
|
| + Node* const capability = m.AllocateJSObjectFromMap(map);
|
| + m.StoreObjectFieldNoWriteBarrier(
|
| + capability, JSPromiseCapability::kPromiseOffset, m.UndefinedConstant());
|
| + m.StoreObjectFieldNoWriteBarrier(
|
| + capability, JSPromiseCapability::kResolveOffset, m.UndefinedConstant());
|
| + m.StoreObjectFieldNoWriteBarrier(
|
| + capability, JSPromiseCapability::kRejectOffset, m.UndefinedConstant());
|
| + Node* const executor_context =
|
| + m.CreatePromiseGetCapabilitiesExecutorContext(capability, native_context);
|
| + m.Return(executor_context);
|
| +
|
| + Handle<Code> code = data.GenerateCode();
|
| + CHECK(!code.is_null());
|
| +
|
| + FunctionTester ft(code, kNumParams);
|
| + Handle<Object> result_obj =
|
| + ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
|
| + CHECK(result_obj->IsContext());
|
| + Handle<Context> context_js = Handle<Context>::cast(result_obj);
|
| + CHECK_EQ(GetPromiseCapabilityExecutor::kContextLength, context_js->length());
|
| + CHECK_EQ(isolate->native_context()->closure(), context_js->closure());
|
| + CHECK_EQ(isolate->heap()->the_hole_value(), context_js->extension());
|
| + CHECK_EQ(*isolate->native_context(), context_js->native_context());
|
| + CHECK(context_js->get(GetPromiseCapabilityExecutor::kCapabilitySlot)
|
| + ->IsJSPromiseCapability());
|
| +}
|
| +
|
| +TEST(NewPromiseCapability) {
|
| + Isolate* isolate(CcTest::InitIsolateOnce());
|
| +
|
| + { // Builtin Promise
|
| + const int kNumParams = 1;
|
| + CodeAssemblerTester data(isolate, kNumParams);
|
| + PromiseBuiltinsAssembler m(data.state());
|
| +
|
| + Node* const context = m.Parameter(kNumParams + 2);
|
| + Node* const native_context = m.LoadNativeContext(context);
|
| + Node* const promise_constructor =
|
| + m.LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX);
|
| +
|
| + Node* const capability =
|
| + m.NewPromiseCapability(context, promise_constructor);
|
| + m.Return(capability);
|
| +
|
| + Handle<Code> code = data.GenerateCode();
|
| + FunctionTester ft(code, kNumParams);
|
| +
|
| + Handle<Object> result_obj =
|
| + ft.Call(isolate->factory()->undefined_value()).ToHandleChecked();
|
| + CHECK(result_obj->IsJSPromiseCapability());
|
| + Handle<JSPromiseCapability> result =
|
| + Handle<JSPromiseCapability>::cast(result_obj);
|
| +
|
| + CHECK(result->promise()->IsJSPromise());
|
| + CHECK(result->resolve()->IsJSFunction());
|
| + CHECK(result->reject()->IsJSFunction());
|
| + CHECK_EQ(isolate->native_context()->promise_resolve_shared_fun(),
|
| + JSFunction::cast(result->resolve())->shared());
|
| + CHECK_EQ(isolate->native_context()->promise_reject_shared_fun(),
|
| + JSFunction::cast(result->reject())->shared());
|
| +
|
| + Handle<JSFunction> callbacks[] = {
|
| + handle(JSFunction::cast(result->resolve())),
|
| + handle(JSFunction::cast(result->reject()))};
|
| +
|
| + for (auto&& callback : callbacks) {
|
| + Handle<Context> context(Context::cast(callback->context()));
|
| + CHECK_EQ(isolate->native_context()->closure(), context->closure());
|
| + CHECK_EQ(isolate->heap()->the_hole_value(), context->extension());
|
| + CHECK_EQ(*isolate->native_context(), context->native_context());
|
| + CHECK_EQ(PromiseUtils::kPromiseContextLength, context->length());
|
| + CHECK_EQ(context->get(PromiseUtils::kPromiseSlot), result->promise());
|
| + }
|
| + }
|
| +
|
| + { // Custom Promise
|
| + const int kNumParams = 2;
|
| + CodeAssemblerTester data(isolate, kNumParams);
|
| + PromiseBuiltinsAssembler m(data.state());
|
| +
|
| + Node* const context = m.Parameter(kNumParams + 2);
|
| +
|
| + Node* const constructor = m.Parameter(1);
|
| + Node* const capability = m.NewPromiseCapability(context, constructor);
|
| + m.Return(capability);
|
| +
|
| + Handle<Code> code = data.GenerateCode();
|
| + FunctionTester ft(code, kNumParams);
|
| +
|
| + Handle<JSFunction> constructor_fn =
|
| + Handle<JSFunction>::cast(v8::Utils::OpenHandle(*CompileRun(
|
| + "(function FakePromise(executor) {"
|
| + " var self = this;"
|
| + " function resolve(value) { self.resolvedValue = value; }"
|
| + " function reject(reason) { self.rejectedReason = reason; }"
|
| + " executor(resolve, reject);"
|
| + "})")));
|
| +
|
| + Handle<Object> result_obj =
|
| + ft.Call(isolate->factory()->undefined_value(), constructor_fn)
|
| + .ToHandleChecked();
|
| + CHECK(result_obj->IsJSPromiseCapability());
|
| + Handle<JSPromiseCapability> result =
|
| + Handle<JSPromiseCapability>::cast(result_obj);
|
| +
|
| + CHECK(result->promise()->IsJSObject());
|
| + Handle<JSObject> promise(JSObject::cast(result->promise()));
|
| + CHECK_EQ(constructor_fn->prototype_or_initial_map(), promise->map());
|
| + CHECK(result->resolve()->IsJSFunction());
|
| + CHECK(result->reject()->IsJSFunction());
|
| +
|
| + Handle<String> resolved_str =
|
| + isolate->factory()->NewStringFromAsciiChecked("resolvedStr");
|
| + Handle<String> rejected_str =
|
| + isolate->factory()->NewStringFromAsciiChecked("rejectedStr");
|
| +
|
| + Handle<Object> argv1[] = {resolved_str};
|
| + Handle<Object> ret =
|
| + Execution::Call(isolate, handle(result->resolve(), isolate),
|
| + isolate->factory()->undefined_value(), 1, argv1)
|
| + .ToHandleChecked();
|
| +
|
| + Handle<Object> prop1 =
|
| + JSReceiver::GetProperty(isolate, promise, "resolvedValue")
|
| + .ToHandleChecked();
|
| + CHECK_EQ(*resolved_str, *prop1);
|
| +
|
| + Handle<Object> argv2[] = {rejected_str};
|
| + ret = Execution::Call(isolate, handle(result->reject(), isolate),
|
| + isolate->factory()->undefined_value(), 1, argv2)
|
| + .ToHandleChecked();
|
| + Handle<Object> prop2 =
|
| + JSReceiver::GetProperty(isolate, promise, "rejectedReason")
|
| + .ToHandleChecked();
|
| + CHECK_EQ(*rejected_str, *prop2);
|
| + }
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace v8
|
|
|