Search in sources :

Example 26 with Statement

use of com.google.template.soy.jbcsrc.restricted.Statement in project closure-templates by google.

the class TemplateCompiler method generateRenderMethod.

private Statement generateRenderMethod() {
    final Label start = new Label();
    final Label end = new Label();
    final LocalVariable thisVar = createThisVar(template.typeInfo(), start, end);
    final LocalVariable appendableVar = createLocal("appendable", 1, LOGGING_ADVISING_APPENDABLE_TYPE, start, end).asNonNullable();
    final LocalVariable contextVar = createLocal("context", 2, RENDER_CONTEXT_TYPE, start, end).asNonNullable();
    final TemplateVariableManager variableSet = new TemplateVariableManager(fieldNames, template.typeInfo(), thisVar, template.renderMethod().method());
    TemplateNode node = template.node();
    TemplateVariables variables = new TemplateVariables(variableSet, thisVar, new RenderContextExpression(contextVar));
    final CompiledMethodBody methodBody = SoyNodeCompiler.create(registry, innerClasses, stateField, thisVar, AppendableExpression.forLocal(appendableVar), variableSet, variables).compile(node);
    final Statement returnDone = Statement.returnExpression(MethodRef.RENDER_RESULT_DONE.invoke());
    new Statement() {

        @Override
        protected void doGen(CodeBuilder adapter) {
            adapter.mark(start);
            methodBody.body().gen(adapter);
            adapter.mark(end);
            returnDone.gen(adapter);
            thisVar.tableEntry(adapter);
            appendableVar.tableEntry(adapter);
            contextVar.tableEntry(adapter);
            variableSet.generateTableEntries(adapter);
        }
    }.writeIOExceptionMethod(Opcodes.ACC_PUBLIC, template.renderMethod().method(), writer);
    writer.setNumDetachStates(methodBody.numberOfDetachStates());
    variableSet.defineStaticFields(writer);
    return variableSet.defineFields(writer);
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) Statement(com.google.template.soy.jbcsrc.restricted.Statement) Label(org.objectweb.asm.Label) LocalVariable(com.google.template.soy.jbcsrc.restricted.LocalVariable) CompiledMethodBody(com.google.template.soy.jbcsrc.SoyNodeCompiler.CompiledMethodBody) CodeBuilder(com.google.template.soy.jbcsrc.restricted.CodeBuilder)

Example 27 with Statement

use of com.google.template.soy.jbcsrc.restricted.Statement in project closure-templates by google.

the class TemplateFactoryCompiler method generateCreateMethod.

/**
 * Writes the {@link CompiledTemplate.Factory#create} method, which directly delegates to the
 * constructor of the {@link #template}.
 */
private void generateCreateMethod(ClassVisitor cv, TypeInfo factoryType) {
    final Label start = new Label();
    final Label end = new Label();
    final LocalVariable thisVar = createThisVar(factoryType, start, end);
    final LocalVariable paramsVar = createLocal("params", 1, SOY_RECORD_TYPE, start, end);
    final LocalVariable ijVar = createLocal("ij", 2, SOY_RECORD_TYPE, start, end);
    final Statement returnTemplate = Statement.returnExpression(template.constructor().construct(paramsVar, ijVar));
    new Statement() {

        @Override
        protected void doGen(CodeBuilder ga) {
            ga.mark(start);
            returnTemplate.gen(ga);
            ga.mark(end);
            thisVar.tableEntry(ga);
            paramsVar.tableEntry(ga);
            ijVar.tableEntry(ga);
        }
    }.writeMethod(Opcodes.ACC_PUBLIC, CREATE_METHOD, cv);
}
Also used : Statement(com.google.template.soy.jbcsrc.restricted.Statement) Label(org.objectweb.asm.Label) LocalVariable(com.google.template.soy.jbcsrc.restricted.LocalVariable) CodeBuilder(com.google.template.soy.jbcsrc.restricted.CodeBuilder)

