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.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 // Layout description. 72 static const int kReactionsOrResultOffset = JSObject::kHeaderSize; 73 static const int kFlagsOffset = kReactionsOrResultOffset + kPointerSize; 74 static const int kSize = kFlagsOffset + kPointerSize; 75 static const int kSizeWithEmbedderFields = 76 kSize + v8::Promise::kEmbedderFieldCount * kPointerSize; 77 78 // Flags layout. 79 // The first two bits store the v8::Promise::PromiseState. 80 static const int kStatusBits = 2; 81 static const int kHasHandlerBit = 2; 82 static const int kHandledHintBit = 3; 83 class AsyncTaskIdField : public BitField<int, kHandledHintBit + 1, 22> {}; 84 85 static const int kStatusShift = 0; 86 static const int kStatusMask = 0x3; 87 STATIC_ASSERT(v8::Promise::kPending == 0); 88 STATIC_ASSERT(v8::Promise::kFulfilled == 1); 89 STATIC_ASSERT(v8::Promise::kRejected == 2); 90 91 private: 92 // ES section #sec-triggerpromisereactions 93 static Handle<Object> TriggerPromiseReactions(Isolate* isolate, 94 Handle<Object> reactions, 95 Handle<Object> argument, 96 PromiseReaction::Type type); 97 }; 98 99 } // namespace internal 100 } // namespace v8 101 102 #include "src/objects/object-macros-undef.h" 103 104 #endif // V8_OBJECTS_JS_PROMISE_H_ 105