List of usage examples for org.objectweb.asm Label Label
public Label()
From source file:com.google.template.soy.jbcsrc.SoyNodeCompiler.java
License:Apache License
@Override protected Statement visitForeachNode(ForeachNode node) { ForeachNonemptyNode nonEmptyNode = (ForeachNonemptyNode) node.getChild(0); SoyExpression expr = exprCompiler.compile(node.getExpr()).unboxAs(List.class); Scope scope = variables.enterScope(); final Variable listVar = scope.createSynthetic(SyntheticVarName.foreachLoopList(nonEmptyNode), expr, STORE); final Variable indexVar = scope.createSynthetic(SyntheticVarName.foreachLoopIndex(nonEmptyNode), constant(0), STORE);/*from w w w. jav a2s .c o m*/ final Variable listSizeVar = scope.createSynthetic(SyntheticVarName.foreachLoopLength(nonEmptyNode), MethodRef.LIST_SIZE.invoke(listVar.local()), DERIVED); final Variable itemVar = scope.create(nonEmptyNode.getVarName(), MethodRef.LIST_GET.invoke(listVar.local(), indexVar.local()).cast(SOY_VALUE_PROVIDER_TYPE), SaveStrategy.DERIVED); final Statement loopBody = visitChildrenInNewScope(nonEmptyNode); final Statement exitScope = scope.exitScope(); // it important for this to be generated after exitScope is called (or before enterScope) final Statement emptyBlock = node.numChildren() == 2 ? visitChildrenInNewScope((ForeachIfemptyNode) node.getChild(1)) : null; return new Statement() { @Override void doGen(CodeBuilder adapter) { listVar.initializer().gen(adapter); listSizeVar.initializer().gen(adapter); listSizeVar.local().gen(adapter); Label emptyListLabel = new Label(); adapter.ifZCmp(Opcodes.IFEQ, emptyListLabel); indexVar.initializer().gen(adapter); Label loopStart = adapter.mark(); itemVar.initializer().gen(adapter); loopBody.gen(adapter); adapter.iinc(indexVar.local().index(), 1); // index++ indexVar.local().gen(adapter); listSizeVar.local().gen(adapter); adapter.ifICmp(Opcodes.IFLT, loopStart); // if index < list.size(), goto loopstart // exit the loop exitScope.gen(adapter); if (emptyBlock != null) { Label skipIfEmptyBlock = new Label(); adapter.goTo(skipIfEmptyBlock); adapter.mark(emptyListLabel); emptyBlock.gen(adapter); adapter.mark(skipIfEmptyBlock); } else { adapter.mark(emptyListLabel); } } }; }
From source file:com.google.template.soy.jbcsrc.SoyNodeCompiler.java
License:Apache License
@Override protected Statement visitPrintNode(PrintNode node) { // First check our special case for compatible content types (no print directives) and an // expression that evaluates to a SoyValueProvider. This will allow us to render incrementally if (node.getChildren().isEmpty()) { Label reattachPoint = new Label(); ExprRootNode expr = node.getExprUnion().getExpr(); Optional<Expression> asSoyValueProvider = expressionToSoyValueProviderCompiler .compileAvoidingBoxing(expr, reattachPoint); if (asSoyValueProvider.isPresent()) { return renderIncrementally(node, asSoyValueProvider.get(), reattachPoint); }/* w w w. j a v a 2 s. c o m*/ } // otherwise we need to do some escapes or simply cannot do incremental rendering Label reattachPoint = new Label(); SoyExpression value = compilePrintNodeAsExpression(node, reattachPoint); AppendableExpression renderSoyValue = appendableExpression.appendString(value.coerceToString()) .labelStart(reattachPoint); return detachState.detachLimited(renderSoyValue).withSourceLocation(node.getSourceLocation()); }
From source file:com.google.template.soy.jbcsrc.SoyNodeCompiler.java
License:Apache License
@Override protected Statement visitCssNode(CssNode node) { Expression renamedSelector = variableLookup.getRenderContext() .invoke(MethodRef.RENDER_CONTEXT_RENAME_CSS_SELECTOR, constant(node.getSelectorText())); if (node.getComponentNameExpr() != null) { Label reattachPoint = new Label(); SoyExpression compiledComponent = exprCompiler.compile(node.getComponentNameExpr(), reattachPoint) .coerceToString();/*from w w w. j av a2 s. c o m*/ return appendableExpression.appendString(compiledComponent).appendChar(constant('-')) .appendString(renamedSelector).labelStart(reattachPoint).toStatement() .withSourceLocation(node.getSourceLocation()); } return appendableExpression.appendString(renamedSelector).toStatement() .withSourceLocation(node.getSourceLocation()); }
From source file:com.google.template.soy.jbcsrc.SoyNodeCompiler.java
License:Apache License
/** * Given this delcall:/*w ww. ja v a 2s.co m*/ * {@code {delcall foo.bar variant="$expr" allowemptydefault="true"}} * * Generate code that looks like: * <pre> {@code * renderContext.getDeltemplate("foo.bar", <variant-expression>, true) * .create(<prepareParameters>, ijParams) * .render(appendable, renderContext) * * }</pre> * * <p>We share logic with {@link #visitCallBasicNode(CallBasicNode)} around the actual calling * convention (setting up detaches, storing the template in a field). As well as the logic for * preparing the data record. The only interesting part of delcalls is calculating the * {@code variant} and the fact that we have to invoke the {@link RenderContext} runtime to do * the deltemplate lookup. */ @Override protected Statement visitCallDelegateNode(CallDelegateNode node) { Label reattachPoint = new Label(); Expression variantExpr; if (node.getDelCalleeVariantExpr() == null) { variantExpr = constant(""); } else { variantExpr = exprCompiler.compile(node.getDelCalleeVariantExpr(), reattachPoint).coerceToString(); } Expression calleeExpression = variableLookup.getRenderContext().invoke( MethodRef.RENDER_CONTEXT_GET_DELTEMPLATE, constant(node.getDelCalleeName()), variantExpr, constant(node.allowsEmptyDefault()), prepareParamsHelper(node, reattachPoint), variableLookup.getIjRecord()); return visitCallNodeHelper(node, registry.getDelTemplateContentKind(node.getDelCalleeName()), reattachPoint, calleeExpression); }
From source file:com.google.template.soy.jbcsrc.SoyNodeCompiler.java
License:Apache License
@Override protected Statement visitCallBasicNode(CallBasicNode node) { // Basic nodes are basic! We can just call the node directly. CompiledTemplateMetadata callee = registry.getTemplateInfoByTemplateName(node.getCalleeName()); Label reattachPoint = new Label(); Expression calleeExpression = callee.constructor().construct(prepareParamsHelper(node, reattachPoint), variableLookup.getIjRecord()); return visitCallNodeHelper(node, callee.node().getContentKind(), reattachPoint, calleeExpression); }
From source file:com.google.template.soy.jbcsrc.TemplateCompiler.java
License:Apache License
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, ADVISING_APPENDABLE_TYPE, start, end) .asNonNullable();/*from ww w . j av a2s . c o m*/ final LocalVariable contextVar = createLocal("context", 2, RENDER_CONTEXT_TYPE, start, end).asNonNullable(); final VariableSet variableSet = new VariableSet(fieldNames, template.typeInfo(), thisVar, template.renderMethod().method()); TemplateNode node = template.node(); TemplateVariables variables = new TemplateVariables(variableSet, thisVar, 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 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); }
From source file:com.google.template.soy.jbcsrc.TemplateCompiler.java
License:Apache License
/** * Generate a public constructor that assigns our final field and checks for missing required * params./* www.ja v a 2s . c o m*/ * * <p>This constructor is called by the generate factory classes. * * @param fieldInitializers additional statements to initialize fields (other than params) */ private void generateConstructor(Statement fieldInitializers) { final Label start = new Label(); final Label end = new Label(); final LocalVariable thisVar = createThisVar(template.typeInfo(), 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 List<Statement> assignments = new ArrayList<>(); assignments.add(fieldInitializers); // for other fields needed by the compiler. assignments.add(paramsField.putInstanceField(thisVar, paramsVar)); assignments.add(ijField.putInstanceField(thisVar, ijVar)); for (final TemplateParam param : template.node().getAllParams()) { Expression paramProvider = getParam(paramsVar, ijVar, param); assignments.add(paramFields.get(param.name()).putInstanceField(thisVar, paramProvider)); } Statement constructorBody = new Statement() { @Override void doGen(CodeBuilder ga) { ga.mark(start); // call super() thisVar.gen(ga); ga.invokeConstructor(OBJECT.type(), NULLARY_INIT); for (Statement assignment : assignments) { assignment.gen(ga); } ga.visitInsn(Opcodes.RETURN); ga.visitLabel(end); thisVar.tableEntry(ga); paramsVar.tableEntry(ga); ijVar.tableEntry(ga); } }; constructorBody.writeMethod(Opcodes.ACC_PUBLIC, template.constructor().method(), writer); }
From source file:com.google.template.soy.jbcsrc.TemplateFactoryCompiler.java
License:Apache License
/** * Writes the {@link CompiledTemplate.Factory#create} method, which directly delegates to the * constructor of the {@link #template}. */// w w w . j a v a 2 s .c o m 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 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); }
From source file:com.google.template.soy.jbcsrc.TemplateVariableManager.java
License:Apache License
/** * Enters a new scope. Variables may only be defined within a scope. *//*from www . j av a 2s . c o m*/ Scope enterScope() { final Map<VarKey, Variable> currentFrame = new LinkedHashMap<>(); final Label scopeExit = new Label(); frames.push(currentFrame); return new Scope() { @Override Variable createSynthetic(SyntheticVarName varName, Expression initExpr, SaveStrategy strategy) { 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 create(String name, Expression initExpr, SaveStrategy strategy) { VarKey key = VarKey.create(Kind.USER_DEFINED, name); name = fieldNames.generateName(name); return doCreate(name, new Label(), scopeExit, initExpr, key, strategy); } @Override Statement exitScope() { 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 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 STORE: var = new FieldSavedVariable(initExpr, local); break; default: throw new AssertionError(); } currentFrame.put(key, var); allVariables.add(var); return var; } }; }
From source file:com.google.template.soy.jbcsrc.VariableSet.java
License:Apache License
/** * Enters a new scope. Variables may only be defined within a scope. *//* ww w.j av a 2s . c o m*/ Scope enterScope() { final Map<VarKey, Variable> currentFrame = new LinkedHashMap<>(); final Label scopeExit = new Label(); frames.push(currentFrame); return new Scope() { @Override Variable createSynthetic(SyntheticVarName varName, Expression initExpr, SaveStrategy strategy) { 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 create(String name, Expression initExpr, SaveStrategy strategy) { VarKey key = VarKey.create(Kind.USER_DEFINED, name); name = fieldNames.generateName(name); return doCreate(name, new Label(), scopeExit, initExpr, key, strategy); } @Override Statement exitScope() { 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 = Collections.newSetFromMap(new IdentityHashMap<Label, Boolean>()); 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 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 STORE: var = new FieldSavedVariable(initExpr, local); break; default: throw new AssertionError(); } currentFrame.put(key, var); allVariables.add(var); return var; } }; }