Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/runtime/runtime-promise.cc

Issue 2452833003: [promises] Create runtime-promise.cc (Closed)
Patch Set: rebase Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/runtime/runtime-internal.cc ('k') | src/v8.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/runtime/runtime-utils.h"
6
7 #include "src/debug/debug.h"
8 #include "src/elements.h"
9
10 namespace v8 {
11 namespace internal {
12
13 namespace {
14
15 void PromiseRejectEvent(Isolate* isolate, Handle<JSReceiver> promise,
16 Handle<Object> rejected_promise, Handle<Object> value,
17 bool debug_event) {
18 if (isolate->debug()->is_active() && debug_event) {
19 isolate->debug()->OnPromiseReject(rejected_promise, value);
20 }
21 Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol();
22 // Do not report if we actually have a handler.
23 if (JSReceiver::GetDataProperty(promise, key)->IsUndefined(isolate)) {
24 isolate->ReportPromiseReject(Handle<JSObject>::cast(promise), value,
25 v8::kPromiseRejectWithNoHandler);
26 }
27 }
28
29 } // namespace
30
31 RUNTIME_FUNCTION(Runtime_PromiseRejectEvent) {
32 DCHECK(args.length() == 3);
33 HandleScope scope(isolate);
34 CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
35 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
36 CONVERT_BOOLEAN_ARG_CHECKED(debug_event, 2);
37
38 PromiseRejectEvent(isolate, promise, promise, value, debug_event);
39 return isolate->heap()->undefined_value();
40 }
41
42 RUNTIME_FUNCTION(Runtime_PromiseRejectEventFromStack) {
43 DCHECK(args.length() == 2);
44 HandleScope scope(isolate);
45 CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
46 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
47
48 Handle<Object> rejected_promise = promise;
49 if (isolate->debug()->is_active()) {
50 // If the Promise.reject call is caught, then this will return
51 // undefined, which will be interpreted by PromiseRejectEvent
52 // as being a caught exception event.
53 rejected_promise = isolate->GetPromiseOnStackOnThrow();
54 }
55 PromiseRejectEvent(isolate, promise, rejected_promise, value, true);
56 return isolate->heap()->undefined_value();
57 }
58
59 RUNTIME_FUNCTION(Runtime_PromiseRevokeReject) {
60 DCHECK(args.length() == 1);
61 HandleScope scope(isolate);
62 CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
63 Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol();
64 // At this point, no revocation has been issued before
65 CHECK(JSReceiver::GetDataProperty(promise, key)->IsUndefined(isolate));
66 isolate->ReportPromiseReject(promise, Handle<Object>(),
67 v8::kPromiseHandlerAddedAfterReject);
68 return isolate->heap()->undefined_value();
69 }
70
71 namespace {
72 void EnqueuePromiseReactionJob(Isolate* isolate, Handle<Object> value,
73 Handle<Object> tasks, Handle<Object> deferred,
74 Handle<Object> status) {
75 Handle<Object> debug_id = isolate->factory()->undefined_value();
76 Handle<Object> debug_name = isolate->factory()->undefined_value();
77 if (isolate->debug()->is_active()) {
78 MaybeHandle<Object> maybe_result;
79 Handle<Object> argv[] = {deferred, status};
80 maybe_result = Execution::TryCall(
81 isolate, isolate->promise_debug_get_info(),
82 isolate->factory()->undefined_value(), arraysize(argv), argv);
83 Handle<Object> result;
84 if ((maybe_result).ToHandle(&result)) {
85 CHECK(result->IsJSArray());
86 Handle<JSArray> array = Handle<JSArray>::cast(result);
87 ElementsAccessor* accessor = array->GetElementsAccessor();
88 DCHECK(accessor->HasElement(array, 0));
89 DCHECK(accessor->HasElement(array, 1));
90 debug_id = accessor->Get(array, 0);
91 debug_name = accessor->Get(array, 1);
92 }
93 }
94 Handle<PromiseReactionJobInfo> info =
95 isolate->factory()->NewPromiseReactionJobInfo(value, tasks, deferred,
96 debug_id, debug_name,
97 isolate->native_context());
98 isolate->EnqueueMicrotask(info);
99 }
100
101 void PromiseFulfill(Isolate* isolate, Handle<JSReceiver> promise,
102 Handle<Smi> status, Handle<Object> value,
103 Handle<Symbol> reaction) {
104 Handle<Object> tasks = JSReceiver::GetDataProperty(promise, reaction);
105 if (!tasks->IsUndefined(isolate)) {
106 Handle<Object> deferred = JSReceiver::GetDataProperty(
107 promise, isolate->factory()->promise_deferred_reaction_symbol());
108 EnqueuePromiseReactionJob(isolate, value, tasks, deferred, status);
109 }
110 }
111 } // namespace
112
113 RUNTIME_FUNCTION(Runtime_PromiseReject) {
114 DCHECK(args.length() == 3);
115 HandleScope scope(isolate);
116 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, promise, 0);
117 CONVERT_ARG_HANDLE_CHECKED(Object, reason, 1);
118 CONVERT_BOOLEAN_ARG_CHECKED(debug_event, 2);
119
120 PromiseRejectEvent(isolate, promise, promise, reason, debug_event);
121
122 Handle<Smi> status = handle(Smi::FromInt(kPromiseRejected), isolate);
123 Handle<Symbol> reaction =
124 isolate->factory()->promise_reject_reactions_symbol();
125 PromiseFulfill(isolate, promise, status, reason, reaction);
126 return isolate->heap()->undefined_value();
127 }
128
129 RUNTIME_FUNCTION(Runtime_PromiseFulfill) {
130 DCHECK(args.length() == 4);
131 HandleScope scope(isolate);
132 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, promise, 0);
133 CONVERT_ARG_HANDLE_CHECKED(Smi, status, 1);
134 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
135 CONVERT_ARG_HANDLE_CHECKED(Symbol, reaction, 3);
136 PromiseFulfill(isolate, promise, status, value, reaction);
137 return isolate->heap()->undefined_value();
138 }
139
140 RUNTIME_FUNCTION(Runtime_EnqueuePromiseReactionJob) {
141 HandleScope scope(isolate);
142 DCHECK(args.length() == 4);
143 CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
144 CONVERT_ARG_HANDLE_CHECKED(Object, tasks, 1);
145 CONVERT_ARG_HANDLE_CHECKED(Object, deferred, 2);
146 CONVERT_ARG_HANDLE_CHECKED(Object, status, 3);
147 EnqueuePromiseReactionJob(isolate, value, tasks, deferred, status);
148 return isolate->heap()->undefined_value();
149 }
150
151 RUNTIME_FUNCTION(Runtime_EnqueuePromiseResolveThenableJob) {
152 HandleScope scope(isolate);
153 DCHECK(args.length() == 4);
154 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, resolution, 0);
155 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, then, 1);
156 CONVERT_ARG_HANDLE_CHECKED(JSFunction, resolve, 2);
157 CONVERT_ARG_HANDLE_CHECKED(JSFunction, reject, 3);
158 Handle<Object> debug_id;
159 Handle<Object> debug_name;
160 if (isolate->debug()->is_active()) {
161 debug_id =
162 handle(Smi::FromInt(isolate->GetNextDebugMicrotaskId()), isolate);
163 debug_name = isolate->factory()->PromiseResolveThenableJob_string();
164 isolate->debug()->OnAsyncTaskEvent(isolate->factory()->enqueue_string(),
165 debug_id,
166 Handle<String>::cast(debug_name));
167 } else {
168 debug_id = isolate->factory()->undefined_value();
169 debug_name = isolate->factory()->undefined_value();
170 }
171 Handle<PromiseResolveThenableJobInfo> info =
172 isolate->factory()->NewPromiseResolveThenableJobInfo(
173 resolution, then, resolve, reject, debug_id, debug_name);
174 isolate->EnqueueMicrotask(info);
175 return isolate->heap()->undefined_value();
176 }
177
178 RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
179 HandleScope scope(isolate);
180 DCHECK(args.length() == 1);
181 CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
182 isolate->EnqueueMicrotask(microtask);
183 return isolate->heap()->undefined_value();
184 }
185
186 RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
187 HandleScope scope(isolate);
188 DCHECK(args.length() == 0);
189 isolate->RunMicrotasks();
190 return isolate->heap()->undefined_value();
191 }
192
193 } // namespace internal
194 } // namespace v8
OLDNEW
« no previous file with comments | « src/runtime/runtime-internal.cc ('k') | src/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698