Search in sources :

Example 1 with LegacyConstructorFunction

use of com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction in project es6draft by anba.

the class FunctionCodeGenerator method generateLegacyFunctionConstruct.

/**
     * Generate bytecode for:
     * 
     * <pre>
     * oldCaller = function.getLegacyCaller()
     * oldArguments = function.getLegacyArguments()
     * function.setLegacyCaller(callerContext.getCurrentFunction())
     * try {
     *   thisArgument = OrdinaryCreateFromConstructor(callerContext, newTarget, %ObjectPrototype%)
     *   calleeContext = newFunctionExecutionContext(function, newTarget, thisArgument)
     *   result = OrdinaryCallEvaluateBody(function, argumentsList)
     *   return returnResultOrThis(result)
     * } finally {
     *   function.restoreLegacyProperties(oldCaller, oldArguments)
     * }
     * </pre>
     * 
     * @param node
     *            the function node
     * @param mv
     *            the instruction visitor
     */
private void generateLegacyFunctionConstruct(FunctionNode node, InstructionVisitor mv) {
    final boolean hasArguments = codegen.isEnabled(CompatibilityOption.FunctionArguments);
    final boolean hasCaller = codegen.isEnabled(CompatibilityOption.FunctionCaller);
    Variable<LegacyConstructorFunction> function = mv.getParameter(FUNCTION, LegacyConstructorFunction.class);
    Variable<ExecutionContext> callerContext = mv.getParameter(EXECUTION_CONTEXT, ExecutionContext.class);
    Variable<Constructor> newTarget = mv.getParameter(NEW_TARGET, Constructor.class);
    Variable<Object[]> arguments = mv.getParameter(ARGUMENTS, Object[].class);
    Variable<ScriptObject> thisArg = mv.newVariable("thisArgument", ScriptObject.class);
    Variable<ExecutionContext> calleeContext = mv.newVariable("calleeContext", ExecutionContext.class);
    Variable<FunctionObject> oldCaller = mv.newVariable("oldCaller", FunctionObject.class);
    Variable<LegacyConstructorFunction.Arguments> oldArguments = mv.newVariable("oldArguments", LegacyConstructorFunction.Arguments.class);
    Variable<Throwable> throwable = mv.newVariable("throwable", Throwable.class);
    // (1) Retrieve 'caller' and 'arguments' and store in local variables
    if (hasCaller) {
        mv.load(function);
        mv.invoke(Methods.LegacyConstructorFunction_getLegacyCaller);
    } else {
        mv.anull();
    }
    mv.store(oldCaller);
    if (hasArguments) {
        mv.load(function);
        mv.invoke(Methods.LegacyConstructorFunction_getLegacyArguments);
    } else {
        mv.anull();
    }
    mv.store(oldArguments);
    // (2) Update 'caller' and 'arguments' properties
    if (hasCaller) {
        setLegacyCaller(function, callerContext, mv);
    }
    if (hasArguments) {
        setLegacyArguments(function, arguments, mv);
    }
    TryCatchLabel startFinally = new TryCatchLabel(), endFinally = new TryCatchLabel();
    TryCatchLabel handlerFinally = new TryCatchLabel();
    mv.mark(startFinally);
    {
        // (3) Create this-argument
        ordinaryCreateFromConstructor(callerContext, newTarget, thisArg, mv);
        // (4) Create a new ExecutionContext
        prepareCallAndBindThis(node, calleeContext, function, newTarget, thisArg, mv);
        // (5) Call OrdinaryCallEvaluateBody
        ordinaryCallEvaluateBody(node, calleeContext, function, arguments, mv);
        // (6) Restore 'caller' and 'arguments'
        restoreLegacyProperties(function, oldCaller, oldArguments, mv);
        // (7) Return result value
        returnResultOrThis(thisArg, false, mv);
    }
    mv.mark(endFinally);
    // Exception: Restore 'caller' and 'arguments' and then rethrow exception
    mv.finallyHandler(handlerFinally);
    mv.store(throwable);
    restoreLegacyProperties(function, oldCaller, oldArguments, mv);
    mv.load(throwable);
    mv.athrow();
    mv.tryFinally(startFinally, endFinally, handlerFinally);
}
Also used : ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) Constructor(com.github.anba.es6draft.runtime.types.Constructor) TryCatchLabel(com.github.anba.es6draft.compiler.assembler.TryCatchLabel) FunctionObject(com.github.anba.es6draft.runtime.types.builtins.FunctionObject) ExecutionContext(com.github.anba.es6draft.runtime.ExecutionContext) ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) FunctionObject(com.github.anba.es6draft.runtime.types.builtins.FunctionObject) LegacyConstructorFunction(com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction)

Example 2 with LegacyConstructorFunction

use of com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction in project es6draft by anba.

the class FunctionConstructor method CreateDynamicFunction.

/**
     * 19.2.1.1.1 RuntimeSemantics: CreateDynamicFunction(constructor, newTarget, kind, args)
     * 
     * @param cx
     *            the execution context
     * @param source
     *            the source object
     * @param function
     *            the compiled function
     * @param newTarget
     *            the newTarget constructor function
     * @param fallbackProto
     *            the fallback prototype
     * @return the new function object
     */
