aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/promise.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/promise.js')
-rw-r--r--deps/v8/src/promise.js673
1 files changed, 337 insertions, 336 deletions
diff --git a/deps/v8/src/promise.js b/deps/v8/src/promise.js
index c7bd204bb0..b0d1aa088b 100644
--- a/deps/v8/src/promise.js
+++ b/deps/v8/src/promise.js
@@ -2,28 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-"use strict";
-
-// This file relies on the fact that the following declaration has been made
-// in runtime.js:
-// var $Object = global.Object
-// var $WeakMap = global.WeakMap
+var $promiseCreate;
+var $promiseResolve;
+var $promiseReject;
+var $promiseChain;
+var $promiseCatch;
+var $promiseThen;
+var $promiseHasUserDefinedRejectHandler;
+var $promiseStatus;
+var $promiseValue;
+
+(function(global, shared, exports) {
-// For bootstrapper.
+"use strict";
-var IsPromise;
-var PromiseCreate;
-var PromiseResolve;
-var PromiseReject;
-var PromiseChain;
-var PromiseCatch;
-var PromiseThen;
-var PromiseHasRejectHandler;
-var PromiseHasUserDefinedRejectHandler;
+%CheckIsBootstrapping();
-// mirror-debugger.js currently uses builtins.promiseStatus. It would be nice
-// if we could move these property names into the closure below.
-// TODO(jkummerow/rossberg/yangguo): Find a better solution.
+// -------------------------------------------------------------------
// Status values: 0 = pending, +1 = resolved, -1 = rejected
var promiseStatus = GLOBAL_PRIVATE("Promise#status");
@@ -34,360 +29,366 @@ var promiseRaw = GLOBAL_PRIVATE("Promise#raw");
var promiseHasHandler = %PromiseHasHandlerSymbol();
var lastMicrotaskId = 0;
-
-(function() {
-
- var $Promise = function Promise(resolver) {
- if (resolver === promiseRaw) return;
- if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]);
- if (!IS_SPEC_FUNCTION(resolver))
- throw MakeTypeError('resolver_not_a_function', [resolver]);
- var promise = PromiseInit(this);
- try {
- %DebugPushPromise(promise, Promise);
- resolver(function(x) { PromiseResolve(promise, x) },
- function(r) { PromiseReject(promise, r) });
- } catch (e) {
- PromiseReject(promise, e);
- } finally {
- %DebugPopPromise();
- }
+var GlobalPromise = function Promise(resolver) {
+ if (resolver === promiseRaw) return;
+ if (!%_IsConstructCall()) throw MakeTypeError(kNotAPromise, this);
+ if (!IS_SPEC_FUNCTION(resolver))
+ throw MakeTypeError(kResolverNotAFunction, resolver);
+ var promise = PromiseInit(this);
+ try {
+ %DebugPushPromise(promise, Promise);
+ resolver(function(x) { PromiseResolve(promise, x) },
+ function(r) { PromiseReject(promise, r) });
+ } catch (e) {
+ PromiseReject(promise, e);
+ } finally {
+ %DebugPopPromise();
}
+}
- // Core functionality.
+// Core functionality.
- function PromiseSet(promise, status, value, onResolve, onReject) {
- SET_PRIVATE(promise, promiseStatus, status);
- SET_PRIVATE(promise, promiseValue, value);
- SET_PRIVATE(promise, promiseOnResolve, onResolve);
- SET_PRIVATE(promise, promiseOnReject, onReject);
- if (DEBUG_IS_ACTIVE) {
- %DebugPromiseEvent({ promise: promise, status: status, value: value });
- }
- return promise;
- }
-
- function PromiseCreateAndSet(status, value) {
- var promise = new $Promise(promiseRaw);
- // If debug is active, notify about the newly created promise first.
- if (DEBUG_IS_ACTIVE) PromiseSet(promise, 0, UNDEFINED);
- return PromiseSet(promise, status, value);
+function PromiseSet(promise, status, value, onResolve, onReject) {
+ SET_PRIVATE(promise, promiseStatus, status);
+ SET_PRIVATE(promise, promiseValue, value);
+ SET_PRIVATE(promise, promiseOnResolve, onResolve);
+ SET_PRIVATE(promise, promiseOnReject, onReject);
+ if (DEBUG_IS_ACTIVE) {
+ %DebugPromiseEvent({ promise: promise, status: status, value: value });
}
-
- function PromiseInit(promise) {
- return PromiseSet(
- promise, 0, UNDEFINED, new InternalArray, new InternalArray)
+ return promise;
+}
+
+function PromiseCreateAndSet(status, value) {
+ var promise = new GlobalPromise(promiseRaw);
+ // If debug is active, notify about the newly created promise first.
+ if (DEBUG_IS_ACTIVE) PromiseSet(promise, 0, UNDEFINED);
+ return PromiseSet(promise, status, value);
+}
+
+function PromiseInit(promise) {
+ return PromiseSet(
+ promise, 0, UNDEFINED, new InternalArray, new InternalArray)
+}
+
+function PromiseDone(promise, status, value, promiseQueue) {
+ if (GET_PRIVATE(promise, promiseStatus) === 0) {
+ var tasks = GET_PRIVATE(promise, promiseQueue);
+ if (tasks.length) PromiseEnqueue(value, tasks, status);
+ PromiseSet(promise, status, value);
}
+}
- function PromiseDone(promise, status, value, promiseQueue) {
- if (GET_PRIVATE(promise, promiseStatus) === 0) {
- var tasks = GET_PRIVATE(promise, promiseQueue);
- if (tasks.length) PromiseEnqueue(value, tasks, status);
- PromiseSet(promise, status, value);
+function PromiseCoerce(constructor, x) {
+ if (!IsPromise(x) && IS_SPEC_OBJECT(x)) {
+ var then;
+ try {
+ then = x.then;
+ } catch(r) {
+ return %_CallFunction(constructor, r, PromiseRejected);
}
- }
-
- function PromiseCoerce(constructor, x) {
- if (!IsPromise(x) && IS_SPEC_OBJECT(x)) {
- var then;
+ if (IS_SPEC_FUNCTION(then)) {
+ var deferred = %_CallFunction(constructor, PromiseDeferred);
try {
- then = x.then;
+ %_CallFunction(x, deferred.resolve, deferred.reject, then);
} catch(r) {
- return %_CallFunction(constructor, r, PromiseRejected);
- }
- if (IS_SPEC_FUNCTION(then)) {
- var deferred = %_CallFunction(constructor, PromiseDeferred);
- try {
- %_CallFunction(x, deferred.resolve, deferred.reject, then);
- } catch(r) {
- deferred.reject(r);
- }
- return deferred.promise;
+ deferred.reject(r);
}
+ return deferred.promise;
}
- return x;
}
-
- function PromiseHandle(value, handler, deferred) {
- try {
- %DebugPushPromise(deferred.promise, PromiseHandle);
- DEBUG_PREPARE_STEP_IN_IF_STEPPING(handler);
- var result = handler(value);
- if (result === deferred.promise)
- throw MakeTypeError('promise_cyclic', [result]);
- else if (IsPromise(result))
- %_CallFunction(result, deferred.resolve, deferred.reject, PromiseChain);
- else
- deferred.resolve(result);
- } catch (exception) {
- try { deferred.reject(exception); } catch (e) { }
- } finally {
- %DebugPopPromise();
- }
+ return x;
+}
+
+function PromiseHandle(value, handler, deferred) {
+ try {
+ %DebugPushPromise(deferred.promise, PromiseHandle);
+ DEBUG_PREPARE_STEP_IN_IF_STEPPING(handler);
+ var result = handler(value);
+ if (result === deferred.promise)
+ throw MakeTypeError(kPromiseCyclic, result);
+ else if (IsPromise(result))
+ %_CallFunction(result, deferred.resolve, deferred.reject, PromiseChain);
+ else
+ deferred.resolve(result);
+ } catch (exception) {
+ try { deferred.reject(exception); } catch (e) { }
+ } finally {
+ %DebugPopPromise();
}
+}
- function PromiseEnqueue(value, tasks, status) {
- var id, name, instrumenting = DEBUG_IS_ACTIVE;
- %EnqueueMicrotask(function() {
- if (instrumenting) {
- %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
- }
- for (var i = 0; i < tasks.length; i += 2) {
- PromiseHandle(value, tasks[i], tasks[i + 1])
- }
- if (instrumenting) {
- %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
- }
- });
+function PromiseEnqueue(value, tasks, status) {
+ var id, name, instrumenting = DEBUG_IS_ACTIVE;
+ %EnqueueMicrotask(function() {
if (instrumenting) {
- id = ++lastMicrotaskId;
- name = status > 0 ? "Promise.resolve" : "Promise.reject";
- %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
+ %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
}
+ for (var i = 0; i < tasks.length; i += 2) {
+ PromiseHandle(value, tasks[i], tasks[i + 1])
+ }
+ if (instrumenting) {
+ %DebugAsyncTaskEvent({ type: "didHandle", id: id, name: name });
+ }
+ });
+ if (instrumenting) {
+ id = ++lastMicrotaskId;
+ name = status > 0 ? "Promise.resolve" : "Promise.reject";
+ %DebugAsyncTaskEvent({ type: "enqueue", id: id, name: name });
}
+}
- function PromiseIdResolveHandler(x) { return x }
- function PromiseIdRejectHandler(r) { throw r }
-
- function PromiseNopResolver() {}
-
- // -------------------------------------------------------------------
- // Define exported functions.
-
- // For bootstrapper.
-
- IsPromise = function IsPromise(x) {
- return IS_SPEC_OBJECT(x) && HAS_DEFINED_PRIVATE(x, promiseStatus);
- }
-
- PromiseCreate = function PromiseCreate() {
- return new $Promise(PromiseNopResolver)
- }
+function PromiseIdResolveHandler(x) { return x }
+function PromiseIdRejectHandler(r) { throw r }
- PromiseResolve = function PromiseResolve(promise, x) {
- PromiseDone(promise, +1, x, promiseOnResolve)
- }
+function PromiseNopResolver() {}
- PromiseReject = function PromiseReject(promise, r) {
- // Check promise status to confirm that this reject has an effect.
- // Call runtime for callbacks to the debugger or for unhandled reject.
- if (GET_PRIVATE(promise, promiseStatus) == 0) {
- var debug_is_active = DEBUG_IS_ACTIVE;
- if (debug_is_active || !HAS_DEFINED_PRIVATE(promise, promiseHasHandler)) {
- %PromiseRejectEvent(promise, r, debug_is_active);
- }
- }
- PromiseDone(promise, -1, r, promiseOnReject)
- }
+// -------------------------------------------------------------------
+// Define exported functions.
- // Convenience.
-
- function PromiseDeferred() {
- if (this === $Promise) {
- // Optimized case, avoid extra closure.
- var promise = PromiseInit(new $Promise(promiseRaw));
- return {
- promise: promise,
- resolve: function(x) { PromiseResolve(promise, x) },
- reject: function(r) { PromiseReject(promise, r) }
- };
- } else {
- var result = {};
- result.promise = new this(function(resolve, reject) {
- result.resolve = resolve;
- result.reject = reject;
- })
- return result;
- }
- }
+// For bootstrapper.
- function PromiseResolved(x) {
- if (this === $Promise) {
- // Optimized case, avoid extra closure.
- return PromiseCreateAndSet(+1, x);
- } else {
- return new this(function(resolve, reject) { resolve(x) });
+function IsPromise(x) {
+ return IS_SPEC_OBJECT(x) && HAS_DEFINED_PRIVATE(x, promiseStatus);
+}
+
+function PromiseCreate() {
+ return new GlobalPromise(PromiseNopResolver)
+}
+
+function PromiseResolve(promise, x) {
+ PromiseDone(promise, +1, x, promiseOnResolve)
+}
+
+function PromiseReject(promise, r) {
+ // Check promise status to confirm that this reject has an effect.
+ // Call runtime for callbacks to the debugger or for unhandled reject.
+ if (GET_PRIVATE(promise, promiseStatus) == 0) {
+ var debug_is_active = DEBUG_IS_ACTIVE;
+ if (debug_is_active || !HAS_DEFINED_PRIVATE(promise, promiseHasHandler)) {
+ %PromiseRejectEvent(promise, r, debug_is_active);
}
}
-
- function PromiseRejected(r) {
- var promise;
- if (this === $Promise) {
- // Optimized case, avoid extra closure.
- promise = PromiseCreateAndSet(-1, r);
- // The debug event for this would always be an uncaught promise reject,
- // which is usually simply noise. Do not trigger that debug event.
- %PromiseRejectEvent(promise, r, false);
- } else {
- promise = new this(function(resolve, reject) { reject(r) });
- }
- return promise;
+ PromiseDone(promise, -1, r, promiseOnReject)
+}
+
+// Convenience.
+
+function PromiseDeferred() {
+ if (this === GlobalPromise) {
+ // Optimized case, avoid extra closure.
+ var promise = PromiseInit(new GlobalPromise(promiseRaw));
+ return {
+ promise: promise,
+ resolve: function(x) { PromiseResolve(promise, x) },
+ reject: function(r) { PromiseReject(promise, r) }
+ };
+ } else {
+ var result = {};
+ result.promise = new this(function(resolve, reject) {
+ result.resolve = resolve;
+ result.reject = reject;
+ })
+ return result;
}
-
- // Simple chaining.
-
- PromiseChain = function PromiseChain(onResolve, onReject) { // a.k.a.
- // flatMap
- onResolve = IS_UNDEFINED(onResolve) ? PromiseIdResolveHandler : onResolve;
- onReject = IS_UNDEFINED(onReject) ? PromiseIdRejectHandler : onReject;
- var deferred = %_CallFunction(this.constructor, PromiseDeferred);
- switch (GET_PRIVATE(this, promiseStatus)) {
- case UNDEFINED:
- throw MakeTypeError('not_a_promise', [this]);
- case 0: // Pending
- GET_PRIVATE(this, promiseOnResolve).push(onResolve, deferred);
- GET_PRIVATE(this, promiseOnReject).push(onReject, deferred);
- break;
- case +1: // Resolved
- PromiseEnqueue(GET_PRIVATE(this, promiseValue),
- [onResolve, deferred],
- +1);
- break;
- case -1: // Rejected
- if (!HAS_DEFINED_PRIVATE(this, promiseHasHandler)) {
- // Promise has already been rejected, but had no handler.
- // Revoke previously triggered reject event.
- %PromiseRevokeReject(this);
- }
- PromiseEnqueue(GET_PRIVATE(this, promiseValue),
- [onReject, deferred],
- -1);
- break;
- }
- // Mark this promise as having handler.
- SET_PRIVATE(this, promiseHasHandler, true);
- if (DEBUG_IS_ACTIVE) {
- %DebugPromiseEvent({ promise: deferred.promise, parentPromise: this });
- }
- return deferred.promise;
+}
+
+function PromiseResolved(x) {
+ if (this === GlobalPromise) {
+ // Optimized case, avoid extra closure.
+ return PromiseCreateAndSet(+1, x);
+ } else {
+ return new this(function(resolve, reject) { resolve(x) });
}
-
- PromiseCatch = function PromiseCatch(onReject) {
- return this.then(UNDEFINED, onReject);
+}
+
+function PromiseRejected(r) {
+ var promise;
+ if (this === GlobalPromise) {
+ // Optimized case, avoid extra closure.
+ promise = PromiseCreateAndSet(-1, r);
+ // The debug event for this would always be an uncaught promise reject,
+ // which is usually simply noise. Do not trigger that debug event.
+ %PromiseRejectEvent(promise, r, false);
+ } else {
+ promise = new this(function(resolve, reject) { reject(r) });
}
-
- // Multi-unwrapped chaining with thenable coercion.
-
- PromiseThen = function PromiseThen(onResolve, onReject) {
- onResolve = IS_SPEC_FUNCTION(onResolve) ? onResolve
- : PromiseIdResolveHandler;
- onReject = IS_SPEC_FUNCTION(onReject) ? onReject
- : PromiseIdRejectHandler;
- var that = this;
- var constructor = this.constructor;
- return %_CallFunction(
- this,
- function(x) {
- x = PromiseCoerce(constructor, x);
- if (x === that) {
- DEBUG_PREPARE_STEP_IN_IF_STEPPING(onReject);
- return onReject(MakeTypeError('promise_cyclic', [x]));
- } else if (IsPromise(x)) {
- return x.then(onResolve, onReject);
- } else {
- DEBUG_PREPARE_STEP_IN_IF_STEPPING(onResolve);
- return onResolve(x);
- }
- },
- onReject,
- PromiseChain
- );
+ return promise;
+}
+
+// Simple chaining.
+
+function PromiseChain(onResolve, onReject) { // a.k.a. flatMap
+ onResolve = IS_UNDEFINED(onResolve) ? PromiseIdResolveHandler : onResolve;
+ onReject = IS_UNDEFINED(onReject) ? PromiseIdRejectHandler : onReject;
+ var deferred = %_CallFunction(this.constructor, PromiseDeferred);
+ switch (GET_PRIVATE(this, promiseStatus)) {
+ case UNDEFINED:
+ throw MakeTypeError(kNotAPromise, this);
+ case 0: // Pending
+ GET_PRIVATE(this, promiseOnResolve).push(onResolve, deferred);
+ GET_PRIVATE(this, promiseOnReject).push(onReject, deferred);
+ break;
+ case +1: // Resolved
+ PromiseEnqueue(GET_PRIVATE(this, promiseValue),
+ [onResolve, deferred],
+ +1);
+ break;
+ case -1: // Rejected
+ if (!HAS_DEFINED_PRIVATE(this, promiseHasHandler)) {
+ // Promise has already been rejected, but had no handler.
+ // Revoke previously triggered reject event.
+ %PromiseRevokeReject(this);
+ }
+ PromiseEnqueue(GET_PRIVATE(this, promiseValue),
+ [onReject, deferred],
+ -1);
+ break;
}
-
- // Combinators.
-
- function PromiseCast(x) {
- // TODO(rossberg): cannot do better until we support @@create.
- return IsPromise(x) ? x : new this(function(resolve) { resolve(x) });
+ // Mark this promise as having handler.
+ SET_PRIVATE(this, promiseHasHandler, true);
+ if (DEBUG_IS_ACTIVE) {
+ %DebugPromiseEvent({ promise: deferred.promise, parentPromise: this });
}
-
- function PromiseAll(iterable) {
- var deferred = %_CallFunction(this, PromiseDeferred);
- var resolutions = [];
- try {
- var count = 0;
- var i = 0;
- for (var value of iterable) {
- this.resolve(value).then(
- // Nested scope to get closure over current i.
- // TODO(arv): Use an inner let binding once available.
- (function(i) {
- return function(x) {
- resolutions[i] = x;
- if (--count === 0) deferred.resolve(resolutions);
- }
- })(i),
- function(r) { deferred.reject(r); });
- ++i;
- ++count;
- }
-
- if (count === 0) {
- deferred.resolve(resolutions);
+ return deferred.promise;
+}
+
+function PromiseCatch(onReject) {
+ return this.then(UNDEFINED, onReject);
+}
+
+// Multi-unwrapped chaining with thenable coercion.
+
+function PromiseThen(onResolve, onReject) {
+ onResolve = IS_SPEC_FUNCTION(onResolve) ? onResolve
+ : PromiseIdResolveHandler;
+ onReject = IS_SPEC_FUNCTION(onReject) ? onReject
+ : PromiseIdRejectHandler;
+ var that = this;
+ var constructor = this.constructor;
+ return %_CallFunction(
+ this,
+ function(x) {
+ x = PromiseCoerce(constructor, x);
+ if (x === that) {
+ DEBUG_PREPARE_STEP_IN_IF_STEPPING(onReject);
+ return onReject(MakeTypeError(kPromiseCyclic, x));
+ } else if (IsPromise(x)) {
+ return x.then(onResolve, onReject);
+ } else {
+ DEBUG_PREPARE_STEP_IN_IF_STEPPING(onResolve);
+ return onResolve(x);
}
+ },
+ onReject,
+ PromiseChain
+ );
+}
+
+// Combinators.
+
+function PromiseCast(x) {
+ // TODO(rossberg): cannot do better until we support @@create.
+ return IsPromise(x) ? x : new this(function(resolve) { resolve(x) });
+}
+
+function PromiseAll(iterable) {
+ var deferred = %_CallFunction(this, PromiseDeferred);
+ var resolutions = [];
+ try {
+ var count = 0;
+ var i = 0;
+ for (var value of iterable) {
+ this.resolve(value).then(
+ // Nested scope to get closure over current i.
+ // TODO(arv): Use an inner let binding once available.
+ (function(i) {
+ return function(x) {
+ resolutions[i] = x;
+ if (--count === 0) deferred.resolve(resolutions);
+ }
+ })(i),
+ function(r) { deferred.reject(r); });
+ ++i;
+ ++count;
+ }
- } catch (e) {
- deferred.reject(e)
+ if (count === 0) {
+ deferred.resolve(resolutions);
}
- return deferred.promise;
- }
- function PromiseRace(iterable) {
- var deferred = %_CallFunction(this, PromiseDeferred);
- try {
- for (var value of iterable) {
- this.resolve(value).then(
- function(x) { deferred.resolve(x) },
- function(r) { deferred.reject(r) });
- }
- } catch (e) {
- deferred.reject(e)
+ } catch (e) {
+ deferred.reject(e)
+ }
+ return deferred.promise;
+}
+
+function PromiseRace(iterable) {
+ var deferred = %_CallFunction(this, PromiseDeferred);
+ try {
+ for (var value of iterable) {
+ this.resolve(value).then(
+ function(x) { deferred.resolve(x) },
+ function(r) { deferred.reject(r) });
}
- return deferred.promise;
+ } catch (e) {
+ deferred.reject(e)
}
+ return deferred.promise;
+}
- // Utility for debugger
+// Utility for debugger
- function PromiseHasUserDefinedRejectHandlerRecursive(promise) {
- var queue = GET_PRIVATE(promise, promiseOnReject);
- if (IS_UNDEFINED(queue)) return false;
- for (var i = 0; i < queue.length; i += 2) {
- if (queue[i] != PromiseIdRejectHandler) return true;
- if (PromiseHasUserDefinedRejectHandlerRecursive(queue[i + 1].promise)) {
- return true;
- }
+function PromiseHasUserDefinedRejectHandlerRecursive(promise) {
+ var queue = GET_PRIVATE(promise, promiseOnReject);
+ if (IS_UNDEFINED(queue)) return false;
+ for (var i = 0; i < queue.length; i += 2) {
+ if (queue[i] != PromiseIdRejectHandler) return true;
+ if (PromiseHasUserDefinedRejectHandlerRecursive(queue[i + 1].promise)) {
+ return true;
}
- return false;
}
-
- // Return whether the promise will be handled by a user-defined reject
- // handler somewhere down the promise chain. For this, we do a depth-first
- // search for a reject handler that's not the default PromiseIdRejectHandler.
- PromiseHasUserDefinedRejectHandler =
- function PromiseHasUserDefinedRejectHandler() {
- return PromiseHasUserDefinedRejectHandlerRecursive(this);
- };
-
- // -------------------------------------------------------------------
- // Install exported functions.
-
- %CheckIsBootstrapping();
- %AddNamedProperty(global, 'Promise', $Promise, DONT_ENUM);
- %AddNamedProperty(
- $Promise.prototype, symbolToStringTag, "Promise", DONT_ENUM | READ_ONLY);
- InstallFunctions($Promise, DONT_ENUM, [
- "defer", PromiseDeferred,
- "accept", PromiseResolved,
- "reject", PromiseRejected,
- "all", PromiseAll,
- "race", PromiseRace,
- "resolve", PromiseCast
- ]);
- InstallFunctions($Promise.prototype, DONT_ENUM, [
- "chain", PromiseChain,
- "then", PromiseThen,
- "catch", PromiseCatch
- ]);
-
-})();
+ return false;
+}
+
+// Return whether the promise will be handled by a user-defined reject
+// handler somewhere down the promise chain. For this, we do a depth-first
+// search for a reject handler that's not the default PromiseIdRejectHandler.
+function PromiseHasUserDefinedRejectHandler() {
+ return PromiseHasUserDefinedRejectHandlerRecursive(this);
+};
+
+// -------------------------------------------------------------------
+// Install exported functions.
+
+%AddNamedProperty(global, 'Promise', GlobalPromise, DONT_ENUM);
+%AddNamedProperty(GlobalPromise.prototype, symbolToStringTag, "Promise",
+ DONT_ENUM | READ_ONLY);
+
+$installFunctions(GlobalPromise, DONT_ENUM, [
+ "defer", PromiseDeferred,
+ "accept", PromiseResolved,
+ "reject", PromiseRejected,
+ "all", PromiseAll,
+ "race", PromiseRace,
+ "resolve", PromiseCast
+]);
+
+$installFunctions(GlobalPromise.prototype, DONT_ENUM, [
+ "chain", PromiseChain,
+ "then", PromiseThen,
+ "catch", PromiseCatch
+]);
+
+$promiseCreate = PromiseCreate;
+$promiseResolve = PromiseResolve;
+$promiseReject = PromiseReject;
+$promiseChain = PromiseChain;
+$promiseCatch = PromiseCatch;
+$promiseThen = PromiseThen;
+$promiseHasUserDefinedRejectHandler = PromiseHasUserDefinedRejectHandler;
+$promiseStatus = promiseStatus;
+$promiseValue = promiseValue;
+
+})