Example 28 with Statement

use of com.google.template.soy.jbcsrc.restricted.Statement in project closure-templates by google.

the class TemplateVariableManager method enterScope.

/**
 * Enters a new scope. Variables may only be defined within a scope.
 */
Scope enterScope() {
    final Map<VarKey, Variable> currentFrame = new LinkedHashMap<>();
    final Label scopeExit = new Label();
    frames.push(currentFrame);
    return new Scope() {

        boolean exited;

        @Override
        Variable createSynthetic(SyntheticVarName varName, Expression initExpr, SaveStrategy strategy) {
            checkState(!exited, "Scope already exited");
            VarKey key = VarKey.create(Kind.SYNTHETIC, varName.name());
            // synthetics are prefixed by $ by convention
            String name = fieldNames.generateName("$" + varName.name());
            return doCreate(name, new Label(), scopeExit, initExpr, key, strategy);
        }

        @Override
        Variable createTemporary(String name, Expression initExpr) {
            checkState(!exited, "Scope already exited");
            VarKey key = VarKey.create(Kind.TEMPORARY, name);
            name = fieldNames.generateName("$$" + name);
            return doCreate(name, new Label(), scopeExit, initExpr, key, SaveStrategy.NEVER);
        }

        @Override
        Variable create(String name, Expression initExpr, SaveStrategy strategy) {
            checkState(!exited, "Scope already exited");
            VarKey key = VarKey.create(Kind.USER_DEFINED, name);
            name = fieldNames.generateName(name);
            return doCreate(name, new Label(), scopeExit, initExpr, key, strategy);
        }

        @Override
        Statement exitScope() {
            checkState(!exited, "Scope already exited");
            exited = true;
            frames.pop();
            // Use identity semantics to make sure we visit each label at most once.  visiting a label
            // more than once tends to corrupt internal asm state.
            final Set<Label> endLabels = Sets.newIdentityHashSet();
            for (Variable var : currentFrame.values()) {
                endLabels.add(var.local.end());
                availableSlots.clear(var.local.index(), var.local.index() + var.local.resultType().getSize());
            }
            return new Statement() {

                // TODO(lukes): we could generate null writes for when object typed fields go out of
                // scope.  This would potentially allow intermediate results to be collected sooner.
                @Override
                protected void doGen(CodeBuilder adapter) {
                    for (Label label : endLabels) {
                        adapter.visitLabel(label);
                    }
                }
            };
        }

        private Variable doCreate(String name, Label start, Label end, Expression initExpr, VarKey key, SaveStrategy strategy) {
            int index = reserveSlotFor(initExpr.resultType());
            LocalVariable local = LocalVariable.createLocal(name, index, initExpr.resultType(), start, end);
            Variable var;
            switch(strategy) {
                case DERIVED:
                    var = new DerivedVariable(initExpr, local);
                    break;
                case NEVER:
                    var = new TemporaryVariable(initExpr, local);
                    break;
                case STORE:
                    var = new FieldSavedVariable(initExpr, local);
                    break;
                default:
                    throw new AssertionError();
            }
            currentFrame.put(key, var);
            allVariables.add(var);
            return var;
        }
    };
}
Also used : LocalVariable(com.google.template.soy.jbcsrc.restricted.LocalVariable) Statement(com.google.template.soy.jbcsrc.restricted.Statement) Label(org.objectweb.asm.Label) LocalVariable(com.google.template.soy.jbcsrc.restricted.LocalVariable) LinkedHashMap(java.util.LinkedHashMap) CodeBuilder(com.google.template.soy.jbcsrc.restricted.CodeBuilder) Expression(com.google.template.soy.jbcsrc.restricted.Expression)

Example 29 with Statement

use of com.google.template.soy.jbcsrc.restricted.Statement in project closure-templates by google.

the class TemplateVariableManager method saveRestoreState.

/**
 * Returns a {@link SaveRestoreState} for the current state of the variable set.
 */
