Search in sources :

Example 11 with CodeBuilder

use of com.google.template.soy.jbcsrc.restricted.CodeBuilder 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 12 with CodeBuilder

use of com.google.template.soy.jbcsrc.restricted.CodeBuilder 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 13 with CodeBuilder

use of com.google.template.soy.jbcsrc.restricted.CodeBuilder 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

CodeBuilder (com.google.template.soy.jbcsrc.restricted.CodeBuilder)13 Statement (com.google.template.soy.jbcsrc.restricted.Statement)13 Label (org.objectweb.asm.Label)11 Expression (com.google.template.soy.jbcsrc.restricted.Expression)8 LocalVariable (com.google.template.soy.jbcsrc.restricted.LocalVariable)6 ArrayList (java.util.ArrayList)4 SoyExpression (com.google.template.soy.jbcsrc.restricted.SoyExpression)3 SaveRestoreState (com.google.template.soy.jbcsrc.TemplateVariableManager.SaveRestoreState)2 Scope (com.google.template.soy.jbcsrc.TemplateVariableManager.Scope)2 Variable (com.google.template.soy.jbcsrc.TemplateVariableManager.Variable)2 Statement.returnExpression (com.google.template.soy.jbcsrc.restricted.Statement.returnExpression)2 CompiledMethodBody (com.google.template.soy.jbcsrc.SoyNodeCompiler.CompiledMethodBody)1 ClassData (com.google.template.soy.jbcsrc.internal.ClassData)1 SoyClassWriter (com.google.template.soy.jbcsrc.internal.SoyClassWriter)1 AppendableAndOptions (com.google.template.soy.jbcsrc.restricted.SoyJbcSrcPrintDirective.Streamable.AppendableAndOptions)1 TypeInfo (com.google.template.soy.jbcsrc.restricted.TypeInfo)1 RangeArgs (com.google.template.soy.shared.RangeArgs)1 ForNonemptyNode (com.google.template.soy.soytree.ForNonemptyNode)1 TemplateNode (com.google.template.soy.soytree.TemplateNode)1 TemplateParam (com.google.template.soy.soytree.defn.TemplateParam)1