/** * 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.internal.Properties.createProperties; import static com.github.anba.es6draft.runtime.objects.FunctionConstructor.functionSource; import static com.github.anba.es6draft.runtime.objects.FunctionConstructor.functionSourceText; import static com.github.anba.es6draft.runtime.objects.FunctionConstructor.newFunctionExecutable; import static com.github.anba.es6draft.runtime.types.builtins.OrdinaryAsyncFunction.FunctionAllocate; import static com.github.anba.es6draft.runtime.types.builtins.OrdinaryFunction.FunctionInitialize; import static com.github.anba.es6draft.runtime.types.builtins.OrdinaryFunction.SetFunctionName; import com.github.anba.es6draft.compiler.CompilationException; import com.github.anba.es6draft.parser.ParserException; import com.github.anba.es6draft.runtime.ExecutionContext; import com.github.anba.es6draft.runtime.GlobalEnvironmentRecord; import com.github.anba.es6draft.runtime.LexicalEnvironment; import com.github.anba.es6draft.runtime.Realm; import com.github.anba.es6draft.runtime.internal.Initializable; import com.github.anba.es6draft.runtime.internal.Properties.Attributes; import com.github.anba.es6draft.runtime.internal.Properties.Prototype; import com.github.anba.es6draft.runtime.internal.Properties.Value; import com.github.anba.es6draft.runtime.internal.RuntimeInfo; import com.github.anba.es6draft.runtime.internal.ScriptLoader; import com.github.anba.es6draft.runtime.internal.Source; import com.github.anba.es6draft.runtime.objects.FunctionConstructor.SourceKind; import com.github.anba.es6draft.runtime.types.Constructor; import com.github.anba.es6draft.runtime.types.Intrinsics; import com.github.anba.es6draft.runtime.types.ScriptObject; import com.github.anba.es6draft.runtime.types.builtins.BuiltinConstructor; import com.github.anba.es6draft.runtime.types.builtins.FunctionObject.FunctionKind; import com.github.anba.es6draft.runtime.types.builtins.OrdinaryAsyncFunction; /** * <h1>Async Functions</h1><br> * <h2>Async Function Objects</h2> * <ul> * <li>The Async Function Constructor * <li>Properties of the AsyncFunction constructor * </ul> */ public final class AsyncFunctionConstructor extends BuiltinConstructor implements Initializable { /** * Constructs a new AsyncFunction constructor function. * * @param realm * the realm object */ public AsyncFunctionConstructor(Realm realm) { super(realm, "AsyncFunction", 1); } @Override public void initialize(Realm realm) { createProperties(realm, this, Properties.class); } @Override public AsyncFunctionConstructor clone() { return new AsyncFunctionConstructor(getRealm()); } /** * AsyncFunction(p1, p2, ..., pn, body) */ @Override public OrdinaryAsyncFunction call(ExecutionContext callerContext, Object thisValue, Object... args) { /* steps 1-3 */ return CreateDynamicFunction(callerContext, calleeContext(), this, args); } /** * AsyncFunction(p1, p2, ..., pn, body) */ @Override public OrdinaryAsyncFunction construct(ExecutionContext callerContext, Constructor newTarget, Object... args) { /* steps 1-3 */ return CreateDynamicFunction(callerContext, calleeContext(), newTarget, args); } /** * 19.2.1.1.1 RuntimeSemantics: CreateDynamicFunction(constructor, newTarget, kind, args) * * @param callerContext * the caller execution context * @param cx * the execution context * @param newTarget * the newTarget constructor function * @param args * the function arguments * @return the new generator function object */ private static OrdinaryAsyncFunction CreateDynamicFunction(ExecutionContext callerContext, ExecutionContext cx, Constructor newTarget, Object... args) { /* step 1 (not applicable) */ /* step 2 (not applicable) */ /* step 3 */ Intrinsics fallbackProto = Intrinsics.AsyncFunction; /* steps 4-10 */ String[] sourceText = functionSourceText(cx, args); String parameters = sourceText[0], bodyText = sourceText[1]; /* steps 11, 13-20 */ Source source = functionSource(SourceKind.AsyncFunction, cx.getRealm(), callerContext); RuntimeInfo.Function function; try { ScriptLoader scriptLoader = cx.getRealm().getScriptLoader(); function = scriptLoader.asyncFunction(source, parameters, bodyText).getFunction(); } catch (ParserException | CompilationException e) { throw e.toScriptException(cx); } /* step 12 */ boolean strict = function.isStrict(); /* steps 21-22 */ ScriptObject proto = GetPrototypeFromConstructor(cx, newTarget, fallbackProto); /* step 23 */ OrdinaryAsyncFunction f = FunctionAllocate(cx, proto, strict, FunctionKind.Normal); /* steps 24-25 */ LexicalEnvironment<GlobalEnvironmentRecord> scope = f.getRealm().getGlobalEnv(); /* step 26 */ FunctionInitialize(f, FunctionKind.Normal, function, scope, newFunctionExecutable(source)); /* steps 27-28 (not applicable) */ /* step 29 */ SetFunctionName(f, "anonymous"); /* step 30 */ return f; } /** * Properties of the AsyncFunction constructor */ public enum Properties { ; @Prototype public static final Intrinsics __proto__ = Intrinsics.Function; /** * AsyncFunction.prototype */ @Value(name = "prototype", attributes = @Attributes(writable = false, enumerable = false, configurable = false)) public static final Intrinsics prototype = Intrinsics.AsyncFunctionPrototype; /** * AsyncFunction.length */ @Value(name = "length", attributes = @Attributes(writable = false, enumerable = false, configurable = true)) public static final int length = 1; @Value(name = "name", attributes = @Attributes(writable = false, enumerable = false, configurable = true)) public static final String name = "AsyncFunction"; } }