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);
}
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;
}
};
}
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);
}
}
};
}
Aggregations