630 lines
30 KiB
JavaScript
630 lines
30 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /**
|
|
* Copyright (c) 2017-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
exports.EnqueueJob = EnqueueJob;
|
|
exports.NewPromiseCapability = NewPromiseCapability;
|
|
exports.PerformPromiseAll = PerformPromiseAll;
|
|
exports.PerformPromiseRace = PerformPromiseRace;
|
|
exports.PerformPromiseThen = PerformPromiseThen;
|
|
exports.PromiseReactionJob = PromiseReactionJob;
|
|
exports.CreateResolvingFunctions = CreateResolvingFunctions;
|
|
exports.FulfillPromise = FulfillPromise;
|
|
exports.RejectPromise = RejectPromise;
|
|
exports.TriggerPromiseReactions = TriggerPromiseReactions;
|
|
exports.HostPromiseRejectionTracker = HostPromiseRejectionTracker;
|
|
exports.PromiseResolveThenableJob = PromiseResolveThenableJob;
|
|
|
|
var _completions = require("../completions.js");
|
|
|
|
var _index = require("../values/index.js");
|
|
|
|
var _abstract = require("../methods/abstract.js");
|
|
|
|
var _construct = require("../methods/construct.js");
|
|
|
|
var _get = require("../methods/get.js");
|
|
|
|
var _call = require("../methods/call.js");
|
|
|
|
var _is = require("../methods/is.js");
|
|
|
|
var _iterator2 = require("../methods/iterator.js");
|
|
|
|
var _singletons = require("../singletons.js");
|
|
|
|
var _invariant = require("../invariant.js");
|
|
|
|
var _invariant2 = _interopRequireDefault(_invariant);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
// ECMA262 8.4.1
|
|
function EnqueueJob(realm, queueName, job, args) {}
|
|
|
|
// ECMA262 25.4.1.5
|
|
function NewPromiseCapability(realm, C) {
|
|
// 1. If IsConstructor(C) is false, throw a TypeError exception.
|
|
if ((0, _is.IsConstructor)(realm, C) === false) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "IsConstructor(C) is false");
|
|
}
|
|
(0, _invariant2.default)(C instanceof _index.ObjectValue);
|
|
|
|
// 2. NOTE C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 25.4.3.1).
|
|
|
|
// 3. Let promiseCapability be a new PromiseCapability { [[Promise]]: undefined, [[Resolve]]: undefined, [[Reject]]: undefined }.
|
|
var promiseCapability = {
|
|
promise: realm.intrinsics.undefined,
|
|
resolve: realm.intrinsics.undefined,
|
|
reject: realm.intrinsics.undefined
|
|
};
|
|
|
|
// 4. Let executor be a new built-in function object as defined in GetCapabilitiesExecutor Functions (25.4.1.5.1).
|
|
var executor = new _index.NativeFunctionValue(realm, undefined, undefined, 2, function (context, _ref) {
|
|
var _ref2 = _slicedToArray(_ref, 2),
|
|
resolve = _ref2[0],
|
|
reject = _ref2[1];
|
|
|
|
// 1. Assert: F has a [[Capability]] internal slot whose value is a PromiseCapability Record.
|
|
(0, _invariant2.default)(executor.$Capability, "F has a [[Capability]] internal slot whose value is a PromiseCapability Record");
|
|
|
|
// 2. Let promiseCapability be the value of F's [[Capability]] internal slot.
|
|
(0, _invariant2.default)(promiseCapability === executor.$Capability);
|
|
|
|
// 3. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
|
|
if (!promiseCapability.resolve.mightBeUndefined()) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "promiseCapability.[[Resolve]] is not undefined");
|
|
}
|
|
promiseCapability.resolve.throwIfNotConcrete();
|
|
|
|
// 4. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
|
|
if (!promiseCapability.reject.mightBeUndefined()) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "promiseCapability.[[Reject]] is not undefined");
|
|
}
|
|
promiseCapability.reject.throwIfNotConcrete();
|
|
|
|
// 5. Set promiseCapability.[[Resolve]] to resolve.
|
|
promiseCapability.resolve = resolve;
|
|
|
|
// 6. Set promiseCapability.[[Reject]] to reject.
|
|
promiseCapability.reject = reject;
|
|
|
|
// 7. Return undefined.
|
|
return realm.intrinsics.undefined;
|
|
}, false);
|
|
|
|
// 5. Set the [[Capability]] internal slot of executor to promiseCapability.
|
|
executor.$Capability = promiseCapability;
|
|
|
|
// 6. Let promise be ? Construct(C, « executor »).
|
|
var promise = (0, _construct.Construct)(realm, C, [executor]);
|
|
|
|
// 7. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
|
|
if ((0, _is.IsCallable)(realm, promiseCapability.resolve) === false) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "IsCallable(promiseCapability.[[Resolve]]) is false");
|
|
}
|
|
|
|
// 8. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
|
|
if ((0, _is.IsCallable)(realm, promiseCapability.reject) === false) {
|
|
throw realm.createErrorThrowCompletion(realm.intrinsics.TypeError, "IsCallable(promiseCapability.[[Reject]]) is false");
|
|
}
|
|
|
|
// 9. Set promiseCapability.[[Promise]] to promise.
|
|
promiseCapability.promise = promise;
|
|
|
|
// 10. Return promiseCapability.
|
|
return promiseCapability;
|
|
}
|
|
|
|
// ECMA262 25.4.4.1.1j
|
|
function createResolveElementFunction(realm) {
|
|
var resolveElement = new _index.NativeFunctionValue(realm, undefined, undefined, 1, function (context, _ref3) {
|
|
var _ref4 = _slicedToArray(_ref3, 1),
|
|
x = _ref4[0];
|
|
|
|
// 1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
|
|
var alreadyCalled = resolveElement.$AlreadyCalled;
|
|
(0, _invariant2.default)(alreadyCalled);
|
|
|
|
// 2. If alreadyCalled.[[Value]] is true, return undefined.
|
|
if (alreadyCalled.value === true) {
|
|
return realm.intrinsics.undefined;
|
|
}
|
|
|
|
// 3. Set alreadyCalled.[[Value]] to true.
|
|
alreadyCalled.value = true;
|
|
|
|
// 4. Let index be the value of F's [[Index]] internal slot.
|
|
var myIndex = resolveElement.$Index;
|
|
(0, _invariant2.default)(typeof myIndex === "number");
|
|
|
|
// 5. Let values be the value of F's [[Values]] internal slot.
|
|
var values = resolveElement.$Values;
|
|
(0, _invariant2.default)(values instanceof Array);
|
|
|
|
// 6. Let promiseCapability be the value of F's [[Capabilities]] internal slot.
|
|
var promiseCapability = resolveElement.$Capabilities;
|
|
(0, _invariant2.default)(promiseCapability);
|
|
|
|
// 7. Let remainingElementsCount be the value of F's [[RemainingElements]] internal slot.
|
|
var remainingElementsCount = resolveElement.$RemainingElements;
|
|
(0, _invariant2.default)(remainingElementsCount);
|
|
|
|
// 8. Set values[index] to x.
|
|
values[myIndex] = x;
|
|
|
|
// 9. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
|
|
remainingElementsCount.value = remainingElementsCount.value - 1;
|
|
|
|
// 10. If remainingElementsCount.[[Value]] is 0, then
|
|
if (remainingElementsCount.value === 0) {
|
|
// a. Let valuesArray be CreateArrayFromList(values).
|
|
var valuesArray = _singletons.Create.CreateArrayFromList(realm, values);
|
|
|
|
// b. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
|
|
(0, _call.Call)(realm, promiseCapability.resolve, realm.intrinsics.undefined, [valuesArray]);
|
|
}
|
|
|
|
// 11. Return undefined.
|
|
return realm.intrinsics.undefined;
|
|
}, false);
|
|
return resolveElement;
|
|
}
|
|
|
|
// ECMA262 25.4.4.1.1
|
|
function PerformPromiseAll(realm, iteratorRecord, constructor, resultCapability) {
|
|
// 1. Assert: constructor is a constructor function.
|
|
(0, _invariant2.default)(constructor instanceof _index.FunctionValue && (0, _is.IsConstructor)(realm, constructor), "constructor is a constructor function");
|
|
|
|
// 2. Assert: resultCapability is a PromiseCapability record.
|
|
resultCapability;
|
|
|
|
// 3. Let values be a new empty List.
|
|
var values = [];
|
|
|
|
// 4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
|
|
var remainingElementsCount = { value: 1 };
|
|
|
|
// 5. Let index be 0.
|
|
var index = 0;
|
|
|
|
// 6. Repeat
|
|
while (true) {
|
|
// a. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
|
|
var next = void 0;
|
|
try {
|
|
next = (0, _iterator2.IteratorStep)(realm, iteratorRecord.$Iterator);
|
|
} catch (e) {
|
|
if (e instanceof _completions.AbruptCompletion) {
|
|
// b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
|
iteratorRecord.$Done = true;
|
|
}
|
|
|
|
// c. ReturnIfAbrupt(next).
|
|
throw e;
|
|
}
|
|
|
|
// d. If next is false, then
|
|
if (next === false) {
|
|
// i. Set iteratorRecord.[[Done]] to true.
|
|
iteratorRecord.$Done = true;
|
|
|
|
// ii. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
|
|
remainingElementsCount.value = remainingElementsCount.value - 1;
|
|
|
|
// iii. If remainingElementsCount.[[Value]] is 0, then
|
|
if (remainingElementsCount.value === 0) {
|
|
// 1. Let valuesArray be CreateArrayFromList(values).
|
|
var valuesArray = _singletons.Create.CreateArrayFromList(realm, values);
|
|
|
|
// 2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
|
|
(0, _call.Call)(realm, resultCapability.resolve, realm.intrinsics.undefined, [valuesArray]);
|
|
}
|
|
|
|
// iv. Return resultCapability.[[Promise]].
|
|
return resultCapability.promise;
|
|
}
|
|
|
|
// e. Let nextValue be IteratorValue(next).
|
|
var nextValue = void 0;
|
|
try {
|
|
nextValue = (0, _iterator2.IteratorValue)(realm, next);
|
|
} catch (e) {
|
|
if (e instanceof _completions.AbruptCompletion) {
|
|
// f. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
|
iteratorRecord.$Done = true;
|
|
}
|
|
|
|
// g. ReturnIfAbrupt(nextValue).
|
|
throw e;
|
|
}
|
|
|
|
// h. Append undefined to values.
|
|
values.push(realm.intrinsics.undefined);
|
|
|
|
// i. Let nextPromise be ? Invoke(constructor, "resolve", « nextValue »).
|
|
var nextPromise = (0, _call.Invoke)(realm, constructor, "resolve", [nextValue]);
|
|
|
|
// j. Let resolveElement be a new built-in function object as defined in Promise.all Resolve Element Functions.
|
|
var resolveElement = createResolveElementFunction(realm);
|
|
|
|
// k. Set the [[AlreadyCalled]] internal slot of resolveElement to a new Record {[[Value]]: false }.
|
|
resolveElement.$AlreadyCalled = { value: false };
|
|
|
|
// l. Set the [[Index]] internal slot of resolveElement to index.
|
|
resolveElement.$Index = index;
|
|
|
|
// m. Set the [[Values]] internal slot of resolveElement to values.
|
|
resolveElement.$Values = values;
|
|
|
|
// n. Set the [[Capabilities]] internal slot of resolveElement to resultCapability.
|
|
resolveElement.$Capabilities = resultCapability;
|
|
|
|
// o. Set the [[RemainingElements]] internal slot of resolveElement to remainingElementsCount.
|
|
resolveElement.$RemainingElements = remainingElementsCount;
|
|
|
|
// p. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] + 1.
|
|
remainingElementsCount.value = remainingElementsCount.value + 1;
|
|
|
|
// q. Perform ? Invoke(nextPromise, "then", « resolveElement, resultCapability.[[Reject]] »).
|
|
(0, _call.Invoke)(realm, nextPromise, "then", [resolveElement, resultCapability.reject]);
|
|
|
|
// r. Set index to index + 1.
|
|
index = index + 1;
|
|
}
|
|
(0, _invariant2.default)(false);
|
|
}
|
|
|
|
// ECMA262 25.4.4.3.1
|
|
function PerformPromiseRace(realm, iteratorRecord, resultCapability, C) {
|
|
// 1. Assert: constructor is a constructor function.
|
|
(0, _invariant2.default)((0, _is.IsConstructor)(realm, C), "constructor is a constructor function");
|
|
|
|
// 2. Assert: resultCapability is a PromiseCapability Record.
|
|
resultCapability;
|
|
|
|
// 3. Repeat
|
|
while (true) {
|
|
// a. Let next be IteratorStep(iteratorRecord.[[Iterator]]).
|
|
var next = void 0;
|
|
try {
|
|
next = (0, _iterator2.IteratorStep)(realm, iteratorRecord.$Iterator);
|
|
} catch (e) {
|
|
if (e instanceof _completions.AbruptCompletion) {
|
|
// b. If next is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
|
iteratorRecord.$Done = true;
|
|
}
|
|
|
|
// c. ReturnIfAbrupt(next).
|
|
throw e;
|
|
}
|
|
|
|
// d. If next is false, then
|
|
if (next === false) {
|
|
// i. Set iteratorRecord.[[Done]] to true.
|
|
iteratorRecord.$Done = true;
|
|
|
|
// ii. Return resultCapability.[[Promise]].
|
|
(0, _invariant2.default)(resultCapability.promise instanceof _index.ObjectValue);
|
|
return resultCapability.promise;
|
|
}
|
|
|
|
// e. Let nextValue be IteratorValue(next).
|
|
var nextValue = void 0;
|
|
try {
|
|
nextValue = (0, _iterator2.IteratorValue)(realm, next);
|
|
} catch (e) {
|
|
if (e instanceof _completions.AbruptCompletion) {
|
|
// f. If nextValue is an abrupt completion, set iteratorRecord.[[Done]] to true.
|
|
iteratorRecord.$Done = true;
|
|
}
|
|
|
|
// g. ReturnIfAbrupt(nextValue).
|
|
throw e;
|
|
}
|
|
|
|
// h. Let nextPromise be ? Invoke(C, "resolve", « nextValue »).
|
|
var nextPromise = (0, _call.Invoke)(realm, C, "resolve", [nextValue]);
|
|
|
|
// i. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
|
|
(0, _call.Invoke)(realm, nextPromise, "then", [resultCapability.resolve, resultCapability.reject]);
|
|
}
|
|
(0, _invariant2.default)(false);
|
|
}
|
|
|
|
// ECMA262 25.4.5.3.1
|
|
function PerformPromiseThen(realm, promise, onFulfilled, onRejected, resultCapability) {
|
|
// 1. Assert: IsPromise(promise) is true.
|
|
(0, _invariant2.default)((0, _is.IsPromise)(realm, promise), "IsPromise(promise) is true");
|
|
|
|
// 2. Assert: resultCapability is a PromiseCapability record.
|
|
resultCapability;
|
|
|
|
// 3. If IsCallable(onFulfilled) is false, then
|
|
if ((0, _is.IsCallable)(realm, onFulfilled) === false) {
|
|
// a. Let onFulfilled be "Identity".
|
|
onFulfilled = new _index.StringValue(realm, "Identity");
|
|
}
|
|
|
|
// 4. If IsCallable(onRejected) is false, then
|
|
if ((0, _is.IsCallable)(realm, onRejected)) {
|
|
// a. Let onRejected be "Thrower".
|
|
onRejected = new _index.StringValue(realm, "Thrower");
|
|
}
|
|
|
|
// 5. Let fulfillReaction be the PromiseReaction { [[Capabilities]]: resultCapability, [[Handler]]: onFulfilled }.
|
|
var fulfillReaction = { capabilities: resultCapability, handler: onFulfilled };
|
|
|
|
// 6. Let rejectReaction be the PromiseReaction { [[Capabilities]]: resultCapability, [[Handler]]: onRejected}.
|
|
var rejectReaction = { capabilities: resultCapability, handler: onRejected };
|
|
|
|
// 7. If the value of promise's [[PromiseState]] internal slot is "pending", then
|
|
if (promise.$PromiseState === "pending") {
|
|
// a. Append fulfillReaction as the last element of the List that is the value of promise's [[PromiseFulfillReactions]] internal slot.
|
|
_singletons.Properties.ThrowIfInternalSlotNotWritable(realm, promise, "$PromiseFulfillReactions");
|
|
(0, _invariant2.default)(promise.$PromiseFulfillReactions);
|
|
promise.$PromiseFulfillReactions.push(fulfillReaction);
|
|
// b. Append rejectReaction as the last element of the List that is the value of promise's [[PromiseRejectReactions]] internal slot.
|
|
_singletons.Properties.ThrowIfInternalSlotNotWritable(realm, promise, "$PromiseRejectReactions");
|
|
(0, _invariant2.default)(promise.$PromiseRejectReactions);
|
|
promise.$PromiseRejectReactions.push(rejectReaction);
|
|
} else if (promise.$PromiseState === "fulfilled") {
|
|
// 8. Else if the value of promise's [[PromiseState]] internal slot is "fulfilled", then
|
|
// a. Let value be the value of promise's [[PromiseResult]] internal slot.
|
|
var value = promise.$PromiseResult;
|
|
// b. Perform EnqueueJob("PromiseJobs", PromiseReactionJob, « fulfillReaction, value »).
|
|
EnqueueJob(realm, "PromiseJobs", PromiseReactionJob, [fulfillReaction, value]);
|
|
} else {
|
|
// 9. Else,
|
|
// a. Assert: The value of promise's [[PromiseState]] internal slot is "rejected".
|
|
(0, _invariant2.default)(promise.$PromiseState === "rejected");
|
|
|
|
// b. Let reason be the value of promise's [[PromiseResult]] internal slot.
|
|
var reason = promise.$PromiseResult;
|
|
|
|
// c. If the value of promise's [[PromiseIsHandled]] internal slot is false, perform HostPromiseRejectionTracker(promise, "handle").
|
|
if (promise.$PromiseIsHandled === false) HostPromiseRejectionTracker(realm, promise, "handle");
|
|
|
|
// d. Perform EnqueueJob("PromiseJobs", PromiseReactionJob, « rejectReaction, reason »).
|
|
EnqueueJob(realm, "PromiseJobs", PromiseReactionJob, [rejectReaction, reason]);
|
|
}
|
|
|
|
// 10. Set promise's [[PromiseIsHandled]] internal slot to true.
|
|
_singletons.Properties.ThrowIfInternalSlotNotWritable(realm, promise, "$PromiseIsHandled").$PromiseIsHandled = true;
|
|
|
|
// 11. Return resultCapability.[[Promise]].
|
|
(0, _invariant2.default)(resultCapability.promise instanceof _index.ObjectValue);
|
|
return resultCapability.promise;
|
|
}
|
|
|
|
// ECMA262 25.4.2.1
|
|
function PromiseReactionJob(realm, reaction, argument) {
|
|
return realm.intrinsics.undefined;
|
|
}
|
|
|
|
// ECMA262 25.4.1.3.2
|
|
function createResolveFunction(realm) {
|
|
// 2. Let resolve be a new built-in function object as defined in Promise Resolve Functions (25.4.1.3.2).
|
|
var resolve = new _index.NativeFunctionValue(realm, undefined, undefined, 1, function (context, _ref5) {
|
|
var _ref6 = _slicedToArray(_ref5, 1),
|
|
resolution = _ref6[0];
|
|
|
|
// 1. Assert: F has a [[Promise]] internal slot whose value is an Object.
|
|
(0, _invariant2.default)(resolve.$Promise instanceof _index.ObjectValue, "F has a [[Promise]] internal slot whose value is an Object");
|
|
|
|
// 2. Let promise be the value of F's [[Promise]] internal slot.
|
|
var promise = resolve.$Promise;
|
|
|
|
// 3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal slot.
|
|
var alreadyResolved = resolve.$AlreadyResolved;
|
|
(0, _invariant2.default)(alreadyResolved !== undefined);
|
|
|
|
// 4. If alreadyResolved.[[Value]] is true, return undefined.
|
|
if (alreadyResolved.value === true) return realm.intrinsics.undefined;
|
|
|
|
// 5. Set alreadyResolved.[[Value]] to true.
|
|
alreadyResolved.value = true;
|
|
|
|
// 6. If SameValue(resolution, promise) is true, then
|
|
if ((0, _abstract.SameValue)(realm, resolution.throwIfNotConcrete(), promise)) {
|
|
// a. Let selfResolutionError be a newly created TypeError object.
|
|
var selfResolutionError = (0, _construct.Construct)(realm, realm.intrinsics.TypeError, [new _index.StringValue(realm, "resolve")]);
|
|
|
|
// b. Return RejectPromise(promise, selfResolutionError).
|
|
return RejectPromise(realm, promise, selfResolutionError);
|
|
}
|
|
// 7. If Type(resolution) is not Object, then
|
|
if (!(resolution instanceof _index.ObjectValue)) {
|
|
// a. Return FulfillPromise(promise, resolution).
|
|
return FulfillPromise(realm, promise, resolution);
|
|
}
|
|
|
|
// 8. Let then be Get(resolution, "then").
|
|
var then = void 0;
|
|
try {
|
|
then = (0, _get.Get)(realm, resolution, "then");
|
|
} catch (e) {
|
|
// 9. If then is an abrupt completion, then
|
|
if (e instanceof _completions.AbruptCompletion) {
|
|
// a. Return RejectPromise(promise, then.[[Value]]).
|
|
return RejectPromise(realm, promise, e);
|
|
} else throw e;
|
|
}
|
|
|
|
// 10. Let thenAction be then.[[Value]].
|
|
var thenAction = then;
|
|
|
|
// 11. If IsCallable(thenAction) is false, then
|
|
if ((0, _is.IsCallable)(realm, thenAction)) {
|
|
// a. Return FulfillPromise(promise, resolution).
|
|
return FulfillPromise(realm, promise, resolution);
|
|
}
|
|
|
|
// 12. Perform EnqueueJob("PromiseJobs", PromiseResolveThenableJob, « promise, resolution, thenAction »).
|
|
EnqueueJob(realm, "PromiseJobs", PromiseResolveThenableJob, [promise, resolution, thenAction]);
|
|
|
|
// 13. Return undefined.
|
|
return realm.intrinsics.undefined;
|
|
}, false);
|
|
return resolve;
|
|
}
|
|
|
|
// ECMA262 25.4.1.3.1
|
|
function createRejectFunction(realm) {
|
|
// 5. Let reject be a new built-in function object as defined in Promise Reject Functions (25.4.1.3.1).
|
|
var reject = new _index.NativeFunctionValue(realm, undefined, undefined, 1, function (context, _ref7) {
|
|
var _ref8 = _slicedToArray(_ref7, 1),
|
|
reason = _ref8[0];
|
|
|
|
// 1. Assert: F has a [[Promise]] internal slot whose value is an Object.
|
|
(0, _invariant2.default)(reject.$Promise instanceof _index.ObjectValue, "F has a [[Promise]] internal slot whose value is an Object");
|
|
|
|
// 2. Let promise be the value of F's [[Promise]] internal slot.
|
|
var promise = reject.$Promise;
|
|
|
|
// 3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal slot.
|
|
var alreadyResolved = reject.$AlreadyResolved;
|
|
(0, _invariant2.default)(alreadyResolved !== undefined);
|
|
|
|
// 4. If alreadyResolved.[[Value]] is true, return undefined.
|
|
if (alreadyResolved.value === true) return realm.intrinsics.undefined;
|
|
|
|
// 5. Set alreadyResolved.[[Value]] to true.
|
|
alreadyResolved.value = true;
|
|
|
|
// 6. Return RejectPromise(promise, reason).
|
|
return RejectPromise(realm, promise, reason);
|
|
}, false);
|
|
return reject;
|
|
}
|
|
|
|
// ECMA262 25.4.1.3
|
|
function CreateResolvingFunctions(realm, promise) {
|
|
// 1. Let alreadyResolved be a new Record { [[Value]]: false }.
|
|
var alreadyResolved = { value: false };
|
|
|
|
// 2. Let resolve be a new built-in function object as defined in Promise Resolve Functions (25.4.1.3.2).
|
|
var resolve = createResolveFunction(realm);
|
|
|
|
// 3. Set the [[Promise]] internal slot of resolve to promise.
|
|
resolve.$Promise = promise;
|
|
|
|
// 4. Set the [[AlreadyResolved]] internal slot of resolve to alreadyResolved.
|
|
resolve.$AlreadyResolved = alreadyResolved;
|
|
|
|
// 5. Let reject be a new built-in function object as defined in Promise Reject Functions (25.4.1.3.1).
|
|
var reject = createRejectFunction(realm);
|
|
|
|
// 6. Set the [[Promise]] internal slot of reject to promise.
|
|
reject.$Promise = promise;
|
|
|
|
// 7. Set the [[AlreadyResolved]] internal slot of reject to alreadyResolved.
|
|
reject.$AlreadyResolved = alreadyResolved;
|
|
|
|
// 8. Return a new Record { [[Resolve]]: resolve, [[Reject]]: reject }.
|
|
return { resolve: resolve, reject: reject };
|
|
}
|
|
|
|
// ECMA262 25.4.1.4
|
|
function FulfillPromise(realm, promise, value) {
|
|
// 1. Assert: The value of promise.[[PromiseState]] is "pending".
|
|
(0, _invariant2.default)(promise.$PromiseState === "pending");
|
|
|
|
// 2. Let reactions be promise.[[PromiseFulfillReactions]].
|
|
var reactions = promise.$PromiseFulfillReactions;
|
|
(0, _invariant2.default)(reactions);
|
|
|
|
// 3. Set promise.[[PromiseResult]] to value.
|
|
_singletons.Properties.ThrowIfInternalSlotNotWritable(realm, promise, "$PromiseResult").$PromiseResult = value;
|
|
|
|
// 4. Set promise.[[PromiseFulfillReactions]] to undefined.
|
|
_singletons.Properties.ThrowIfInternalSlotNotWritable(realm, promise, "$PromiseFulfillReactions").$PromiseFulfillReactions = undefined;
|
|
|
|
// 5. Set promise.[[PromiseRejectReactions]] to undefined.
|
|
_singletons.Properties.ThrowIfInternalSlotNotWritable(realm, promise, "$PromiseRejectReactions").$PromiseRejectReactions = undefined;
|
|
|
|
// 6. Set promise.[[PromiseState]] to "fulfilled".
|
|
_singletons.Properties.ThrowIfInternalSlotNotWritable(realm, promise, "$PromiseState").$PromiseState = "fulfilled";
|
|
|
|
// 7. Return TriggerPromiseReactions(reactions, value).
|
|
return TriggerPromiseReactions(realm, reactions, value);
|
|
}
|
|
|
|
// ECMA262 25.4.1.7
|
|
function RejectPromise(realm, promise, reason) {
|
|
// 1. Assert: The value of promise.[[PromiseState]] is "pending".
|
|
(0, _invariant2.default)(promise.$PromiseState === "pending");
|
|
|
|
// 2. Let reactions be promise.[[PromiseRejectReactions]].
|
|
var reactions = promise.$PromiseFulfillReactions;
|
|
(0, _invariant2.default)(reactions);
|
|
|
|
// 3. Set promise.[[PromiseResult]] to reason.
|
|
_singletons.Properties.ThrowIfInternalSlotNotWritable(realm, promise, "$PromiseResult").$PromiseResult = reason;
|
|
|
|
// 4. Set promise.[[PromiseFulfillReactions]] to undefined.
|
|
_singletons.Properties.ThrowIfInternalSlotNotWritable(realm, promise, "$PromiseFulfillReactions").$PromiseFulfillReactions = undefined;
|
|
|
|
// 5. Set promise.[[PromiseRejectReactions]] to undefined.
|
|
_singletons.Properties.ThrowIfInternalSlotNotWritable(realm, promise, "$PromiseRejectReactions").$PromiseRejectReactions = undefined;
|
|
|
|
// 6. Set promise.[[PromiseState]] to "rejected".
|
|
_singletons.Properties.ThrowIfInternalSlotNotWritable(realm, promise, "$PromiseState").$PromiseState = "rejected";
|
|
|
|
// 7. If promise.[[PromiseIsHandled]] is false, perform HostPromiseRejectionTracker(promise, "reject").
|
|
if (promise.$PromiseIsHandled === false) HostPromiseRejectionTracker(realm, promise, "reject");
|
|
|
|
// 8. Return TriggerPromiseReactions(reactions, reason).
|
|
return TriggerPromiseReactions(realm, reactions, reason);
|
|
}
|
|
|
|
// ECMA262 25.4.1.8
|
|
function TriggerPromiseReactions(realm, reactions, argument) {
|
|
// 1. Repeat for each reaction in reactions, in original insertion order
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = reactions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var reaction = _step.value;
|
|
|
|
// a. Perform EnqueueJob("PromiseJobs", PromiseReactionJob, « reaction, argument »).
|
|
EnqueueJob(realm, "PromiseJobs", PromiseReactionJob, [reaction, argument]);
|
|
}
|
|
// 2. Return undefined.
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
_iterator.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
|
|
return realm.intrinsics.undefined;
|
|
}
|
|
|
|
// ECMA262 25.4.1.9
|
|
function HostPromiseRejectionTracker(realm, promise, operation) {}
|
|
|
|
// ECMA262 25.4.2.2
|
|
function PromiseResolveThenableJob(realm, promiseToResolve, thenable, then) {}
|
|
//# sourceMappingURL=promise.js.map
|