Search in sources :

Example 1 with DeclarativeEnvironmentRecord

use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.

the class ComprehensionGenerator method visit.

/**
     * Runtime Semantics: ComprehensionComponentEvaluation
     * <p>
     * ComprehensionFor : for ( ForBinding of AssignmentExpression )
     */
@Override
public Void visit(ComprehensionFor node, CodeVisitor mv) {
    Jump lblTest = new Jump(), lblLoop = new Jump();
    Variable<ScriptIterator<?>> iter = iterators.next();
    /* steps 1-2 */
    expressionBoxed(node.getExpression(), mv);
    /* steps 3-4 */
    mv.loadExecutionContext();
    mv.lineInfo(node.getExpression());
    mv.invoke(Methods.ScriptRuntime_iterate);
    mv.store(iter);
    /* step 5 (not applicable) */
    /* step 6 */
    mv.nonDestructiveGoTo(lblTest);
    /* steps 6.d-e */
    mv.mark(lblLoop);
    mv.load(iter);
    mv.lineInfo(node);
    mv.invoke(Methods.Iterator_next);
    /* steps 6.f-j */
    BlockScope scope = node.getScope();
    if (scope.isPresent()) {
        mv.enterVariableScope();
        Variable<LexicalEnvironment<DeclarativeEnvironmentRecord>> env = mv.newVariable("env", LexicalEnvironment.class).uncheckedCast();
        Variable<DeclarativeEnvironmentRecord> envRec = mv.newVariable("envRec", DeclarativeEnvironmentRecord.class);
        // stack: [nextValue] -> []
        Variable<Object> nextValue = mv.newVariable("nextValue", Object.class);
        mv.store(nextValue);
        newDeclarativeEnvironment(scope, mv);
        mv.store(env);
        getEnvRec(env, envRec, mv);
        for (Name name : BoundNames(node.getBinding())) {
            BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(envRec, name);
            op.createMutableBinding(envRec, name, false, mv);
        }
        BindingInitialization(codegen, envRec, node.getBinding(), nextValue, mv);
        mv.load(env);
        pushLexicalEnvironment(mv);
        mv.exitVariableScope();
    } else {
        // stack: [nextValue] -> []
        mv.pop();
    }
    /* step 6.k */
    mv.enterScope(node);
    new IterationGenerator<ComprehensionFor>(codegen) {

        @Override
        protected Completion iterationBody(ComprehensionFor node, Variable<ScriptIterator<?>> iterator, CodeVisitor mv) {
            elements.next().accept(ComprehensionGenerator.this, mv);
            return Completion.Normal;
        }

        @Override
        protected MutableValue<Object> enterIteration(ComprehensionFor node, CodeVisitor mv) {
            return mv.enterIteration();
        }

        @Override
        protected List<TempLabel> exitIteration(ComprehensionFor node, CodeVisitor mv) {
            return mv.exitIteration();
        }
    }.generate(node, iter, mv);
    mv.exitScope();
    /* steps 6.l-m */
    if (scope.isPresent()) {
        popLexicalEnvironment(mv);
    }
    /* steps 6.a-c */
    mv.mark(lblTest);
    mv.load(iter);
    mv.lineInfo(node);
    mv.invoke(Methods.Iterator_hasNext);
    mv.ifne(lblLoop);
    return null;
}
Also used : LegacyComprehensionFor(com.github.anba.es6draft.ast.LegacyComprehensionFor) ComprehensionFor(com.github.anba.es6draft.ast.ComprehensionFor) MutableValue(com.github.anba.es6draft.compiler.assembler.MutableValue) Jump(com.github.anba.es6draft.compiler.assembler.Jump) ScriptIterator(com.github.anba.es6draft.runtime.internal.ScriptIterator) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) Name(com.github.anba.es6draft.ast.scope.Name) Completion(com.github.anba.es6draft.compiler.StatementGenerator.Completion) LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) BlockScope(com.github.anba.es6draft.ast.scope.BlockScope) ArrayList(java.util.ArrayList) List(java.util.List) DeclarativeEnvironmentRecord(com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord)

Example 2 with DeclarativeEnvironmentRecord

use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.

the class DefaultCodeGenerator method ClassDefinitionEvaluation.

/**
     * 14.5.14 Runtime Semantics: ClassDefinitionEvaluation
     * 
     * @param def
     *            the class definition node
     * @param className
     *            the class name or {@code null} if not present
     * @param mv
     *            the code visitor
     */
