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 "include/v8-promise.h"
9#include "src/objects/js-objects.h"
10#include "src/objects/promise.h"
11#include "torque-generated/bit-fields.h"
12
13// Has to be the last include (doesn't have include guards):
14#include "src/objects/object-macros.h"
15
16namespace v8 {
17namespace internal {
18
19#include "torque-generated/src/objects/js-promise-tq.inc"
20
21// Representation of promise objects in the specification. Our layout of
22// JSPromise differs a bit from the layout in the specification, for example
23// there's only a single list of PromiseReaction objects, instead of separate
24// lists for fulfill and reject reactions. The PromiseReaction carries both
25// callbacks from the start, and is eventually morphed into the proper kind of
26// PromiseReactionJobTask when the JSPromise is settled.
27//
28// We also overlay the result and reactions fields on the JSPromise, since
29// the reactions are only necessary for pending promises, whereas the result
30// is only meaningful for settled promises.
31class JSPromise
32    : public TorqueGeneratedJSPromise<JSPromise, JSObjectWithEmbedderSlots> {
33 public:
34  // [result]: Checks that the promise is settled and returns the result.
35  inline Object result() const;
36
37  // [reactions]: Checks that the promise is pending and returns the reactions.
38  inline Object reactions() const;
39
40  // [has_handler]: Whether this promise has a reject handler or not.
41  DECL_BOOLEAN_ACCESSORS(has_handler)
42
43  // [handled_hint]: Whether this promise will be handled by a catch
44  // block in an async function.
45  DECL_BOOLEAN_ACCESSORS(handled_hint)
46
47  // [is_silent]: Whether this promise should cause the debugger to pause when
48  // rejected.
49  DECL_BOOLEAN_ACCESSORS(is_silent)
50
51  int async_task_id() const;
52  void set_async_task_id(int id);
53
54  static const char* Status(Promise::PromiseState status);
55  V8_EXPORT_PRIVATE Promise::PromiseState status() const;
56  void set_status(Promise::PromiseState status);
57
58  // ES section #sec-fulfillpromise
59  V8_EXPORT_PRIVATE static Handle<Object> Fulfill(Handle<JSPromise> promise,
60                                                  Handle<Object> value);
61  // ES section #sec-rejectpromise
62  static Handle<Object> Reject(Handle<JSPromise> promise, Handle<Object> reason,
63                               bool debug_event = true);
64  // ES section #sec-promise-resolve-functions
65  V8_WARN_UNUSED_RESULT static MaybeHandle<Object> Resolve(
66      Handle<JSPromise> promise, Handle<Object> resolution);
67
68  // Dispatched behavior.
69  DECL_PRINTER(JSPromise)
70  DECL_VERIFIER(JSPromise)
71
72  static const int kSizeWithEmbedderFields =
73      kHeaderSize + v8::Promise::kEmbedderFieldCount * kEmbedderDataSlotSize;
74
75  // Flags layout.
76  DEFINE_TORQUE_GENERATED_JS_PROMISE_FLAGS()
77
78  STATIC_ASSERT(v8::Promise::kPending == 0);
79  STATIC_ASSERT(v8::Promise::kFulfilled == 1);
80  STATIC_ASSERT(v8::Promise::kRejected == 2);
81
82 private:
83  // ES section #sec-triggerpromisereactions
84  static Handle<Object> TriggerPromiseReactions(Isolate* isolate,
85                                                Handle<Object> reactions,
86                                                Handle<Object> argument,
87                                                PromiseReaction::Type type);
88
89  TQ_OBJECT_CONSTRUCTORS(JSPromise)
90};
91
92}  // namespace internal
93}  // namespace v8
94
95#include "src/objects/object-macros-undef.h"
96
97#endif  // V8_OBJECTS_JS_PROMISE_H_
98