/**
* 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.iteration;
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.OrdinaryAsyncGenerator.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.Property;
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;
import com.github.anba.es6draft.runtime.types.builtins.FunctionObject.FunctionKind;
import com.github.anba.es6draft.runtime.types.builtins.OrdinaryAsyncGenerator;
import com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject;
/**
* <h1>Async Generator Functions</h1><br>
* <h2>AsyncGeneratorFunction Objects</h2>
* <ul>
* <li>The AsyncGeneratorFunction Constructor
* <li>Properties of the AsyncGeneratorFunction Constructor
* </ul>
*/
public final class AsyncGeneratorFunctionConstructor extends BuiltinConstructor implements Initializable {
/**
* Constructs a new AsyncGeneratorFunction constructor function.
*
* @param realm
* the realm object
*/
public AsyncGeneratorFunctionConstructor(Realm realm) {
super(realm, "AsyncGeneratorFunction", 1);
}
@Override
public void initialize(Realm realm) {
createProperties(realm, this, Properties.class);
}
@Override
public AsyncGeneratorFunctionConstructor clone() {
return new AsyncGeneratorFunctionConstructor(getRealm());
}
/**
* AsyncGeneratorFunction (p1, p2, ... , pn, body)
*/
@Override
public FunctionObject call(ExecutionContext callerContext, Object thisValue, Object... args) {
/* steps 1-3 */
return CreateDynamicFunction(callerContext, calleeContext(), this, args);
}
/**
* AsyncGeneratorFunction (p1, p2, ... , pn, body)
*/
@Override
public FunctionObject 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 async generator function object
*/
private static FunctionObject CreateDynamicFunction(ExecutionContext callerContext, ExecutionContext cx,
Constructor newTarget, Object... args) {
/* step 1 (not applicable) */
/* step 2 (not applicable) */
/* step 3 */
Intrinsics fallbackProto = Intrinsics.AsyncGenerator;
/* steps 4-10 */
String[] sourceText = functionSourceText(cx, args);
String parameters = sourceText[0], bodyText = sourceText[1];
/* steps 11, 13-20 */
Source source = functionSource(SourceKind.AsyncGenerator, cx.getRealm(), callerContext);
RuntimeInfo.Function function;
try {
ScriptLoader scriptLoader = cx.getRealm().getScriptLoader();
function = scriptLoader.asyncGenerator(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 */
OrdinaryAsyncGenerator 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));
/* step 27 */
OrdinaryObject prototype = ObjectCreate(cx, Intrinsics.AsyncGeneratorPrototype);
f.infallibleDefineOwnProperty("prototype", new Property(prototype, true, false, false));
/* step 28 (not applicable) */
/* step 29 */
SetFunctionName(f, "anonymous");
/* step 30 */
return f;
}
/**
* Properties of the AsyncGeneratorFunction Constructor
*/
public enum Properties {
;
@Prototype
public static final Intrinsics __proto__ = Intrinsics.Function;
/**
* AsyncGeneratorFunction.prototype
*/
@Value(name = "prototype",
attributes = @Attributes(writable = false, enumerable = false, configurable = false) )
public static final Intrinsics prototype = Intrinsics.AsyncGenerator;
/**
* AsyncGeneratorFunction.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 = "AsyncGeneratorFunction";
}
}