define_built_in_data_property(Promise, "all", function (iterable) {
    let C = this;
    let promiseCapability = NewPromiseCapability(C);

    let iterator;
    try {
        iterator = GetIterator(iterable);
    } catch (iteratorE) {
        return IfAbruptRejectPromise(iteratorE, promiseCapability);
    }

    let values = ArrayCreate(0);
    let remainingElementsCount = { "[[value]]": 0 };
    let index = 0;

    while(true) {
        let next;
        try {
            next = IteratorStep(iterator);
        } catch (nextE) {
            return IfAbruptRejectPromise(nextE, promiseCapability);
        }

        if (next === false) {
            if (index === 0) {
                promiseCapability["[[Resolve]]"].call(undefined, values);
            }
            return promiseCapability["[[Promise]]"];
        }

        let nextValue;
        try {
            nextValue = IteratorValue(next);
        } catch (nextValueE) {
            return IfAbruptRejectPromise(nextValueE, promiseCapability);
        }

        let nextPromise;
        try {
            nextPromise = Invoke(C, "resolve", [nextValue]);
        } catch (nextPromiseE) {
            return IfAbruptRejectPromise(nextPromiseE, promiseCapability);
        }

        let resolveElement = new_built_in_PromiseDotAllResolveElement_Function();
        set_slot(resolveElement, "[[Index]]", index);
        set_slot(resolveElement, "[[Values]]", values);
        set_slot(resolveElement, "[[Capabilities]]", promiseCapability);
        set_slot(resolveElement, "[[RemainingElements]]", remainingElementsCount);

        try {
            Invoke(nextPromise, "then", [resolveElement, promiseCapability["[[Reject]]"]]);
        } catch (resultE) {
            return IfAbruptRejectPromise(resultE, promiseCapability);
        }

        index = index + 1;
        remainingElementsCount["[[value]]"] = remainingElementsCount["[[value]]"] + 1;
    }
});
define_built_in_data_property(Promise, "race", function (iterable) {
    let C = this;
    let promiseCapability = NewPromiseCapability(C);

    let iterator;
    try {
        iterator = GetIterator(iterable);
    } catch (iteratorE) {
        return IfAbruptRejectPromise(iteratorE, promiseCapability);
    }

    while (true) {
        let next;
        try {
            next = IteratorStep(iterator);
        } catch (nextE) {
            return IfAbruptRejectPromise(nextE, promiseCapability);
        }

        if (next === false) {
            return promiseCapability["[[Promise]]"];
        }

        let nextValue;
        try {
            nextValue = IteratorValue(next);
        } catch (nextValueE) {
            return IfAbruptRejectPromise(nextValueE, promiseCapability);
        }

        let nextPromise;
        try {
            nextPromise = Invoke(C, "resolve", [nextValue]);
        } catch (nextPromiseE) {
            return IfAbruptRejectPromise(nextPromiseE, promiseCapability);
        }

        try {
            Invoke(nextPromise, "then", [promiseCapability["[[Resolve]]"], promiseCapability["[[Reject]]"]]);
        } catch (resultE) {
            IfAbruptRejectPromise(resultE, promiseCapability);
        }
    }
});
    let F = function (x) {
        let promise = get_slot(F, "[[Promise]]");
        let fulfillmentHandler = get_slot(F, "[[FulfillmentHandler]]");
        let rejectionHandler = get_slot(F, "[[RejectionHandler]]");

        if (SameValue(x, promise) === true) {
            let selfResolutionError = new TypeError("Tried to resolve a promise with itself!");
            return rejectionHandler.call(undefined, selfResolutionError);
        }

        let C = get_slot(promise, "[[PromiseConstructor]]");
        let promiseCapability = NewPromiseCapability(C);
        let updateResult = UpdateDeferredFromPotentialThenable(x, promiseCapability);
        if (updateResult !== "not a thenable") {
            return Invoke(promiseCapability["[[Promise]]"], "then", [fulfillmentHandler, rejectionHandler]);
        }
        return fulfillmentHandler.call(undefined, x);
    };
define_built_in_data_property(Promise.prototype, "catch", function (onRejected) {
    let promise = this;
    return Invoke(promise, "then", [undefined, onRejected]);
});