/** * 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.types.builtins; import static com.github.anba.es6draft.runtime.objects.async.iteration.AsyncGeneratorAbstractOperations.AsyncGeneratorStart; import static com.github.anba.es6draft.runtime.types.builtins.OrdinaryFunction.FunctionInitialize; import com.github.anba.es6draft.runtime.ExecutionContext; import com.github.anba.es6draft.runtime.LexicalEnvironment; import com.github.anba.es6draft.runtime.Realm; import com.github.anba.es6draft.runtime.internal.RuntimeInfo; import com.github.anba.es6draft.runtime.objects.async.iteration.AsyncGeneratorObject; import com.github.anba.es6draft.runtime.types.Intrinsics; import com.github.anba.es6draft.runtime.types.ScriptObject; /** * Extension: Async Generator Function Definitions */ public final class OrdinaryAsyncGenerator extends FunctionObject { /** * Constructs a new Async Generator Function object. * * @param realm * the realm object */ protected OrdinaryAsyncGenerator(Realm realm) { super(realm); } @Override protected OrdinaryAsyncGenerator allocateNew() { return FunctionAllocate(getRealm().defaultContext(), getPrototype(), isStrict(), getFunctionKind()); } /** * 9.2.1 [[Call]] (thisArgument, argumentsList) */ @Override public AsyncGeneratorObject call(ExecutionContext callerContext, Object thisValue, Object... args) { try { return (AsyncGeneratorObject) getCallMethod().invokeExact(this, callerContext, thisValue, args); } catch (Throwable e) { throw FunctionObject.<RuntimeException> rethrow(e); } } /** * 9.2.1 [[Call]] (thisArgument, argumentsList) */ @Override public AsyncGeneratorObject tailCall(ExecutionContext callerContext, Object thisValue, Object... args) throws Throwable { return (AsyncGeneratorObject) getTailCallMethod().invokeExact(this, callerContext, thisValue, args); } /** * Runtime Semantics: EvaluateBody * * @param cx * the execution context * @param functionObject * the async generator function object * @return the async generator result value */ public static AsyncGeneratorObject EvaluateBody(ExecutionContext cx, OrdinaryAsyncGenerator functionObject) { /* steps 1-2 */ AsyncGeneratorObject gen = OrdinaryCreateFromConstructor(cx, functionObject, Intrinsics.AsyncGeneratorPrototype, AsyncGeneratorObject::new); /* step 3 */ AsyncGeneratorStart(cx, gen, functionObject.getCode()); /* step 4 */ return gen; } /* ***************************************************************************************** */ /** * 9.2.3 FunctionAllocate (functionPrototype, strict [,functionKind] ) * * @param cx * the execution context * @param functionPrototype * the function prototype * @param strict * the strict mode flag * @param kind * the function kind * @return the new async enerator function object */ public static OrdinaryAsyncGenerator FunctionAllocate(ExecutionContext cx, ScriptObject functionPrototype, boolean strict, FunctionKind kind) { assert kind != FunctionKind.ClassConstructor; Realm realm = cx.getRealm(); /* steps 1-5 (implicit) */ /* steps 6-9 */ OrdinaryAsyncGenerator f = new OrdinaryAsyncGenerator(realm); /* steps 10-14 */ f.allocate(realm, functionPrototype, strict, kind, ConstructorKind.Base); /* step 15 */ return f; } /** * 9.2.6 GeneratorFunctionCreate (kind, ParameterList, Body, Scope, Strict) * * @param cx * the execution context * @param kind * the function kind * @param function * the function code * @param scope * the lexical environment * @return the new async generator function object */ public static OrdinaryAsyncGenerator AsyncGeneratorFunctionCreate(ExecutionContext cx, FunctionKind kind, RuntimeInfo.Function function, LexicalEnvironment<?> scope) { assert function.isAsync() && function.isGenerator() && kind != FunctionKind.ClassConstructor; /* step 1 */ ScriptObject functionPrototype = cx.getIntrinsic(Intrinsics.AsyncGenerator); /* step 2 */ OrdinaryAsyncGenerator f = FunctionAllocate(cx, functionPrototype, function.isStrict(), kind); /* step 3 */ FunctionInitialize(f, kind, function, scope, cx.getCurrentExecutable()); return f; } }