protected final void ClassDefinitionEvaluation(ClassDefinition def, Name className, CodeVisitor mv) {
    mv.enterVariableScope();
    Variable<ArrayList<Callable>> classDecorators = null;
    boolean hasClassDecorators = !def.getDecorators().isEmpty();
    if (hasClassDecorators) {
        classDecorators = newDecoratorVariable("classDecorators", mv);
        evaluateDecorators(classDecorators, def.getDecorators(), mv);
    }
    mv.enterClassDefinition();
    // step 1 (not applicable)
    // steps 2-4
    BlockScope scope = def.getScope();
    assert (scope != null && scope.isPresent()) == (className != null);
    Variable<DeclarativeEnvironmentRecord> classScopeEnvRec = null;
    if (className != null) {
        // stack: [] -> [classScope]
        newDeclarativeEnvironment(scope, mv);
        classScopeEnvRec = mv.newVariable("classScopeEnvRec", DeclarativeEnvironmentRecord.class);
        getEnvRec(classScopeEnvRec, mv);
        // stack: [classScope] -> [classScope]
        Name innerName = scope.resolveName(className, false);
        BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(classScopeEnvRec, innerName);
        op.createImmutableBinding(classScopeEnvRec, innerName, true, mv);
        // stack: [classScope] -> []
        pushLexicalEnvironment(mv);
        mv.enterScope(def);
    }
    // steps 5-7
    // stack: [] -> [<constructorParent,proto>]
    Expression classHeritage = def.getHeritage();
    if (classHeritage == null) {
        mv.loadExecutionContext();
        mv.invoke(Methods.ScriptRuntime_getDefaultClassProto);
    } else if (classHeritage instanceof NullLiteral) {
        mv.loadExecutionContext();
        mv.invoke(Methods.ScriptRuntime_getClassProto_Null);
    } else {
        expressionBoxed(classHeritage, mv);
        mv.loadExecutionContext();
        mv.lineInfo(def);
        mv.invoke(Methods.ScriptRuntime_getClassProto);
    }
    // stack: [<constructorParent,proto>] -> [<constructorParent,proto>]
    Variable<OrdinaryObject> proto = mv.newVariable("proto", OrdinaryObject.class);
    mv.dup();
    mv.aload(1, Types.ScriptObject);
    mv.checkcast(Types.OrdinaryObject);
    mv.store(proto);
    // stack: [<constructorParent,proto>] -> [constructorParent, proto]
    mv.aload(0, Types.ScriptObject);
    mv.load(proto);
    // steps 8-9
    // stack: [constructorParent, proto] -> [constructorParent, proto, <rti>]
    MethodDefinition constructor = ConstructorMethod(def);
    assert constructor != null;
    MethodName method = codegen.compile(def);
    // Runtime Semantics: Evaluation -> MethodDefinition
    mv.invoke(method);
    // step 10 (not applicable)
    // steps 11-18
    // stack: [constructorParent, proto, <rti>] -> [F]
    mv.iconst(classHeritage != null);
    mv.loadExecutionContext();
    mv.lineInfo(def);
    mv.invoke(Methods.ScriptRuntime_EvaluateConstructorMethod);
    // stack: [F] -> []
    Variable<OrdinaryConstructorFunction> F = mv.newVariable("F", OrdinaryConstructorFunction.class);
    mv.store(F);
    Variable<ArrayList<Object>> methodDecorators = null;
    boolean hasMethodDecorators = HasDecorators(def);
    if (hasMethodDecorators) {
        methodDecorators = newDecoratorVariable("methodDecorators", mv);
    }
    if (!constructor.getDecorators().isEmpty()) {
        addDecoratorObject(methodDecorators, proto, mv);
        evaluateDecorators(methodDecorators, constructor.getDecorators(), mv);
        addDecoratorKey(methodDecorators, "constructor", mv);
    }
    // steps 19-21
    ClassPropertyEvaluation(codegen, def.getProperties(), F, proto, methodDecorators, mv);
    if (hasClassDecorators) {
        mv.load(F);
        mv.load(classDecorators);
        mv.loadExecutionContext();
        mv.lineInfo(def);
        mv.invoke(Methods.ScriptRuntime_EvaluateClassDecorators);
    }
    if (hasMethodDecorators) {
        mv.load(methodDecorators);
        mv.loadExecutionContext();
        mv.lineInfo(def);
        mv.invoke(Methods.ScriptRuntime_EvaluateClassMethodDecorators);
    }
    // steps 22-23 (moved)
    if (className != null) {
        // stack: [] -> []
        Name innerName = scope.resolveName(className, false);
        BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(classScopeEnvRec, innerName);
        op.initializeBinding(classScopeEnvRec, innerName, F, mv);
        mv.exitScope();
        popLexicalEnvironment(mv);
    }
    // stack: [] -> [F]
    mv.load(F);
    mv.exitVariableScope();
    // step 24 (return F)
    mv.exitClassDefinition();
}
Also used : ArrayList(java.util.ArrayList) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) Name(com.github.anba.es6draft.ast.scope.Name) FieldName(com.github.anba.es6draft.compiler.assembler.FieldName) OrdinaryConstructorFunction(com.github.anba.es6draft.runtime.types.builtins.OrdinaryConstructorFunction) BlockScope(com.github.anba.es6draft.ast.scope.BlockScope) OrdinaryObject(com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) DeclarativeEnvironmentRecord(com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord)

