darling-JavaScriptCore/builtins/InternalPromiseConstructor.js
2017-08-12 09:48:01 -07:00

87 lines
3.2 KiB
JavaScript

/*
* Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
function internalAll(array)
{
// This function is intended to be used in the JSC internals.
// The implementation should take care not to perform the user
// observable / trappable operations.
//
// 1. Don't use for-of and iterables. This function only accepts
// the dense array of the promises.
// 2. Don't look up this.constructor / @@species. Always construct
// the plain Promise object.
"use strict";
var promiseCapability = @newPromiseCapability(@InternalPromise);
var values = [];
var index = 0;
var remainingElementsCount = 0;
function newResolveElement(index)
{
var alreadyCalled = false;
return function (argument)
{
if (alreadyCalled)
return @undefined;
alreadyCalled = true;
@putByValDirect(values, index, argument);
--remainingElementsCount;
if (remainingElementsCount === 0)
return promiseCapability.@resolve.@call(@undefined, values);
return @undefined;
}
}
try {
if (array.length === 0)
promiseCapability.@resolve.@call(@undefined, values);
else {
for (var index = 0, length = array.length; index < length; ++index) {
var value = array[index];
@putByValDirect(values, index, @undefined);
var nextPromiseCapability = @newPromiseCapability(@InternalPromise);
nextPromiseCapability.@resolve.@call(@undefined, value);
var nextPromise = nextPromiseCapability.@promise;
var resolveElement = newResolveElement(index);
++remainingElementsCount;
nextPromise.then(resolveElement, promiseCapability.@reject);
}
}
} catch (error) {
promiseCapability.@reject.@call(@undefined, error);
}
return promiseCapability.@promise;
}