List of usage examples for org.objectweb.asm Label Label
public Label()
From source file:com.google.template.soy.jbcsrc.MsgCompiler.java
License:Apache License
/** * Returns a statement that adds the content rendered by the call to the map. * * @param mapExpression The map to put the new entry in * @param mapKey The map key/*from ww w .j a v a 2s. com*/ * @param printNode The node */ private Statement addPrintNodeToPlaceholderMap(Expression mapExpression, String mapKey, PrintNode printNode) { // This is much like the escaping path of visitPrintNode but somewhat simpler because our // ultimate target is a string rather than putting bytes on the output stream. Label reattachPoint = new Label(); Expression compileToString = soyNodeCompiler.compileToString(printNode, reattachPoint); return putToMap(mapExpression, mapKey, compileToString).labelStart(reattachPoint); }
From source file:com.google.template.soy.jbcsrc.PluginFunctionCompiler.java
License:Apache License
/** * @see com.google.template.soy.basicfunctions.IsNonnullFunction *//*from ww w . j av a2 s .com*/ private SoyExpression invokeIsNonnullFunction(final SoyExpression soyExpression) { if (BytecodeUtils.isPrimitive(soyExpression.resultType())) { return SoyExpression.TRUE; } return SoyExpression.forBool(new Expression(Type.BOOLEAN_TYPE, soyExpression.features()) { @Override void doGen(CodeBuilder adapter) { soyExpression.gen(adapter); Label isNull = new Label(); adapter.ifNull(isNull); // non-null adapter.pushBoolean(true); Label end = new Label(); adapter.goTo(end); adapter.mark(isNull); adapter.pushBoolean(false); adapter.mark(end); } }); }
From source file:com.google.template.soy.jbcsrc.restricted.BytecodeProducer.java
License:Apache License
/** Writes the bytecode to the adapter. */ public final void gen(CodeBuilder adapter) { boolean shouldClearIsGeneratingBit = false; if (Flags.DEBUG && !isGenerating.get()) { isGenerating.set(true);// ww w. j av a 2s .c o m shouldClearIsGeneratingBit = true; } try { if (location.isKnown()) { // These add entries to the line number tables that are associated with the current method. // The line number table is just a mapping of bytecode offset (aka 'pc') to line number, // http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.12 // It is used by the JVM to add source data to stack traces and by debuggers to highlight // source files. Label start = new Label(); adapter.mark(start); adapter.visitLineNumber(location.getBeginLine(), start); } doGen(adapter); if (location.isKnown()) { Label end = new Label(); adapter.mark(end); adapter.visitLineNumber(location.getEndLine(), end); } } finally { if (shouldClearIsGeneratingBit) { isGenerating.set(false); } } }
From source file:com.google.template.soy.jbcsrc.restricted.BytecodeUtils.java
License:Apache License
/** * Returns an expression that evaluates to {@code left} if left is non null, and evaluates to * {@code right} otherwise./*from w w w . jav a2 s . com*/ */ public static Expression firstNonNull(final Expression left, final Expression right) { checkArgument(left.resultType().getSort() == Type.OBJECT); checkArgument(right.resultType().getSort() == Type.OBJECT); Features features = Features.of(); if (Expression.areAllCheap(left, right)) { features = features.plus(Feature.CHEAP); } if (right.isNonNullable()) { features = features.plus(Feature.NON_NULLABLE); } return new Expression(left.resultType(), features) { @Override protected void doGen(CodeBuilder cb) { Label leftIsNonNull = new Label(); left.gen(cb); // Stack: L cb.dup(); // Stack: L, L cb.ifNonNull(leftIsNonNull); // Stack: L // pop the extra copy of left cb.pop(); // Stack: right.gen(cb); // Stack: R cb.mark(leftIsNonNull); // At this point the stack has an instance of L or R } }; }
From source file:com.google.template.soy.jbcsrc.restricted.BytecodeUtils.java
License:Apache License
/** * Returns an expression that evaluates equivalently to a java ternary expression: {@code * condition ? left : right}//from w w w . j ava 2 s . c o m */ public static Expression ternary(final Expression condition, final Expression trueBranch, final Expression falseBranch) { checkArgument(condition.resultType().equals(Type.BOOLEAN_TYPE)); checkArgument(trueBranch.resultType().getSort() == falseBranch.resultType().getSort()); Features features = Features.of(); if (Expression.areAllCheap(condition, trueBranch, falseBranch)) { features = features.plus(Feature.CHEAP); } if (trueBranch.isNonNullable() && falseBranch.isNonNullable()) { features = features.plus(Feature.NON_NULLABLE); } return new Expression(trueBranch.resultType(), features) { @Override protected void doGen(CodeBuilder mv) { condition.gen(mv); Label ifFalse = new Label(); Label end = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, ifFalse); // if 0 goto ifFalse trueBranch.gen(mv); // eval true branch mv.visitJumpInsn(Opcodes.GOTO, end); // jump to the end mv.visitLabel(ifFalse); falseBranch.gen(mv); // eval false branch mv.visitLabel(end); } }; }
From source file:com.google.template.soy.jbcsrc.restricted.BytecodeUtils.java
License:Apache License
private static Expression doShortCircuitingLogicalOperator( final ImmutableList<? extends Expression> expressions, final boolean isOrOperator) { checkArgument(!expressions.isEmpty()); for (Expression expr : expressions) { expr.checkAssignableTo(Type.BOOLEAN_TYPE); }/*from w w w . ja v a 2 s.c o m*/ if (expressions.size() == 1) { return expressions.get(0); } return new Expression(Type.BOOLEAN_TYPE, Expression.areAllCheap(expressions) ? Features.of(Feature.CHEAP) : Features.of()) { @Override protected void doGen(CodeBuilder adapter) { Label end = new Label(); Label shortCircuit = new Label(); for (int i = 0; i < expressions.size(); i++) { Expression expr = expressions.get(i); expr.gen(adapter); if (i == expressions.size() - 1) { // if we are the last one, just goto end. Whatever the result of the last expression is // determines the result of the whole expression (when all prior tests fail). adapter.goTo(end); } else { adapter.ifZCmp(isOrOperator ? Opcodes.IFNE : Opcodes.IFEQ, shortCircuit); } } adapter.mark(shortCircuit); adapter.pushBoolean(isOrOperator); // default for || is true && is false adapter.mark(end); } }; }
From source file:com.google.template.soy.jbcsrc.restricted.BytecodeUtils.java
License:Apache License
/** * Outputs bytecode that will test the item at the top of the stack for null, and branch to {@code * nullExit} if it is {@code null}. At {@code nullSafeExit} there will be a null value at the top * of the stack./* w w w . ja v a2 s. c om*/ */ public static void nullCoalesce(CodeBuilder builder, Label nullExit) { builder.dup(); Label nonNull = new Label(); builder.ifNonNull(nonNull); // See http://mail.ow2.org/wws/arc/asm/2016-02/msg00001.html for a discussion of this pattern // but even though the value at the top of the stack here is null, its type isn't. So we need // to pop and push. This is the idiomatic pattern. builder.pop(); builder.pushNull(); builder.goTo(nullExit); builder.mark(nonNull); }
From source file:com.google.template.soy.jbcsrc.restricted.BytecodeUtils.java
License:Apache License
/** * Returns a {@link SoyExpression} that evaluates to true if the expression evaluated to a * non-null value./*from w ww. java 2 s .co m*/ */ public static SoyExpression isNonNull(final Expression expr) { if (BytecodeUtils.isPrimitive(expr.resultType())) { return SoyExpression.TRUE; } return SoyExpression.forBool(new Expression(Type.BOOLEAN_TYPE, expr.features()) { @Override protected void doGen(CodeBuilder adapter) { expr.gen(adapter); Label isNull = new Label(); adapter.ifNull(isNull); // non-null adapter.pushBoolean(true); Label end = new Label(); adapter.goTo(end); adapter.mark(isNull); adapter.pushBoolean(false); adapter.mark(end); } }); }
From source file:com.google.template.soy.jbcsrc.restricted.BytecodeUtils.java
License:Apache License
/** Returns a {@link SoyExpression} that evaluates to true if the expression evaluated to null. */ public static SoyExpression isNull(final Expression expr) { if (BytecodeUtils.isPrimitive(expr.resultType())) { return SoyExpression.FALSE; }// w ww . ja v a 2 s . c om // This is what javac generates for 'someObject == null' return SoyExpression.forBool(new Expression(Type.BOOLEAN_TYPE, expr.features()) { @Override protected void doGen(CodeBuilder adapter) { expr.gen(adapter); Label isNull = new Label(); adapter.ifNull(isNull); // non-null adapter.pushBoolean(false); Label end = new Label(); adapter.goTo(end); adapter.mark(isNull); adapter.pushBoolean(true); adapter.mark(end); } }); }
From source file:com.google.template.soy.jbcsrc.restricted.SoyExpression.java
License:Apache License
/** Returns an Expression of a non-null {@link SoyValueProvider} providing this value. */ public Expression boxAsSoyValueProvider() { if (soyType().equals(NullType.getInstance())) { if (delegate == NULL || delegate == NULL_BOXED) { return FieldRef.NULL_PROVIDER.accessor(); }//from w ww .ja va2 s . c o m // otherwise this expression might have side effects, evaluate it as a statement then return // the NULL_PROVIDER return toStatement().then(FieldRef.NULL_PROVIDER.accessor()); } if (delegate.isNonNullable()) { // Every SoyValue is-a SoyValueProvider, so if it is non-null return box(); } if (isBoxed()) { return new Expression(BytecodeUtils.SOY_VALUE_PROVIDER_TYPE, delegate.features().plus(Feature.NON_NULLABLE)) { @Override protected void doGen(CodeBuilder adapter) { Label end = new Label(); delegate.gen(adapter); adapter.dup(); adapter.ifNonNull(end); adapter.pop(); FieldRef.NULL_PROVIDER.accessStaticUnchecked(adapter); adapter.mark(end); } }; } return new Expression(BytecodeUtils.SOY_VALUE_PROVIDER_TYPE, delegate.features().plus(Feature.NON_NULLABLE)) { @Override protected void doGen(CodeBuilder adapter) { Label end = new Label(); delegate.gen(adapter); adapter.dup(); Label nonNull = new Label(); adapter.ifNonNull(nonNull); adapter.pop(); // pop the null value and replace with the nullprovider FieldRef.NULL_PROVIDER.accessStaticUnchecked(adapter); adapter.goTo(end); adapter.mark(nonNull); doBox(adapter, soyRuntimeType); adapter.mark(end); } }; }