OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/base/utils/random-number-generator.h" | 5 #include "src/base/utils/random-number-generator.h" |
6 #include "src/builtins/builtins-promise.h" | 6 #include "src/builtins/builtins-promise.h" |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stub-assembler.h" | 8 #include "src/code-stub-assembler.h" |
9 #include "src/compiler/node.h" | 9 #include "src/compiler/node.h" |
10 #include "src/isolate.h" | 10 #include "src/isolate.h" |
(...skipping 2052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2063 Handle<JSFunction> fun = Handle<JSFunction>::cast(result_obj); | 2063 Handle<JSFunction> fun = Handle<JSFunction>::cast(result_obj); |
2064 CHECK_EQ(isolate->heap()->empty_fixed_array(), fun->properties()); | 2064 CHECK_EQ(isolate->heap()->empty_fixed_array(), fun->properties()); |
2065 CHECK_EQ(isolate->heap()->empty_fixed_array(), fun->elements()); | 2065 CHECK_EQ(isolate->heap()->empty_fixed_array(), fun->elements()); |
2066 CHECK_EQ(isolate->heap()->empty_literals_array(), fun->literals()); | 2066 CHECK_EQ(isolate->heap()->empty_literals_array(), fun->literals()); |
2067 CHECK_EQ(isolate->heap()->the_hole_value(), fun->prototype_or_initial_map()); | 2067 CHECK_EQ(isolate->heap()->the_hole_value(), fun->prototype_or_initial_map()); |
2068 CHECK_EQ(*isolate->promise_resolve_shared_fun(), fun->shared()); | 2068 CHECK_EQ(*isolate->promise_resolve_shared_fun(), fun->shared()); |
2069 CHECK_EQ(isolate->promise_resolve_shared_fun()->code(), fun->code()); | 2069 CHECK_EQ(isolate->promise_resolve_shared_fun()->code(), fun->code()); |
2070 CHECK_EQ(isolate->heap()->undefined_value(), fun->next_function_link()); | 2070 CHECK_EQ(isolate->heap()->undefined_value(), fun->next_function_link()); |
2071 } | 2071 } |
2072 | 2072 |
| 2073 TEST(CreatePromiseGetCapabilitiesExecutorContext) { |
| 2074 Isolate* isolate(CcTest::InitIsolateOnce()); |
| 2075 |
| 2076 const int kNumParams = 1; |
| 2077 CodeAssemblerTester data(isolate, kNumParams); |
| 2078 PromiseBuiltinsAssembler m(data.state()); |
| 2079 |
| 2080 Node* const context = m.Parameter(kNumParams + 2); |
| 2081 Node* const native_context = m.LoadNativeContext(context); |
| 2082 |
| 2083 Node* const map = m.LoadRoot(Heap::kJSPromiseCapabilityMapRootIndex); |
| 2084 Node* const capability = m.AllocateJSObjectFromMap(map); |
| 2085 m.StoreObjectFieldNoWriteBarrier( |
| 2086 capability, JSPromiseCapability::kPromiseOffset, m.UndefinedConstant()); |
| 2087 m.StoreObjectFieldNoWriteBarrier( |
| 2088 capability, JSPromiseCapability::kResolveOffset, m.UndefinedConstant()); |
| 2089 m.StoreObjectFieldNoWriteBarrier( |
| 2090 capability, JSPromiseCapability::kRejectOffset, m.UndefinedConstant()); |
| 2091 Node* const executor_context = |
| 2092 m.CreatePromiseGetCapabilitiesExecutorContext(capability, native_context); |
| 2093 m.Return(executor_context); |
| 2094 |
| 2095 Handle<Code> code = data.GenerateCode(); |
| 2096 CHECK(!code.is_null()); |
| 2097 |
| 2098 FunctionTester ft(code, kNumParams); |
| 2099 Handle<Object> result_obj = |
| 2100 ft.Call(isolate->factory()->undefined_value()).ToHandleChecked(); |
| 2101 CHECK(result_obj->IsContext()); |
| 2102 Handle<Context> context_js = Handle<Context>::cast(result_obj); |
| 2103 CHECK_EQ(GetPromiseCapabilityExecutor::kContextLength, context_js->length()); |
| 2104 CHECK_EQ(isolate->native_context()->closure(), context_js->closure()); |
| 2105 CHECK_EQ(isolate->heap()->the_hole_value(), context_js->extension()); |
| 2106 CHECK_EQ(*isolate->native_context(), context_js->native_context()); |
| 2107 CHECK(context_js->get(GetPromiseCapabilityExecutor::kCapabilitySlot) |
| 2108 ->IsJSPromiseCapability()); |
| 2109 } |
| 2110 |
| 2111 TEST(NewPromiseCapability) { |
| 2112 Isolate* isolate(CcTest::InitIsolateOnce()); |
| 2113 |
| 2114 { // Builtin Promise |
| 2115 const int kNumParams = 1; |
| 2116 CodeAssemblerTester data(isolate, kNumParams); |
| 2117 PromiseBuiltinsAssembler m(data.state()); |
| 2118 |
| 2119 Node* const context = m.Parameter(kNumParams + 2); |
| 2120 Node* const native_context = m.LoadNativeContext(context); |
| 2121 Node* const promise_constructor = |
| 2122 m.LoadContextElement(native_context, Context::PROMISE_FUNCTION_INDEX); |
| 2123 |
| 2124 Node* const capability = |
| 2125 m.NewPromiseCapability(context, promise_constructor); |
| 2126 m.Return(capability); |
| 2127 |
| 2128 Handle<Code> code = data.GenerateCode(); |
| 2129 FunctionTester ft(code, kNumParams); |
| 2130 |
| 2131 Handle<Object> result_obj = |
| 2132 ft.Call(isolate->factory()->undefined_value()).ToHandleChecked(); |
| 2133 CHECK(result_obj->IsJSPromiseCapability()); |
| 2134 Handle<JSPromiseCapability> result = |
| 2135 Handle<JSPromiseCapability>::cast(result_obj); |
| 2136 |
| 2137 CHECK(result->promise()->IsJSPromise()); |
| 2138 CHECK(result->resolve()->IsJSFunction()); |
| 2139 CHECK(result->reject()->IsJSFunction()); |
| 2140 CHECK_EQ(isolate->native_context()->promise_resolve_shared_fun(), |
| 2141 JSFunction::cast(result->resolve())->shared()); |
| 2142 CHECK_EQ(isolate->native_context()->promise_reject_shared_fun(), |
| 2143 JSFunction::cast(result->reject())->shared()); |
| 2144 |
| 2145 Handle<JSFunction> callbacks[] = { |
| 2146 handle(JSFunction::cast(result->resolve())), |
| 2147 handle(JSFunction::cast(result->reject()))}; |
| 2148 |
| 2149 for (auto&& callback : callbacks) { |
| 2150 Handle<Context> context(Context::cast(callback->context())); |
| 2151 CHECK_EQ(isolate->native_context()->closure(), context->closure()); |
| 2152 CHECK_EQ(isolate->heap()->the_hole_value(), context->extension()); |
| 2153 CHECK_EQ(*isolate->native_context(), context->native_context()); |
| 2154 CHECK_EQ(PromiseUtils::kPromiseContextLength, context->length()); |
| 2155 CHECK_EQ(context->get(PromiseUtils::kPromiseSlot), result->promise()); |
| 2156 } |
| 2157 } |
| 2158 |
| 2159 { // Custom Promise |
| 2160 const int kNumParams = 2; |
| 2161 CodeAssemblerTester data(isolate, kNumParams); |
| 2162 PromiseBuiltinsAssembler m(data.state()); |
| 2163 |
| 2164 Node* const context = m.Parameter(kNumParams + 2); |
| 2165 |
| 2166 Node* const constructor = m.Parameter(1); |
| 2167 Node* const capability = m.NewPromiseCapability(context, constructor); |
| 2168 m.Return(capability); |
| 2169 |
| 2170 Handle<Code> code = data.GenerateCode(); |
| 2171 FunctionTester ft(code, kNumParams); |
| 2172 |
| 2173 Handle<JSFunction> constructor_fn = |
| 2174 Handle<JSFunction>::cast(v8::Utils::OpenHandle(*CompileRun( |
| 2175 "(function FakePromise(executor) {" |
| 2176 " var self = this;" |
| 2177 " function resolve(value) { self.resolvedValue = value; }" |
| 2178 " function reject(reason) { self.rejectedReason = reason; }" |
| 2179 " executor(resolve, reject);" |
| 2180 "})"))); |
| 2181 |
| 2182 Handle<Object> result_obj = |
| 2183 ft.Call(isolate->factory()->undefined_value(), constructor_fn) |
| 2184 .ToHandleChecked(); |
| 2185 CHECK(result_obj->IsJSPromiseCapability()); |
| 2186 Handle<JSPromiseCapability> result = |
| 2187 Handle<JSPromiseCapability>::cast(result_obj); |
| 2188 |
| 2189 CHECK(result->promise()->IsJSObject()); |
| 2190 Handle<JSObject> promise(JSObject::cast(result->promise())); |
| 2191 CHECK_EQ(constructor_fn->prototype_or_initial_map(), promise->map()); |
| 2192 CHECK(result->resolve()->IsJSFunction()); |
| 2193 CHECK(result->reject()->IsJSFunction()); |
| 2194 |
| 2195 Handle<String> resolved_str = |
| 2196 isolate->factory()->NewStringFromAsciiChecked("resolvedStr"); |
| 2197 Handle<String> rejected_str = |
| 2198 isolate->factory()->NewStringFromAsciiChecked("rejectedStr"); |
| 2199 |
| 2200 Handle<Object> argv1[] = {resolved_str}; |
| 2201 Handle<Object> ret = |
| 2202 Execution::Call(isolate, handle(result->resolve(), isolate), |
| 2203 isolate->factory()->undefined_value(), 1, argv1) |
| 2204 .ToHandleChecked(); |
| 2205 |
| 2206 Handle<Object> prop1 = |
| 2207 JSReceiver::GetProperty(isolate, promise, "resolvedValue") |
| 2208 .ToHandleChecked(); |
| 2209 CHECK_EQ(*resolved_str, *prop1); |
| 2210 |
| 2211 Handle<Object> argv2[] = {rejected_str}; |
| 2212 ret = Execution::Call(isolate, handle(result->reject(), isolate), |
| 2213 isolate->factory()->undefined_value(), 1, argv2) |
| 2214 .ToHandleChecked(); |
| 2215 Handle<Object> prop2 = |
| 2216 JSReceiver::GetProperty(isolate, promise, "rejectedReason") |
| 2217 .ToHandleChecked(); |
| 2218 CHECK_EQ(*rejected_str, *prop2); |
| 2219 } |
| 2220 } |
| 2221 |
2073 } // namespace internal | 2222 } // namespace internal |
2074 } // namespace v8 | 2223 } // namespace v8 |
OLD | NEW |