SaveRestoreState saveRestoreState() {
    List<Statement> saves = new ArrayList<>();
    List<Statement> restores = new ArrayList<>();
    // derived fields work correctly.
    for (Iterator<Map<VarKey, Variable>> iterator = frames.descendingIterator(); iterator.hasNext(); ) {
        Map<VarKey, Variable> frame = iterator.next();
        for (Variable var : frame.values()) {
            saves.add(var.save());
            restores.add(var.restore());
        }
    }
    return new AutoValue_TemplateVariableManager_SaveRestoreState(Statement.concat(saves), Statement.concat(restores));
}
Also used : LocalVariable(com.google.template.soy.jbcsrc.restricted.LocalVariable) Statement(com.google.template.soy.jbcsrc.restricted.Statement) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 30 with Statement

use of com.google.template.soy.jbcsrc.restricted.Statement in project closure-templates by google.

the class ControlFlow method ifElseChain.

/**
 * Returns a statement that encodes the given sequence of {@link IfBlock if blocks} as an
 * if-elseif-else chain.
 */
static Statement ifElseChain(final List<IfBlock> ifs, final Optional<Statement> elseBlock) {
    checkArgument(!ifs.isEmpty());
    return new Statement() {

        @Override
        protected void doGen(CodeBuilder adapter) {
            Label end = new Label();
            Label next;
            for (int i = 0; i < ifs.size(); i++) {
                IfBlock curr = ifs.get(i);
                boolean isLastIfBlock = i == ifs.size() - 1;
                if (isLastIfBlock && !elseBlock.isPresent()) {
                    next = end;
                } else {
                    next = new Label();
                }
                curr.condition().gen(adapter);
                adapter.ifZCmp(Opcodes.IFEQ, next);
                curr.block().gen(adapter);
                if (end != next) {
                    adapter.goTo(end);
                }
                adapter.mark(next);
            }
            if (elseBlock.isPresent()) {
                elseBlock.get().gen(adapter);
                adapter.mark(end);
            }
        }
    };
}
Also used : Statement(com.google.template.soy.jbcsrc.restricted.Statement) Label(org.objectweb.asm.Label) CodeBuilder(com.google.template.soy.jbcsrc.restricted.CodeBuilder)

Aggregations

Statement (com.google.template.soy.jbcsrc.restricted.Statement)30 Expression (com.google.template.soy.jbcsrc.restricted.Expression)15 Label (org.objectweb.asm.Label)14 CodeBuilder (com.google.template.soy.jbcsrc.restricted.CodeBuilder)13 SoyExpression (com.google.template.soy.jbcsrc.restricted.SoyExpression)11 ArrayList (java.util.ArrayList)8 LocalVariable (com.google.template.soy.jbcsrc.restricted.LocalVariable)7 Scope (com.google.template.soy.jbcsrc.TemplateVariableManager.Scope)5 Variable (com.google.template.soy.jbcsrc.TemplateVariableManager.Variable)4 AppendableAndOptions (com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective.Streamable.AppendableAndOptions)4 IfBlock (com.google.template.soy.jbcsrc.ControlFlow.IfBlock)3 SaveRestoreState (com.google.template.soy.jbcsrc.TemplateVariableManager.SaveRestoreState)3 FieldRef (com.google.template.soy.jbcsrc.restricted.FieldRef)3 LinkedHashMap (java.util.LinkedHashMap)3 ExprRootNode (com.google.template.soy.exprtree.ExprRootNode)2 ClassData (com.google.template.soy.jbcsrc.internal.ClassData)2 Statement.returnExpression (com.google.template.soy.jbcsrc.restricted.Statement.returnExpression)2 RangeArgs (com.google.template.soy.shared.RangeArgs)2 SoyPrintDirective (com.google.template.soy.shared.restricted.SoyPrintDirective)2 ForNonemptyNode (com.google.template.soy.soytree.ForNonemptyNode)2