Line data Source code
1 : // Copyright 2018 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 : #ifndef V8_OBJECTS_JS_PROMISE_H_
6 : #define V8_OBJECTS_JS_PROMISE_H_
7 :
8 : #include "src/objects/js-objects.h"
9 : #include "src/objects/promise.h"
10 :
11 : // Has to be the last include (doesn't have include guards):
12 : #include "src/objects/object-macros.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : // Representation of promise objects in the specification. Our layout of
18 : // JSPromise differs a bit from the layout in the specification, for example
19 : // there's only a single list of PromiseReaction objects, instead of separate
20 : // lists for fulfill and reject reactions. The PromiseReaction carries both
21 : // callbacks from the start, and is eventually morphed into the proper kind of
22 : // PromiseReactionJobTask when the JSPromise is settled.
23 : //
24 : // We also overlay the result and reactions fields on the JSPromise, since
25 : // the reactions are only necessary for pending promises, whereas the result
26 : // is only meaningful for settled promises.
27 : class JSPromise : public JSObject {
28 : public:
29 : // [reactions_or_result]: Smi 0 terminated list of PromiseReaction objects
30 : // in case the JSPromise was not settled yet, otherwise the result.
31 : DECL_ACCESSORS(reactions_or_result, Object)
32 :
33 : // [result]: Checks that the promise is settled and returns the result.
34 : inline Object result() const;
35 :
36 : // [reactions]: Checks that the promise is pending and returns the reactions.
37 : inline Object reactions() const;
38 :
39 : DECL_INT_ACCESSORS(flags)
40 :
41 : // [has_handler]: Whether this promise has a reject handler or not.
42 : DECL_BOOLEAN_ACCESSORS(has_handler)
43 :
44 : // [handled_hint]: Whether this promise will be handled by a catch
45 : // block in an async function.
46 : DECL_BOOLEAN_ACCESSORS(handled_hint)
47 :
48 : int async_task_id() const;
49 : void set_async_task_id(int id);
50 :
51 : static const char* Status(Promise::PromiseState status);
52 : Promise::PromiseState status() const;
53 : void set_status(Promise::PromiseState status);
54 :
55 : // ES section #sec-fulfillpromise
56 : static Handle<Object> Fulfill(Handle<JSPromise> promise,
57 : Handle<Object> value);
58 : // ES section #sec-rejectpromise
59 : static Handle<Object> Reject(Handle<JSPromise> promise, Handle<Object> reason,
60 : bool debug_event = true);
61 : // ES section #sec-promise-resolve-functions
62 : V8_WARN_UNUSED_RESULT static MaybeHandle<Object> Resolve(
63 : Handle<JSPromise> promise, Handle<Object> resolution);
64 :
65 : DECL_CAST(JSPromise)
66 :
67 : // Dispatched behavior.
68 : DECL_PRINTER(JSPromise)
69 : DECL_VERIFIER(JSPromise)
70 :
71 : #define JS_PROMISE_FIELDS(V) \
72 : V(kReactionsOrResultOffset, kTaggedSize) \
73 : V(kFlagsOffset, kTaggedSize) \
74 : /* Header size. */ \
75 : V(kSize, 0)
76 :
77 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_PROMISE_FIELDS)
78 : #undef JS_PROMISE_FIELDS
79 :
80 : static const int kSizeWithEmbedderFields =
81 : kSize + v8::Promise::kEmbedderFieldCount * kEmbedderDataSlotSize;
82 :
83 : // Flags layout.
84 : // The first two bits store the v8::Promise::PromiseState.
85 : static const int kStatusBits = 2;
86 : static const int kHasHandlerBit = 2;
87 : static const int kHandledHintBit = 3;
88 : class AsyncTaskIdField : public BitField<int, kHandledHintBit + 1, 22> {};
89 :
90 : static const int kStatusShift = 0;
91 : static const int kStatusMask = 0x3;
92 : STATIC_ASSERT(v8::Promise::kPending == 0);
93 : STATIC_ASSERT(v8::Promise::kFulfilled == 1);
94 : STATIC_ASSERT(v8::Promise::kRejected == 2);
95 :
96 : private:
97 : // ES section #sec-triggerpromisereactions
98 : static Handle<Object> TriggerPromiseReactions(Isolate* isolate,
99 : Handle<Object> reactions,
100 : Handle<Object> argument,
101 : PromiseReaction::Type type);
102 :
103 28100 : OBJECT_CONSTRUCTORS(JSPromise, JSObject);
104 : };
105 :
106 : } // namespace internal
107 : } // namespace v8
108 :
109 : #include "src/objects/object-macros-undef.h"
110 :
111 : #endif // V8_OBJECTS_JS_PROMISE_H_
|