Line data Source code
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 : #include "src/runtime/runtime-utils.h"
5 :
6 : #include "src/arguments.h"
7 : #include "src/counters.h"
8 : #include "src/debug/debug.h"
9 : #include "src/elements.h"
10 : #include "src/objects-inl.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 :
15 : namespace {
16 :
17 2192 : void PromiseRejectEvent(Isolate* isolate, Handle<JSPromise> promise,
18 : Handle<Object> rejected_promise, Handle<Object> value,
19 : bool debug_event) {
20 : isolate->RunPromiseHook(PromiseHookType::kResolve, promise,
21 1096 : isolate->factory()->undefined_value());
22 :
23 1096 : if (isolate->debug()->is_active() && debug_event) {
24 452 : isolate->debug()->OnPromiseReject(rejected_promise, value);
25 : }
26 :
27 : // Report only if we don't actually have a handler.
28 1096 : if (!promise->has_handler()) {
29 : isolate->ReportPromiseReject(Handle<JSObject>::cast(promise), value,
30 1096 : v8::kPromiseRejectWithNoHandler);
31 : }
32 1096 : }
33 :
34 : } // namespace
35 :
36 4192 : RUNTIME_FUNCTION(Runtime_PromiseRejectEventFromStack) {
37 : DCHECK_EQ(2, args.length());
38 1096 : HandleScope scope(isolate);
39 2192 : CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
40 1096 : CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
41 :
42 : Handle<Object> rejected_promise = promise;
43 1096 : if (isolate->debug()->is_active()) {
44 : // If the Promise.reject call is caught, then this will return
45 : // undefined, which will be interpreted by PromiseRejectEvent
46 : // as being a caught exception event.
47 452 : rejected_promise = isolate->GetPromiseOnStackOnThrow();
48 : isolate->debug()->OnAsyncTaskEvent(
49 : debug::kDebugEnqueuePromiseReject,
50 904 : isolate->debug()->NextAsyncTaskId(promise), 0);
51 : }
52 1096 : PromiseRejectEvent(isolate, promise, rejected_promise, value, true);
53 1096 : return isolate->heap()->undefined_value();
54 : }
55 :
56 35980 : RUNTIME_FUNCTION(Runtime_ReportPromiseReject) {
57 : DCHECK_EQ(2, args.length());
58 17990 : HandleScope scope(isolate);
59 35980 : CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
60 17990 : CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
61 : isolate->ReportPromiseReject(Handle<JSObject>::cast(promise), value,
62 17990 : v8::kPromiseRejectWithNoHandler);
63 17990 : return isolate->heap()->undefined_value();
64 : }
65 :
66 15412 : RUNTIME_FUNCTION(Runtime_PromiseRevokeReject) {
67 : DCHECK_EQ(1, args.length());
68 7706 : HandleScope scope(isolate);
69 15412 : CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
70 : // At this point, no revocation has been issued before
71 7706 : CHECK(!promise->has_handler());
72 : isolate->ReportPromiseReject(promise, Handle<Object>(),
73 7706 : v8::kPromiseHandlerAddedAfterReject);
74 7706 : return isolate->heap()->undefined_value();
75 : }
76 :
77 460552 : RUNTIME_FUNCTION(Runtime_EnqueuePromiseReactionJob) {
78 230276 : HandleScope scope(isolate);
79 : DCHECK_EQ(1, args.length());
80 460552 : CONVERT_ARG_HANDLE_CHECKED(PromiseReactionJobInfo, info, 0);
81 230276 : isolate->EnqueueMicrotask(info);
82 230276 : return isolate->heap()->undefined_value();
83 : }
84 :
85 49044 : RUNTIME_FUNCTION(Runtime_EnqueuePromiseResolveThenableJob) {
86 24522 : HandleScope scope(isolate);
87 : DCHECK(args.length() == 1);
88 49044 : CONVERT_ARG_HANDLE_CHECKED(PromiseResolveThenableJobInfo, info, 0);
89 24522 : isolate->EnqueueMicrotask(info);
90 24522 : return isolate->heap()->undefined_value();
91 : }
92 :
93 1072 : RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
94 536 : HandleScope scope(isolate);
95 : DCHECK_EQ(1, args.length());
96 1072 : CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
97 536 : isolate->EnqueueMicrotask(microtask);
98 536 : return isolate->heap()->undefined_value();
99 : }
100 :
101 22096 : RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
102 11048 : HandleScope scope(isolate);
103 : DCHECK_EQ(0, args.length());
104 11048 : isolate->RunMicrotasks();
105 11048 : return isolate->heap()->undefined_value();
106 : }
107 :
108 36 : RUNTIME_FUNCTION(Runtime_PromiseStatus) {
109 18 : HandleScope scope(isolate);
110 : DCHECK_EQ(1, args.length());
111 36 : CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
112 :
113 18 : return Smi::FromInt(promise->status());
114 : }
115 :
116 0 : RUNTIME_FUNCTION(Runtime_PromiseResult) {
117 0 : HandleScope scope(isolate);
118 : DCHECK_EQ(1, args.length());
119 0 : CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
120 0 : return promise->result();
121 : }
122 :
123 12 : RUNTIME_FUNCTION(Runtime_PromiseMarkAsHandled) {
124 : SealHandleScope shs(isolate);
125 : DCHECK_EQ(1, args.length());
126 12 : CONVERT_ARG_CHECKED(JSPromise, promise, 0);
127 :
128 6 : promise->set_has_handler(true);
129 6 : return isolate->heap()->undefined_value();
130 : }
131 :
132 75124 : RUNTIME_FUNCTION(Runtime_PromiseHookInit) {
133 37562 : HandleScope scope(isolate);
134 : DCHECK_EQ(2, args.length());
135 75124 : CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
136 37562 : CONVERT_ARG_HANDLE_CHECKED(Object, parent, 1);
137 37562 : isolate->RunPromiseHook(PromiseHookType::kInit, promise, parent);
138 37562 : return isolate->heap()->undefined_value();
139 : }
140 :
141 85800 : RUNTIME_FUNCTION(Runtime_PromiseHookResolve) {
142 42900 : HandleScope scope(isolate);
143 : DCHECK_EQ(1, args.length());
144 85800 : CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
145 : isolate->RunPromiseHook(PromiseHookType::kResolve, promise,
146 85800 : isolate->factory()->undefined_value());
147 42900 : return isolate->heap()->undefined_value();
148 : }
149 :
150 38116 : RUNTIME_FUNCTION(Runtime_PromiseHookBefore) {
151 19058 : HandleScope scope(isolate);
152 : DCHECK_EQ(1, args.length());
153 38116 : CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
154 19058 : if (promise->IsJSPromise()) {
155 : isolate->RunPromiseHook(PromiseHookType::kBefore,
156 : Handle<JSPromise>::cast(promise),
157 38088 : isolate->factory()->undefined_value());
158 : }
159 19058 : return isolate->heap()->undefined_value();
160 : }
161 :
162 38088 : RUNTIME_FUNCTION(Runtime_PromiseHookAfter) {
163 19044 : HandleScope scope(isolate);
164 : DCHECK_EQ(1, args.length());
165 38088 : CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
166 19044 : if (promise->IsJSPromise()) {
167 : isolate->RunPromiseHook(PromiseHookType::kAfter,
168 : Handle<JSPromise>::cast(promise),
169 38088 : isolate->factory()->undefined_value());
170 : }
171 19044 : return isolate->heap()->undefined_value();
172 : }
173 :
174 : } // namespace internal
175 : } // namespace v8
|