private static FunctionObject CreateDynamicFunction(ExecutionContext cx, Source source, RuntimeInfo.Function function, Constructor newTarget, Intrinsics fallbackProto) {
    /* steps 1-11, 13-20 (not applicable) */
    /* step 12 */
    boolean strict = function.isStrict();
    /* steps 21-22 */
    ScriptObject proto = GetPrototypeFromConstructor(cx, newTarget, fallbackProto);
    /* step 23 */
    FunctionObject f;
    if (function.is(RuntimeInfo.FunctionFlags.Legacy)) {
        assert !strict;
        f = LegacyConstructorFunction.FunctionAllocate(cx, proto);
    } else {
        f = FunctionAllocate(cx, proto, strict, FunctionKind.Normal, ConstructorKind.Base);
    }
    /* steps 24-25 */
    LexicalEnvironment<GlobalEnvironmentRecord> scope = f.getRealm().getGlobalEnv();
    /* step 26 */
    FunctionInitialize(f, FunctionKind.Normal, function, scope, newFunctionExecutable(source));
    // Work around for: https://bugs.eclipse.org/bugs/show_bug.cgi?id=479802
    if (f instanceof LegacyConstructorFunction) {
        MakeConstructor(cx, (LegacyConstructorFunction) f);
    } else {
        MakeConstructor(cx, (OrdinaryConstructorFunction) f);
    }
    /* step 29 */
    SetFunctionName(f, "anonymous");
    /* step 30 */
    return f;
}
Also used : ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) GlobalEnvironmentRecord(com.github.anba.es6draft.runtime.GlobalEnvironmentRecord) FunctionObject(com.github.anba.es6draft.runtime.types.builtins.FunctionObject) LegacyConstructorFunction(com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction)

Example 3 with LegacyConstructorFunction

use of com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction in project es6draft by anba.

the class FunctionOperations method EvaluateLegacyFunctionExpression.

/**
 * 14.1 Function Definitions
 * <p>
 * 14.1.21 Runtime Semantics: Evaluation
 * <ul>
 * <li>FunctionExpression : function ( FormalParameters ) { FunctionBody }
 * <li>FunctionExpression : function BindingIdentifier ( FormalParameters ) { FunctionBody }
 * </ul>
 *
 * @param fd
 *            the function runtime info object
 * @param cx
 *            the execution context
 * @return the new function instance
 */
public static LegacyConstructorFunction EvaluateLegacyFunctionExpression(RuntimeInfo.Function fd, ExecutionContext cx) {
    LegacyConstructorFunction closure;
    if (!fd.is(RuntimeInfo.FunctionFlags.ScopedName)) {
        /* step 1 (not applicable) */
        /* step 2 */
        LexicalEnvironment<?> scope = cx.getLexicalEnvironment();
        /* step 3 */
        closure = LegacyFunctionCreate(cx, fd, scope);
        /* step 4 */
        MakeConstructor(cx, closure);
    } else {
        /* step 1 (not applicable) */
        /* step 2 */
        LexicalEnvironment<?> scope = cx.getLexicalEnvironment();
        /* step 3 */
        LexicalEnvironment<DeclarativeEnvironmentRecord> funcEnv = newDeclarativeEnvironment(scope);
        /* step 4 */
        DeclarativeEnvironmentRecord envRec = funcEnv.getEnvRec();
        /* step 5 */
        String name = fd.functionName();
        /* step 6 */
        envRec.createImmutableBinding(name, false);
        /* step 7 */
        closure = LegacyFunctionCreate(cx, fd, funcEnv);
        /* step 8 */
        MakeConstructor(cx, closure);
        /* step 9 */
        SetFunctionName(closure, name);
        /* step 10 */
        envRec.initializeBinding(name, closure);
    }
    /* step 5/11 */
    return closure;
}
Also used : DeclarativeEnvironmentRecord(com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord) LegacyConstructorFunction(com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction)

Example 4 with LegacyConstructorFunction

use of com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction in project es6draft by anba.

the class FunctionOperations method InstantiateLegacyFunctionObject.

/**
 * 14.1 Function Definitions
 * <p>
 * 14.1.20 Runtime Semantics: InstantiateFunctionObject
 *
 * @param scope
 *            the current lexical scope
 * @param cx
 *            the execution context
 * @param fd
 *            the function runtime info object
 * @return the new function instance
 */
public static LegacyConstructorFunction InstantiateLegacyFunctionObject(LexicalEnvironment<?> scope, ExecutionContext cx, RuntimeInfo.Function fd) {
    /* step 1 (not applicable) */
    /* step 2 */
    String name = fd.functionName();
    /* step 3 */
    LegacyConstructorFunction f = LegacyFunctionCreate(cx, fd, scope);
    /* step 4 */
    MakeConstructor(cx, f);
    /* step 4 */
    SetFunctionName(f, name);
    /* step 6 */
    return f;
}
Also used : LegacyConstructorFunction(com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction)

Example 5 with LegacyConstructorFunction

use of com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction in project es6draft by anba.

