1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/promise-utils.h"
6 
7 #include "src/factory.h"
8 #include "src/isolate.h"
9 #include "src/objects-inl.h"
10 
11 namespace v8 {
12 namespace internal {
13 
14 enum PromiseResolvingFunctionContextSlot {
15   kAlreadyVisitedSlot = Context::MIN_CONTEXT_SLOTS,
16   kPromiseSlot,
17   kDebugEventSlot,
18   kPromiseContextLength,
19 };
20 
GetPromise(Handle<Context> context)21 JSObject* PromiseUtils::GetPromise(Handle<Context> context) {
22   return JSObject::cast(context->get(kPromiseSlot));
23 }
24 
GetDebugEvent(Handle<Context> context)25 Object* PromiseUtils::GetDebugEvent(Handle<Context> context) {
26   return context->get(kDebugEventSlot);
27 }
28 
HasAlreadyVisited(Handle<Context> context)29 bool PromiseUtils::HasAlreadyVisited(Handle<Context> context) {
30   return Smi::cast(context->get(kAlreadyVisitedSlot))->value() != 0;
31 }
32 
SetAlreadyVisited(Handle<Context> context)33 void PromiseUtils::SetAlreadyVisited(Handle<Context> context) {
34   context->set(kAlreadyVisitedSlot, Smi::FromInt(1));
35 }
36 
CreateResolvingFunctions(Isolate * isolate,Handle<JSObject> promise,Handle<Object> debug_event,Handle<JSFunction> * resolve,Handle<JSFunction> * reject)37 void PromiseUtils::CreateResolvingFunctions(Isolate* isolate,
38                                             Handle<JSObject> promise,
39                                             Handle<Object> debug_event,
40                                             Handle<JSFunction>* resolve,
41                                             Handle<JSFunction>* reject) {
42   DCHECK(debug_event->IsTrue(isolate) || debug_event->IsFalse(isolate));
43   Handle<Context> context =
44       isolate->factory()->NewPromiseResolvingFunctionContext(
45           kPromiseContextLength);
46   context->set_native_context(*isolate->native_context());
47   // We set the closure to be an empty function, same as native context.
48   context->set_closure(isolate->native_context()->closure());
49   context->set(kAlreadyVisitedSlot, Smi::kZero);
50   context->set(kPromiseSlot, *promise);
51   context->set(kDebugEventSlot, *debug_event);
52 
53   Handle<SharedFunctionInfo> resolve_shared_fun(
54       isolate->native_context()->promise_resolve_shared_fun(), isolate);
55   Handle<JSFunction> resolve_fun =
56       isolate->factory()->NewFunctionFromSharedFunctionInfo(
57           isolate->sloppy_function_without_prototype_map(), resolve_shared_fun,
58           isolate->native_context(), TENURED);
59 
60   Handle<SharedFunctionInfo> reject_shared_fun(
61       isolate->native_context()->promise_reject_shared_fun(), isolate);
62   Handle<JSFunction> reject_fun =
63       isolate->factory()->NewFunctionFromSharedFunctionInfo(
64           isolate->sloppy_function_without_prototype_map(), reject_shared_fun,
65           isolate->native_context(), TENURED);
66 
67   resolve_fun->set_context(*context);
68   reject_fun->set_context(*context);
69 
70   *resolve = resolve_fun;
71   *reject = reject_fun;
72 }
73 
74 }  // namespace internal
75 }  // namespace v8
76