Example 3 with DeclarativeEnvironmentRecord

use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.

the class EvalDeclarationInstantiationGenerator method declareBlockFunctions.

private <ENVREC extends EnvironmentRecord> void declareBlockFunctions(Script evalScript, HashSet<Name> declaredFunctionOrVarNames, Variable<ExecutionContext> context, Variable<LexicalEnvironment<ENVREC>> varEnv, Variable<LexicalEnvironment<DeclarativeEnvironmentRecord>> lexEnv, Variable<ENVREC> varEnvRec, Variable<Undefined> undef, InstructionVisitor mv) {
    final boolean catchVar = codegen.isEnabled(CompatibilityOption.CatchVarStatement);
    int idCounter = 0;
    List<FunctionDeclaration> blockFunctions = evalScript.getScope().blockFunctions();
    for (FunctionDeclaration f : blockFunctions) {
        Name fn = f.getName();
        Jump next = null;
        if (isEnclosedByLexical(evalScript)) {
            // Runtime check only necessary when enclosed by lexical declarations.
            f.setLegacyBlockScopeId(++idCounter);
            next = new Jump();
            canDeclareVarBinding(varEnv, lexEnv, fn, catchVar, next, mv);
            setLegacyBlockFunction(context, f, mv);
        }
        if (declaredFunctionOrVarNames.add(fn)) {
            BindingOp<EnvironmentRecord> op = BindingOp.LOOKUP;
            Jump varAlreadyDeclared = new Jump();
            op.hasBinding(varEnvRec, fn, mv);
            mv.ifne(varAlreadyDeclared);
            {
                op.createMutableBinding(varEnvRec, fn, true, mv);
                op.initializeBinding(varEnvRec, fn, undef, mv);
            }
            mv.mark(varAlreadyDeclared);
        }
        if (next != null) {
            mv.mark(next);
        }
    }
}
Also used : FunctionDeclaration(com.github.anba.es6draft.ast.FunctionDeclaration) Jump(com.github.anba.es6draft.compiler.assembler.Jump) EnvironmentRecord(com.github.anba.es6draft.runtime.EnvironmentRecord) GlobalEnvironmentRecord(com.github.anba.es6draft.runtime.GlobalEnvironmentRecord) DeclarativeEnvironmentRecord(com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord) ScriptName(com.github.anba.es6draft.compiler.CodeGenerator.ScriptName) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) Name(com.github.anba.es6draft.ast.scope.Name)

Example 4 with DeclarativeEnvironmentRecord

use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.

the class StatementGenerator method visit.

/**
     * 14.1.20 Runtime Semantics: Evaluation
     */