the class FunctionConstructor method CreateDynamicFunction.

/**
 * 19.2.1.1.1 RuntimeSemantics: CreateDynamicFunction(constructor, newTarget, kind, args)
 *
 * @param cx
 *            the execution context
 * @param kind
 *            the function kind
 * @param compiledFunction
 *            the compiled function
 * @param proto
 *            the function prototype
 * @return the new function object
 */
public static FunctionObject CreateDynamicFunction(ExecutionContext cx, SourceKind kind, CompiledFunction compiledFunction, ScriptObject proto) {
    RuntimeInfo.Function function = compiledFunction.getFunction();
    /* step 18 */
    boolean strict = function.isStrict();
    /* step 30 */
    ObjectAllocator<? extends FunctionObject> allocator;
    switch(kind) {
        case AsyncFunction:
            allocator = OrdinaryAsyncFunction::new;
            break;
        case AsyncGenerator:
            allocator = OrdinaryAsyncGenerator::new;
            break;
        case Function:
            if (function.is(RuntimeInfo.FunctionFlags.Legacy)) {
                assert !strict;
                allocator = LegacyConstructorFunction::new;
            } else {
                allocator = OrdinaryConstructorFunction::new;
            }
            break;
        case Generator:
            allocator = OrdinaryGenerator::new;
            break;
        default:
            throw new AssertionError();
    }
    FunctionObject f = FunctionAllocate(cx, allocator, proto, strict, FunctionKind.Normal);
    /* steps 31-32 */
    LexicalEnvironment<GlobalEnvironmentRecord> scope = f.getRealm().getGlobalEnv();
    /* step 33 */
    FunctionInitialize(f, FunctionKind.Normal, function, scope, compiledFunction);
    /* steps 34-36 */
    switch(kind) {
        case AsyncFunction:
            /* step 36 */
            break;
        case AsyncGenerator:
            {
                OrdinaryObject prototype = ObjectCreate(cx, Intrinsics.AsyncGeneratorPrototype);
                f.infallibleDefineOwnProperty("prototype", new Property(prototype, true, false, false));
                break;
            }
        case Function:
            /* step 35 */
            if (f instanceof LegacyConstructorFunction) {
                MakeConstructor(cx, (LegacyConstructorFunction) f);
            } else {
                MakeConstructor(cx, (OrdinaryConstructorFunction) f);
            }
            break;
        case Generator:
            {
                /* step 34 */
                OrdinaryObject prototype = ObjectCreate(cx, Intrinsics.GeneratorPrototype);
                f.infallibleDefineOwnProperty("prototype", new Property(prototype, true, false, false));
                break;
            }
        default:
            throw new AssertionError();
    }
    /* step 37 */
    SetFunctionName(f, "anonymous");
    /* step 38 */
    return f;
}
Also used : RuntimeInfo(com.github.anba.es6draft.runtime.internal.RuntimeInfo) GlobalEnvironmentRecord(com.github.anba.es6draft.runtime.GlobalEnvironmentRecord) FunctionObject(com.github.anba.es6draft.runtime.types.builtins.FunctionObject) OrdinaryConstructorFunction(com.github.anba.es6draft.runtime.types.builtins.OrdinaryConstructorFunction) OrdinaryAsyncGenerator(com.github.anba.es6draft.runtime.types.builtins.OrdinaryAsyncGenerator) OrdinaryGenerator(com.github.anba.es6draft.runtime.types.builtins.OrdinaryGenerator) OrdinaryObject(com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject) OrdinaryAsyncFunction(com.github.anba.es6draft.runtime.types.builtins.OrdinaryAsyncFunction) Property(com.github.anba.es6draft.runtime.types.Property) LegacyConstructorFunction(com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction)

Aggregations

LegacyConstructorFunction (com.github.anba.es6draft.runtime.types.builtins.LegacyConstructorFunction)8 FunctionObject (com.github.anba.es6draft.runtime.types.builtins.FunctionObject)6 ScriptObject (com.github.anba.es6draft.runtime.types.ScriptObject)5 TryCatchLabel (com.github.anba.es6draft.compiler.assembler.TryCatchLabel)4 ExecutionContext (com.github.anba.es6draft.runtime.ExecutionContext)4 GlobalEnvironmentRecord (com.github.anba.es6draft.runtime.GlobalEnvironmentRecord)2 Constructor (com.github.anba.es6draft.runtime.types.Constructor)2 DeclarativeEnvironmentRecord (com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord)1 RuntimeInfo (com.github.anba.es6draft.runtime.internal.RuntimeInfo)1 Property (com.github.anba.es6draft.runtime.types.Property)1 OrdinaryAsyncFunction (com.github.anba.es6draft.runtime.types.builtins.OrdinaryAsyncFunction)1 OrdinaryAsyncGenerator (com.github.anba.es6draft.runtime.types.builtins.OrdinaryAsyncGenerator)1 OrdinaryConstructorFunction (com.github.anba.es6draft.runtime.types.builtins.OrdinaryConstructorFunction)1 OrdinaryGenerator (com.github.anba.es6draft.runtime.types.builtins.OrdinaryGenerator)1 OrdinaryObject (com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject)1