/**
* Copyright (c) 2012-2016 André Bargull
* Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms.
*
* <https://github.com/anba/es6draft>
*/
package com.github.anba.es6draft.runtime.objects.async;
import static com.github.anba.es6draft.runtime.objects.promise.PromiseAbstractOperations.PromiseBuiltinCapability;
import static com.github.anba.es6draft.runtime.objects.promise.PromisePrototype.PerformPromiseThen;
import static com.github.anba.es6draft.runtime.types.Undefined.UNDEFINED;
import com.github.anba.es6draft.runtime.ExecutionContext;
import com.github.anba.es6draft.runtime.Realm;
import com.github.anba.es6draft.runtime.internal.RuntimeInfo;
import com.github.anba.es6draft.runtime.objects.promise.PromiseCapability;
import com.github.anba.es6draft.runtime.objects.promise.PromiseObject;
import com.github.anba.es6draft.runtime.types.Undefined;
import com.github.anba.es6draft.runtime.types.builtins.BuiltinFunction;
/**
* <h1>Async Functions</h1>
* <ul>
* <li>Abstract Operations
* </ul>
*/
public final class AsyncAbstractOperations {
private AsyncAbstractOperations() {
}
/**
* 2.2 AsyncFunctionStart(promiseCapability, asyncFunctionBody)
*
* @param cx
* the execution context
* @param promiseCapability
* the promise capability
* @param asyncFunctionBody
* the function body
*/
public static void AsyncFunctionStart(ExecutionContext cx, PromiseCapability<PromiseObject> promiseCapability,
RuntimeInfo.Function asyncFunctionBody) {
/* steps 1-7 */
AsyncObject asyncObject = new AsyncObject(promiseCapability);
asyncObject.start(cx, asyncFunctionBody);
}
/**
* 2.3 AsyncFunctionAwait(value)
*
* @param cx
* the execution context
* @param value
* the await value
*/
public static void AsyncFunctionAwait(ExecutionContext cx, Object value) {
/* step 1 */
Async asyncObject = cx.getCurrentAsync();
assert asyncObject != null;
/* steps 2-3 */
PromiseCapability<PromiseObject> promiseCapability = PromiseBuiltinCapability(cx);
/* steps 4-5 */
promiseCapability.getResolve().call(cx, UNDEFINED, value);
/* steps 6, 8 */
AwaitedFulfilled onFulfilled = new AwaitedFulfilled(cx.getRealm(), asyncObject);
/* steps 7, 8 */
AwaitedRejected onRejected = new AwaitedRejected(cx.getRealm(), asyncObject);
/* step 9 */
PromiseCapability<PromiseObject> throwawayCapability = PromiseBuiltinCapability(cx);
/* step 10 */
PerformPromiseThen(cx, promiseCapability.getPromise(), onFulfilled, onRejected, throwawayCapability);
/* steps 11-13 (implemented in generated code) */
}
/**
* 2.4 AsyncFunction Awaited Fulfilled
*/
public static final class AwaitedFulfilled extends BuiltinFunction {
private final Async asyncObject;
public AwaitedFulfilled(Realm realm, Async asyncObject) {
this(realm, asyncObject, null);
createDefaultFunctionProperties();
}
private AwaitedFulfilled(Realm realm, Async asyncObject, Void ignore) {
super(realm, ANONYMOUS, 1);
this.asyncObject = asyncObject;
}
@Override
public AwaitedFulfilled clone() {
return new AwaitedFulfilled(getRealm(), asyncObject, null);
}
@Override
public Undefined call(ExecutionContext callerContext, Object thisValue, Object... args) {
ExecutionContext calleeContext = calleeContext();
Object value = argument(args, 0);
/* steps 1-7 */
asyncObject.resume(calleeContext, value);
return UNDEFINED;
}
}
/**
* 2.5 AsyncFunction Awaited Rejected
*/
public static final class AwaitedRejected extends BuiltinFunction {
private final Async asyncObject;
public AwaitedRejected(Realm realm, Async asyncObject) {
this(realm, asyncObject, null);
createDefaultFunctionProperties();
}
private AwaitedRejected(Realm realm, Async asyncObject, Void ignore) {
super(realm, ANONYMOUS, 1);
this.asyncObject = asyncObject;
}
@Override
public AwaitedRejected clone() {
return new AwaitedRejected(getRealm(), asyncObject, null);
}
@Override
public Undefined call(ExecutionContext callerContext, Object thisValue, Object... args) {
ExecutionContext calleeContext = calleeContext();
Object reason = argument(args, 0);
/* steps 1-7 */
asyncObject._throw(calleeContext, reason);
return UNDEFINED;
}
}
}