@Override
public Completion visit(FunctionDeclaration node, CodeVisitor mv) {
    /* B.3.3 Block-Level Function Declarations Web Legacy Compatibility Semantics */
    if (node.isLegacyBlockScoped()) {
        Name name = node.getIdentifier().getName();
        TopLevelScope top = mv.getScope().getTop();
        if (mv.isFunction()) {
            assert top instanceof FunctionScope;
            Name varName = ((FunctionScope) top).variableScope().resolveName(name, false);
            assert varName != null && name != varName;
            /* step 1.a.ii.3.1 */
            Value<DeclarativeEnvironmentRecord> fenv = getVariableEnvironmentRecord(Types.DeclarativeEnvironmentRecord, mv);
            /* steps 1.a.ii.3.5-6 */
            BindingOp.of(fenv, varName).setMutableBinding(fenv, varName, asm -> {
                Value<DeclarativeEnvironmentRecord> benv = getLexicalEnvironmentRecord(Types.DeclarativeEnvironmentRecord, mv);
                BindingOp.of(benv, name).getBindingValue(benv, name, false, mv);
            }, false, mv);
        } else {
            assert top instanceof ScriptScope;
            Name varName = name;
            int functionId = node.getLegacyBlockScopeId();
            Jump isLegacyScoped = null;
            if (functionId > 0) {
                isLegacyScoped = new Jump();
                mv.loadExecutionContext();
                mv.iconst(functionId);
                mv.invoke(Methods.ScriptRuntime_isLegacyBlockFunction);
                mv.ifeq(isLegacyScoped);
            }
            // The variable environment record is either:
            // 1. The global environment record for global (eval) scripts.
            // 2. Or a (function) declarative environment record for eval in functions.
            // 3. Or a script-context environment record for eval in JSR-223 scripting.
            Value<EnvironmentRecord> genv = getVariableEnvironmentRecord(Types.EnvironmentRecord, mv);
            BindingOp.of(genv, varName).setMutableBinding(genv, varName, asm -> {
                Value<DeclarativeEnvironmentRecord> benv = getLexicalEnvironmentRecord(Types.DeclarativeEnvironmentRecord, mv);
                BindingOp.of(benv, name).getBindingValue(benv, name, false, mv);
            }, false, mv);
            if (isLegacyScoped != null) {
                mv.mark(isLegacyScoped);
            }
        }
    }
    /* step 1 */
    return Completion.Empty;
}
Also used : ScriptScope(com.github.anba.es6draft.ast.scope.ScriptScope) TopLevelScope(com.github.anba.es6draft.ast.scope.TopLevelScope) FunctionScope(com.github.anba.es6draft.ast.scope.FunctionScope) DeclarativeEnvironmentRecord(com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord) Jump(com.github.anba.es6draft.compiler.assembler.Jump) EnvironmentRecord(com.github.anba.es6draft.runtime.EnvironmentRecord) DeclarativeEnvironmentRecord(com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord) InitializeBoundName(com.github.anba.es6draft.compiler.BindingInitializationGenerator.InitializeBoundName) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) Name(com.github.anba.es6draft.ast.scope.Name)

Example 5 with DeclarativeEnvironmentRecord

use of com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord in project es6draft by anba.

the class ScriptRuntime method EvaluateFunctionExpression.

/**
     * 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 OrdinaryConstructorFunction EvaluateFunctionExpression(RuntimeInfo.Function fd, ExecutionContext cx) {
    OrdinaryConstructorFunction closure;
    if (!fd.is(RuntimeInfo.FunctionFlags.ScopedName)) {
        /* step 1 (not applicable) */
        /* step 2 */
        LexicalEnvironment<?> scope = cx.getLexicalEnvironment();
        /* step 3 */
        closure = ConstructorFunctionCreate(cx, FunctionKind.Normal, 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 = ConstructorFunctionCreate(cx, FunctionKind.Normal, 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 : ConsString(org.mozilla.javascript.ConsString) DeclarativeEnvironmentRecord(com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord)

Aggregations

DeclarativeEnvironmentRecord (com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord)25 Name (com.github.anba.es6draft.ast.scope.Name)16 MethodName (com.github.anba.es6draft.compiler.assembler.MethodName)15 LexicalEnvironment (com.github.anba.es6draft.runtime.LexicalEnvironment)8 BlockScope (com.github.anba.es6draft.ast.scope.BlockScope)7 Jump (com.github.anba.es6draft.compiler.assembler.Jump)7 ConsString (org.mozilla.javascript.ConsString)7 EnvironmentRecord (com.github.anba.es6draft.runtime.EnvironmentRecord)6 GlobalEnvironmentRecord (com.github.anba.es6draft.runtime.GlobalEnvironmentRecord)6 ScriptName (com.github.anba.es6draft.compiler.CodeGenerator.ScriptName)5 HoistableDeclaration (com.github.anba.es6draft.ast.HoistableDeclaration)4 InitializeBoundName (com.github.anba.es6draft.compiler.BindingInitializationGenerator.InitializeBoundName)4 ExecutionContext (com.github.anba.es6draft.runtime.ExecutionContext)4 FunctionObject (com.github.anba.es6draft.runtime.types.builtins.FunctionObject)4 Declaration (com.github.anba.es6draft.ast.Declaration)3 FunctionDeclaration (com.github.anba.es6draft.ast.FunctionDeclaration)3 StatementListItem (com.github.anba.es6draft.ast.StatementListItem)3 ArrayDeque (java.util.ArrayDeque)3 HashSet (java.util.HashSet)3 LinkedHashSet (java.util.LinkedHashSet)3