blob: 42b772bab1580883b53e8ff6d6ddac255af37da2 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2012 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(function(global, utils, extrasUtils) {
6
7"use strict";
8
9%CheckIsBootstrapping();
10
11// -------------------------------------------------------------------
12// Imports
13
14var InternalArray = utils.InternalArray;
15var MakeTypeError;
16var promiseCombinedDeferredSymbol =
17 utils.ImportNow("promise_combined_deferred_symbol");
18var promiseHasHandlerSymbol =
19 utils.ImportNow("promise_has_handler_symbol");
Ben Murdochc5610432016-08-08 18:44:38 +010020var promiseRejectReactionsSymbol =
21 utils.ImportNow("promise_reject_reactions_symbol");
22var promiseFulfillReactionsSymbol =
23 utils.ImportNow("promise_fulfill_reactions_symbol");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000024var promiseRawSymbol = utils.ImportNow("promise_raw_symbol");
Ben Murdochc5610432016-08-08 18:44:38 +010025var promiseStateSymbol = utils.ImportNow("promise_state_symbol");
26var promiseResultSymbol = utils.ImportNow("promise_result_symbol");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000027var SpeciesConstructor;
28var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
29
30utils.Import(function(from) {
31 MakeTypeError = from.MakeTypeError;
32 SpeciesConstructor = from.SpeciesConstructor;
33});
34
35// -------------------------------------------------------------------
36
Ben Murdochc5610432016-08-08 18:44:38 +010037// [[PromiseState]] values:
38const kPending = 0;
39const kFulfilled = +1;
40const kRejected = -1;
41
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042var lastMicrotaskId = 0;
43
Ben Murdochc5610432016-08-08 18:44:38 +010044// ES#sec-createresolvingfunctions
45// CreateResolvingFunctions ( promise )
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000046function CreateResolvingFunctions(promise) {
47 var alreadyResolved = false;
48
Ben Murdochc5610432016-08-08 18:44:38 +010049 // ES#sec-promise-resolve-functions
50 // Promise Resolve Functions
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000051 var resolve = value => {
52 if (alreadyResolved === true) return;
53 alreadyResolved = true;
Ben Murdochc5610432016-08-08 18:44:38 +010054 FulfillPromise(promise, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000055 };
56
Ben Murdochc5610432016-08-08 18:44:38 +010057 // ES#sec-promise-reject-functions
58 // Promise Reject Functions
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000059 var reject = reason => {
60 if (alreadyResolved === true) return;
61 alreadyResolved = true;
Ben Murdochc5610432016-08-08 18:44:38 +010062 RejectPromise(promise, reason);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000063 };
64
65 return {
66 __proto__: null,
67 resolve: resolve,
68 reject: reject
69 };
70}
71
72
Ben Murdochc5610432016-08-08 18:44:38 +010073// ES#sec-promise-executor
74// Promise ( executor )
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000075var GlobalPromise = function Promise(resolver) {
76 if (resolver === promiseRawSymbol) {
Ben Murdochda12d292016-06-02 14:46:10 +010077 return %_NewObject(GlobalPromise, new.target);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000078 }
79 if (IS_UNDEFINED(new.target)) throw MakeTypeError(kNotAPromise, this);
Ben Murdochc5610432016-08-08 18:44:38 +010080 if (!IS_CALLABLE(resolver)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000081 throw MakeTypeError(kResolverNotAFunction, resolver);
Ben Murdochc5610432016-08-08 18:44:38 +010082 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000083
Ben Murdochda12d292016-06-02 14:46:10 +010084 var promise = PromiseInit(%_NewObject(GlobalPromise, new.target));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000085 var callbacks = CreateResolvingFunctions(promise);
86
87 try {
88 %DebugPushPromise(promise, Promise);
89 resolver(callbacks.resolve, callbacks.reject);
90 } catch (e) {
91 %_Call(callbacks.reject, UNDEFINED, e);
92 } finally {
93 %DebugPopPromise();
94 }
95
96 return promise;
97}
98
99// Core functionality.
100
101function PromiseSet(promise, status, value, onResolve, onReject) {
Ben Murdochc5610432016-08-08 18:44:38 +0100102 SET_PRIVATE(promise, promiseStateSymbol, status);
103 SET_PRIVATE(promise, promiseResultSymbol, value);
104 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, onResolve);
105 SET_PRIVATE(promise, promiseRejectReactionsSymbol, onReject);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000106 return promise;
107}
108
109function PromiseCreateAndSet(status, value) {
110 var promise = new GlobalPromise(promiseRawSymbol);
111 // If debug is active, notify about the newly created promise first.
Ben Murdochc5610432016-08-08 18:44:38 +0100112 if (DEBUG_IS_ACTIVE) PromiseSet(promise, kPending, UNDEFINED);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000113 return PromiseSet(promise, status, value);
114}
115
116function PromiseInit(promise) {
117 return PromiseSet(
Ben Murdochc5610432016-08-08 18:44:38 +0100118 promise, kPending, UNDEFINED, new InternalArray, new InternalArray)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000119}
120
121function PromiseDone(promise, status, value, promiseQueue) {
Ben Murdochc5610432016-08-08 18:44:38 +0100122 if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123 var tasks = GET_PRIVATE(promise, promiseQueue);
124 if (tasks.length) PromiseEnqueue(value, tasks, status);
125 PromiseSet(promise, status, value);
126 }
127}
128
129function PromiseHandle(value, handler, deferred) {
130 try {
131 %DebugPushPromise(deferred.promise, PromiseHandle);
132 var result = handler(value);
133 deferred.resolve(result);
134 } catch (exception) {
135 try { deferred.reject(exception); } catch (e) { }
136 } finally {
137 %DebugPopPromise();
138 }
139}
140
141function PromiseEnqueue(value, tasks, status) {
142 var id, name, instrumenting = DEBUG_IS_ACTIVE;
143 %EnqueueMicrotask(function() {
144 if (instrumenting) {
145 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
146 }
147 for (var i = 0; i < tasks.length; i += 2) {
148 PromiseHandle(value, tasks[i], tasks[i + 1])
149 }
150 if (instrumenting) {
151 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
152 }
153 });
154 if (instrumenting) {
155 id = ++lastMicrotaskId;
Ben Murdochc5610432016-08-08 18:44:38 +0100156 name = status === kFulfilled ? "Promise.resolve" : "Promise.reject";
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000157 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
158 }
159}
160
161function PromiseIdResolveHandler(x) { return x }
162function PromiseIdRejectHandler(r) { throw r }
163
164function PromiseNopResolver() {}
165
166// -------------------------------------------------------------------
167// Define exported functions.
168
169// For bootstrapper.
170
Ben Murdochc5610432016-08-08 18:44:38 +0100171// ES#sec-ispromise IsPromise ( x )
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000172function IsPromise(x) {
Ben Murdochc5610432016-08-08 18:44:38 +0100173 return IS_RECEIVER(x) && HAS_DEFINED_PRIVATE(x, promiseStateSymbol);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000174}
175
176function PromiseCreate() {
177 return new GlobalPromise(PromiseNopResolver)
178}
179
Ben Murdochc5610432016-08-08 18:44:38 +0100180// ES#sec-fulfillpromise
181// FulfillPromise ( promise, value)
182function FulfillPromise(promise, x) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000183 if (x === promise) {
Ben Murdochc5610432016-08-08 18:44:38 +0100184 return RejectPromise(promise, MakeTypeError(kPromiseCyclic, x));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000185 }
186 if (IS_RECEIVER(x)) {
187 // 25.4.1.3.2 steps 8-12
188 try {
189 var then = x.then;
190 } catch (e) {
Ben Murdochc5610432016-08-08 18:44:38 +0100191 return RejectPromise(promise, e);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000192 }
193 if (IS_CALLABLE(then)) {
194 // PromiseResolveThenableJob
195 var id, name, instrumenting = DEBUG_IS_ACTIVE;
196 %EnqueueMicrotask(function() {
197 if (instrumenting) {
198 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
199 }
200 var callbacks = CreateResolvingFunctions(promise);
201 try {
202 %_Call(then, x, callbacks.resolve, callbacks.reject);
203 } catch (e) {
204 %_Call(callbacks.reject, UNDEFINED, e);
205 }
206 if (instrumenting) {
207 %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
208 }
209 });
210 if (instrumenting) {
211 id = ++lastMicrotaskId;
212 name = "PromseResolveThenableJob";
213 %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
214 }
215 return;
216 }
217 }
Ben Murdochc5610432016-08-08 18:44:38 +0100218 PromiseDone(promise, kFulfilled, x, promiseFulfillReactionsSymbol);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219}
220
Ben Murdochc5610432016-08-08 18:44:38 +0100221// ES#sec-rejectpromise
222// RejectPromise ( promise, reason )
223function RejectPromise(promise, r) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000224 // Check promise status to confirm that this reject has an effect.
225 // Call runtime for callbacks to the debugger or for unhandled reject.
Ben Murdochc5610432016-08-08 18:44:38 +0100226 if (GET_PRIVATE(promise, promiseStateSymbol) === kPending) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000227 var debug_is_active = DEBUG_IS_ACTIVE;
228 if (debug_is_active ||
229 !HAS_DEFINED_PRIVATE(promise, promiseHasHandlerSymbol)) {
230 %PromiseRejectEvent(promise, r, debug_is_active);
231 }
232 }
Ben Murdochc5610432016-08-08 18:44:38 +0100233 PromiseDone(promise, kRejected, r, promiseRejectReactionsSymbol)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000234}
235
Ben Murdochc5610432016-08-08 18:44:38 +0100236// ES#sec-newpromisecapability
237// NewPromiseCapability ( C )
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000238function NewPromiseCapability(C) {
239 if (C === GlobalPromise) {
240 // Optimized case, avoid extra closure.
241 var promise = PromiseInit(new GlobalPromise(promiseRawSymbol));
242 var callbacks = CreateResolvingFunctions(promise);
243 return {
244 promise: promise,
245 resolve: callbacks.resolve,
246 reject: callbacks.reject
247 };
248 }
249
250 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED };
251 result.promise = new C((resolve, reject) => {
252 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject))
253 throw MakeTypeError(kPromiseExecutorAlreadyInvoked);
254 result.resolve = resolve;
255 result.reject = reject;
256 });
257
Ben Murdochda12d292016-06-02 14:46:10 +0100258 if (!IS_CALLABLE(result.resolve) || !IS_CALLABLE(result.reject))
259 throw MakeTypeError(kPromiseNonCallable);
260
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000261 return result;
262}
263
Ben Murdochc5610432016-08-08 18:44:38 +0100264// Unspecified V8-specific legacy function
265function PromiseDefer() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000266 %IncrementUseCounter(kPromiseDefer);
267 return NewPromiseCapability(this);
268}
269
Ben Murdochc5610432016-08-08 18:44:38 +0100270// Unspecified V8-specific legacy function
271function PromiseAccept(x) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000272 %IncrementUseCounter(kPromiseAccept);
Ben Murdochc5610432016-08-08 18:44:38 +0100273 return %_Call(PromiseResolve, this, x);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000274}
275
Ben Murdochc5610432016-08-08 18:44:38 +0100276// ES#sec-promise.reject
277// Promise.reject ( x )
278function PromiseReject(r) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000279 if (!IS_RECEIVER(this)) {
Ben Murdochc5610432016-08-08 18:44:38 +0100280 throw MakeTypeError(kCalledOnNonObject, PromiseResolve);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000281 }
282 if (this === GlobalPromise) {
283 // Optimized case, avoid extra closure.
Ben Murdochc5610432016-08-08 18:44:38 +0100284 var promise = PromiseCreateAndSet(kRejected, r);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000285 // The debug event for this would always be an uncaught promise reject,
286 // which is usually simply noise. Do not trigger that debug event.
287 %PromiseRejectEvent(promise, r, false);
288 return promise;
289 } else {
290 var promiseCapability = NewPromiseCapability(this);
291 %_Call(promiseCapability.reject, UNDEFINED, r);
292 return promiseCapability.promise;
293 }
294}
295
Ben Murdochc5610432016-08-08 18:44:38 +0100296// Shortcut Promise.reject and Promise.resolve() implementations, used by
297// Async Functions implementation.
298function PromiseCreateRejected(r) {
299 return %_Call(PromiseReject, GlobalPromise, r);
300}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000301
Ben Murdochc5610432016-08-08 18:44:38 +0100302function PromiseCreateResolved(x) {
303 return %_Call(PromiseResolve, GlobalPromise, x);
304}
305
306// ES#sec-promise.prototype.then
307// Promise.prototype.then ( onFulfilled, onRejected )
308// Multi-unwrapped chaining with thenable coercion.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000309function PromiseThen(onResolve, onReject) {
Ben Murdochc5610432016-08-08 18:44:38 +0100310 var status = GET_PRIVATE(this, promiseStateSymbol);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000311 if (IS_UNDEFINED(status)) {
312 throw MakeTypeError(kNotAPromise, this);
313 }
314
315 var constructor = SpeciesConstructor(this, GlobalPromise);
316 onResolve = IS_CALLABLE(onResolve) ? onResolve : PromiseIdResolveHandler;
317 onReject = IS_CALLABLE(onReject) ? onReject : PromiseIdRejectHandler;
318 var deferred = NewPromiseCapability(constructor);
319 switch (status) {
Ben Murdochc5610432016-08-08 18:44:38 +0100320 case kPending:
321 GET_PRIVATE(this, promiseFulfillReactionsSymbol).push(onResolve,
322 deferred);
323 GET_PRIVATE(this, promiseRejectReactionsSymbol).push(onReject, deferred);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000324 break;
Ben Murdochc5610432016-08-08 18:44:38 +0100325 case kFulfilled:
326 PromiseEnqueue(GET_PRIVATE(this, promiseResultSymbol),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000327 [onResolve, deferred],
Ben Murdochc5610432016-08-08 18:44:38 +0100328 kFulfilled);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000329 break;
Ben Murdochc5610432016-08-08 18:44:38 +0100330 case kRejected:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000331 if (!HAS_DEFINED_PRIVATE(this, promiseHasHandlerSymbol)) {
332 // Promise has already been rejected, but had no handler.
333 // Revoke previously triggered reject event.
334 %PromiseRevokeReject(this);
335 }
Ben Murdochc5610432016-08-08 18:44:38 +0100336 PromiseEnqueue(GET_PRIVATE(this, promiseResultSymbol),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000337 [onReject, deferred],
Ben Murdochc5610432016-08-08 18:44:38 +0100338 kRejected);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000339 break;
340 }
341 // Mark this promise as having handler.
342 SET_PRIVATE(this, promiseHasHandlerSymbol, true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000343 return deferred.promise;
344}
345
Ben Murdochc5610432016-08-08 18:44:38 +0100346// Unspecified V8-specific legacy function
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000347// Chain is left around for now as an alias for then
348function PromiseChain(onResolve, onReject) {
349 %IncrementUseCounter(kPromiseChain);
350 return %_Call(PromiseThen, this, onResolve, onReject);
351}
352
Ben Murdochc5610432016-08-08 18:44:38 +0100353// ES#sec-promise.prototype.catch
354// Promise.prototype.catch ( onRejected )
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000355function PromiseCatch(onReject) {
356 return this.then(UNDEFINED, onReject);
357}
358
359// Combinators.
360
Ben Murdochc5610432016-08-08 18:44:38 +0100361// ES#sec-promise.resolve
362// Promise.resolve ( x )
363function PromiseResolve(x) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000364 if (!IS_RECEIVER(this)) {
Ben Murdochc5610432016-08-08 18:44:38 +0100365 throw MakeTypeError(kCalledOnNonObject, PromiseResolve);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000366 }
367 if (IsPromise(x) && x.constructor === this) return x;
368
369 var promiseCapability = NewPromiseCapability(this);
370 var resolveResult = %_Call(promiseCapability.resolve, UNDEFINED, x);
371 return promiseCapability.promise;
372}
373
Ben Murdochc5610432016-08-08 18:44:38 +0100374// ES#sec-promise.all
375// Promise.all ( iterable )
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000376function PromiseAll(iterable) {
377 if (!IS_RECEIVER(this)) {
378 throw MakeTypeError(kCalledOnNonObject, "Promise.all");
379 }
380
381 var deferred = NewPromiseCapability(this);
382 var resolutions = new InternalArray();
383 var count;
384
385 function CreateResolveElementFunction(index, values, promiseCapability) {
386 var alreadyCalled = false;
387 return (x) => {
388 if (alreadyCalled === true) return;
389 alreadyCalled = true;
390 values[index] = x;
391 if (--count === 0) {
392 var valuesArray = [];
393 %MoveArrayContents(values, valuesArray);
394 %_Call(promiseCapability.resolve, UNDEFINED, valuesArray);
395 }
396 };
397 }
398
399 try {
400 var i = 0;
401 count = 1;
402 for (var value of iterable) {
403 var nextPromise = this.resolve(value);
404 ++count;
405 nextPromise.then(
406 CreateResolveElementFunction(i, resolutions, deferred),
407 deferred.reject);
408 SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred);
409 ++i;
410 }
411
412 // 6.d
413 if (--count === 0) {
414 var valuesArray = [];
415 %MoveArrayContents(resolutions, valuesArray);
416 %_Call(deferred.resolve, UNDEFINED, valuesArray);
417 }
418
419 } catch (e) {
420 %_Call(deferred.reject, UNDEFINED, e);
421 }
422 return deferred.promise;
423}
424
Ben Murdochc5610432016-08-08 18:44:38 +0100425// ES#sec-promise.race
426// Promise.race ( iterable )
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000427function PromiseRace(iterable) {
428 if (!IS_RECEIVER(this)) {
429 throw MakeTypeError(kCalledOnNonObject, PromiseRace);
430 }
431
432 var deferred = NewPromiseCapability(this);
433 try {
434 for (var value of iterable) {
435 this.resolve(value).then(deferred.resolve, deferred.reject);
436 SET_PRIVATE(deferred.reject, promiseCombinedDeferredSymbol, deferred);
437 }
438 } catch (e) {
439 deferred.reject(e)
440 }
441 return deferred.promise;
442}
443
444
445// Utility for debugger
446
447function PromiseHasUserDefinedRejectHandlerRecursive(promise) {
Ben Murdochc5610432016-08-08 18:44:38 +0100448 var queue = GET_PRIVATE(promise, promiseRejectReactionsSymbol);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000449 if (IS_UNDEFINED(queue)) return false;
450 for (var i = 0; i < queue.length; i += 2) {
451 var handler = queue[i];
452 if (handler !== PromiseIdRejectHandler) {
453 var deferred = GET_PRIVATE(handler, promiseCombinedDeferredSymbol);
454 if (IS_UNDEFINED(deferred)) return true;
455 if (PromiseHasUserDefinedRejectHandlerRecursive(deferred.promise)) {
456 return true;
457 }
458 } else if (PromiseHasUserDefinedRejectHandlerRecursive(
459 queue[i + 1].promise)) {
460 return true;
461 }
462 }
463 return false;
464}
465
466// Return whether the promise will be handled by a user-defined reject
467// handler somewhere down the promise chain. For this, we do a depth-first
468// search for a reject handler that's not the default PromiseIdRejectHandler.
469function PromiseHasUserDefinedRejectHandler() {
470 return PromiseHasUserDefinedRejectHandlerRecursive(this);
471};
472
473// -------------------------------------------------------------------
474// Install exported functions.
475
476%AddNamedProperty(global, 'Promise', GlobalPromise, DONT_ENUM);
477%AddNamedProperty(GlobalPromise.prototype, toStringTagSymbol, "Promise",
478 DONT_ENUM | READ_ONLY);
479
480utils.InstallFunctions(GlobalPromise, DONT_ENUM, [
Ben Murdochc5610432016-08-08 18:44:38 +0100481 "reject", PromiseReject,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000482 "all", PromiseAll,
483 "race", PromiseRace,
Ben Murdochc5610432016-08-08 18:44:38 +0100484 "resolve", PromiseResolve
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000485]);
486
487utils.InstallFunctions(GlobalPromise.prototype, DONT_ENUM, [
488 "then", PromiseThen,
489 "catch", PromiseCatch
490]);
491
492%InstallToContext([
493 "promise_catch", PromiseCatch,
494 "promise_chain", PromiseChain,
495 "promise_create", PromiseCreate,
496 "promise_has_user_defined_reject_handler", PromiseHasUserDefinedRejectHandler,
Ben Murdochc5610432016-08-08 18:44:38 +0100497 "promise_reject", RejectPromise,
498 "promise_resolve", FulfillPromise,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000499 "promise_then", PromiseThen,
Ben Murdochc5610432016-08-08 18:44:38 +0100500 "promise_create_rejected", PromiseCreateRejected,
501 "promise_create_resolved", PromiseCreateResolved
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000502]);
503
504// This allows extras to create promises quickly without building extra
505// resolve/reject closures, and allows them to later resolve and reject any
506// promise without having to hold on to those closures forever.
507utils.InstallFunctions(extrasUtils, 0, [
508 "createPromise", PromiseCreate,
Ben Murdochc5610432016-08-08 18:44:38 +0100509 "resolvePromise", FulfillPromise,
510 "rejectPromise", RejectPromise
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000511]);
512
513// TODO(v8:4567): Allow experimental natives to remove function prototype
Ben Murdochc5610432016-08-08 18:44:38 +0100514[PromiseChain, PromiseDefer, PromiseAccept].forEach(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000515 fn => %FunctionRemovePrototype(fn));
516
517utils.Export(function(to) {
518 to.PromiseChain = PromiseChain;
Ben Murdochc5610432016-08-08 18:44:38 +0100519 to.PromiseDefer = PromiseDefer;
520 to.PromiseAccept = PromiseAccept;
521
522 to.PromiseCreateRejected = PromiseCreateRejected;
523 to.PromiseCreateResolved = PromiseCreateResolved;
524 to.PromiseThen = PromiseThen;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000525});
526
527})