Example usage for org.objectweb.asm Opcodes IFNE

List of usage examples for org.objectweb.asm Opcodes IFNE

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes IFNE.

Prototype

int IFNE

To view the source code for org.objectweb.asm Opcodes IFNE.

Click Source Link

Usage

From source file:lucee.transformer.bytecode.statement.DoWhile.java

License:Open Source License

@Override
public void _writeOut(BytecodeContext bc) throws BytecodeException {
    GeneratorAdapter adapter = bc.getAdapter();
    adapter.visitLabel(begin);/*from w w w.j  ava 2 s  . c o m*/
    body.writeOut(bc);

    adapter.visitLabel(beforeEnd);

    expr.writeOut(bc, Expression.MODE_VALUE);
    adapter.ifZCmp(Opcodes.IFNE, begin);

    adapter.visitLabel(end);

}

From source file:lucee.transformer.bytecode.statement.For.java

License:Open Source License

@Override
public void _writeOut(BytecodeContext bc) throws BytecodeException {
    GeneratorAdapter adapter = bc.getAdapter();
    Label beforeInit = new Label();
    Label afterInit = new Label();
    Label afterUpdate = new Label();

    ExpressionUtil.visitLine(bc, getStart());
    adapter.visitLabel(beforeInit);/*from w  w  w  .  java  2s .c o  m*/
    if (init != null) {
        init.writeOut(bc, Expression.MODE_VALUE);
        adapter.pop();
    }
    adapter.visitJumpInsn(Opcodes.GOTO, afterUpdate);
    adapter.visitLabel(afterInit);

    body.writeOut(bc);

    adapter.visitLabel(beforeUpdate);
    //ExpressionUtil.visitLine(bc, getStartLine());
    if (update != null) {
        update.writeOut(bc, Expression.MODE_VALUE);
        ASMUtil.pop(adapter, update, Expression.MODE_VALUE);
    }
    //ExpressionUtil.visitLine(bc, getStartLine());
    adapter.visitLabel(afterUpdate);

    if (condition != null)
        condition.writeOut(bc, Expression.MODE_VALUE);
    else
        LitBoolean.TRUE.writeOut(bc, Expression.MODE_VALUE);
    adapter.visitJumpInsn(Opcodes.IFNE, afterInit);
    //ExpressionUtil.visitLine(bc, getEndLine());
    adapter.visitLabel(end);

}

From source file:lucee.transformer.bytecode.visitor.DoWhileVisitor.java

License:Open Source License

public void visitEndExpr(GeneratorAdapter mv) {
    mv.ifZCmp(Opcodes.IFNE, begin);
    mv.visitLabel(end);
}

From source file:lucee.transformer.bytecode.visitor.ForConditionIntVisitor.java

License:Open Source License

public void visitEndAfterCondition(BytecodeContext bc) {
    GeneratorAdapter adapter = bc.getAdapter();

    adapter.ifZCmp(Opcodes.IFNE, l3);

    adapter.visitLabel(lend);/*  w  ww .j  ava 2s . com*/

    adapter.visitLocalVariable("i", "I", null, l1, lend, i);

}

From source file:name.martingeisse.minimal.compiler.Compiler.java

License:Open Source License

/**
 * Compiles a {@link MethodNode} to MCode.
 * /*ww w. jav a2  s .  co m*/
 * @param methodNode the method node to compile
 * @return the compiled code
 */
public ImmutableList<MCodeEntry> compile(final MethodNode methodNode) {
    for (int i = 0; i < methodNode.instructions.size(); i++) {
        final AbstractInsnNode instruction = methodNode.instructions.get(i);
        if (instruction instanceof LineNumberNode) {
            // ignored
        } else if (instruction instanceof FrameNode) {
            // this could be useful in the future
        } else if (instruction instanceof LabelNode) {
            label(((LabelNode) instruction).getLabel());
        } else if (instruction instanceof InsnNode) {
            switch (instruction.getOpcode()) {

            case Opcodes.ICONST_M1:
                iconst(-1);
                break;

            case Opcodes.ICONST_0:
                iconst(0);
                break;

            case Opcodes.ICONST_1:
                iconst(1);
                break;

            case Opcodes.ICONST_2:
                iconst(2);
                break;

            case Opcodes.ICONST_3:
                iconst(3);
                break;

            case Opcodes.ICONST_4:
                iconst(4);
                break;

            case Opcodes.ICONST_5:
                iconst(5);
                break;

            default:
                unsupported(instruction);
                break;

            }
        } else if (instruction instanceof VarInsnNode) {
            final VarInsnNode varInsnNode = (VarInsnNode) instruction;
            switch (varInsnNode.getOpcode()) {

            case Opcodes.ILOAD:
                iload(varInsnNode.var);
                break;

            case Opcodes.ISTORE:
                istore(varInsnNode.var);
                break;

            default:
                unsupported(instruction);
                break;

            }
        } else if (instruction instanceof IincInsnNode) {
            final IincInsnNode iincInsnNode = (IincInsnNode) instruction;
            iinc(iincInsnNode.var, iincInsnNode.incr);
        } else if (instruction instanceof JumpInsnNode) {
            final JumpInsnNode jumpInsnNode = (JumpInsnNode) instruction;
            switch (jumpInsnNode.getOpcode()) {

            case Opcodes.IFEQ:
            case Opcodes.IFNE:
            case Opcodes.IFLT:
            case Opcodes.IFGE:
            case Opcodes.IFGT:
            case Opcodes.IFLE:
                branch1(jumpInsnNode.label.getLabel(), jumpInsnNode.getOpcode());
                break;

            case Opcodes.IF_ICMPEQ:
            case Opcodes.IF_ICMPNE:
            case Opcodes.IF_ICMPLT:
            case Opcodes.IF_ICMPGE:
            case Opcodes.IF_ICMPGT:
            case Opcodes.IF_ICMPLE:
                branch2(jumpInsnNode.label.getLabel(), jumpInsnNode.getOpcode());
                break;

            case Opcodes.IFNULL:
            case Opcodes.IFNONNULL:
                // unsupported: one-argument reference comparison operator
                unsupported(instruction);
                break;

            case Opcodes.IF_ACMPEQ:
            case Opcodes.IF_ACMPNE:
                // unsupported: two-argument reference comparison operator
                unsupported(instruction);
                break;

            case Opcodes.GOTO:
                jump(jumpInsnNode.label.getLabel());
                break;

            case Opcodes.JSR:
                jsr(jumpInsnNode.label.getLabel());
                break;

            default:
                unsupported(instruction);
                break;

            }
        } else if (instruction instanceof IntInsnNode) {
            final IntInsnNode intInsnNode = (IntInsnNode) instruction;
            if (instruction.getOpcode() == Opcodes.BIPUSH || instruction.getOpcode() == Opcodes.SIPUSH) {
                iconst(intInsnNode.operand);
            } else {
                // NEWARRAY
                unsupported(instruction);
            }
        } else if (instruction instanceof MethodInsnNode) {
            final MethodInsnNode methodInsnNode = (MethodInsnNode) instruction;
            if (methodInsnNode.getOpcode() == Opcodes.INVOKESTATIC) {
                if (methodInsnNode.owner.replace('/', '.').equals(Native.class.getName())) {
                    nativeCall(methodInsnNode.name, methodInsnNode.desc);
                } else {
                    unsupported(instruction);
                }
            } else {
                unsupported(instruction);
            }
        } else {
            unsupported(instruction);
        }
    }
    return builder.build();
}

From source file:name.martingeisse.minimal.compiler.Compiler.java

License:Open Source License

private MBinaryIntegerOperator mapOperator(final int jvmOpcode) {
    switch (jvmOpcode) {

    case Opcodes.IFEQ:
    case Opcodes.IF_ICMPEQ:
        return MBinaryIntegerOperator.EQUAL;

    case Opcodes.IFNE:
    case Opcodes.IF_ICMPNE:
        return MBinaryIntegerOperator.NOT_EQUAL;

    case Opcodes.IFLT:
    case Opcodes.IF_ICMPLT:
        return MBinaryIntegerOperator.LESS_THAN;

    case Opcodes.IFLE:
    case Opcodes.IF_ICMPLE:
        return MBinaryIntegerOperator.LESS_THAN_OR_EQUAL;

    case Opcodes.IFGT:
    case Opcodes.IF_ICMPGT:
        return MBinaryIntegerOperator.GREATER_THAN;

    case Opcodes.IFGE:
    case Opcodes.IF_ICMPGE:
        return MBinaryIntegerOperator.GREATER_THAN_OR_EQUAL;

    default://from   www.j  a v  a2  s  . c  o  m
        throw new IllegalArgumentException("cannot map comparison operator for JVM opcode: " + jvmOpcode);

    }
}

From source file:org.actorsguildframework.internal.codegenerator.ActorProxyCreator.java

License:Apache License

/**
 * Writes a proxy method for messages.//from   w  ww . j  a  va 2s  .  c o  m
 * @param classNameInternal the internal class name
 * @param classNameDescriptor the class name descriptor
 * @param cw the ClassWriter
 * @param index the message index
 * @param type the ActorState type to use
 * @param concurrencyModel the concurrency model of the message
 * @param messageDescriptor the message's descriptor
 * @param method the method to override
 * @param simpleDescriptor a simple descriptor of the message
 * @param genericSignature the signature of the message
 */
private static void writeProxyMethod(String classNameInternal, String classNameDescriptor, ClassWriter cw,
        int index, Type actorState, ConcurrencyModel concurrencyModel, MessageImplDescriptor messageDescriptor,
        Method method, String simpleDescriptor, String genericSignature) throws NoSuchMethodException {
    MethodVisitor mv;
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), simpleDescriptor, genericSignature, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitIntInsn(Opcodes.BIPUSH, method.getParameterTypes().length);
        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
        for (int j = 0; j < method.getParameterTypes().length; j++) {
            mv.visitInsn(Opcodes.DUP);
            mv.visitIntInsn(Opcodes.BIPUSH, j);
            Class<?> paraType = method.getParameterTypes()[j];
            if (paraType.isPrimitive()) {
                String wrapperClass = GenerationUtils.getWrapperInternalName(paraType);
                Type primType = Type.getType(paraType);
                mv.visitVarInsn(primType.getOpcode(Opcodes.ILOAD), j + 1);
                mv.visitMethodInsn(Opcodes.INVOKESTATIC, wrapperClass, "valueOf",
                        "(" + primType.getDescriptor() + ")" + "L" + wrapperClass + ";");
            } else if (isArgumentFreezingRequired(method, j, paraType)) {
                mv.visitVarInsn(Opcodes.ALOAD, j + 1);
                mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(SerializableFreezer.class),
                        "freeze",
                        Type.getMethodDescriptor(SerializableFreezer.class.getMethod("freeze", Object.class)));
            } else if (paraType.isInterface()) {
                mv.visitVarInsn(Opcodes.ALOAD, j + 1);
                mv.visitInsn(Opcodes.DUP);
                mv.visitTypeInsn(Opcodes.INSTANCEOF, "org/actorsguildframework/Actor");
                Label lEndif = new Label();
                mv.visitJumpInsn(Opcodes.IFNE, lEndif);
                mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(ActorRuntimeException.class));
                mv.visitInsn(Opcodes.DUP);
                mv.visitLdcInsn(String.format(
                        "Argument %d is an non-Serializable interface, but you did not give an Actor. If a message's argument type is an interface that does not extend Serializable, only Actors are acceptable as argument.",
                        j));
                mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(ActorRuntimeException.class),
                        "<init>", "(Ljava/lang/String;)V");
                mv.visitInsn(Opcodes.ATHROW);
                mv.visitLabel(lEndif);
            } else
                mv.visitVarInsn(Opcodes.ALOAD, j + 1);

            mv.visitInsn(Opcodes.AASTORE);
        }
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitVarInsn(Opcodes.ASTORE, method.getParameterTypes().length + 1); // method.getParameterTypes().length+1 ==> 'args' local variable
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, classNameInternal, "actorState__ACTORPROXY",
                actorState.getDescriptor());
        mv.visitFieldInsn(Opcodes.GETSTATIC, classNameInternal,
                String.format(MESSAGE_CALLER_NAME_FORMAT, index),
                "Lorg/actorsguildframework/internal/MessageCaller;");
        mv.visitFieldInsn(Opcodes.GETSTATIC, "org/actorsguildframework/annotations/ThreadUsage",
                messageDescriptor.getThreadUsage().name(),
                "Lorg/actorsguildframework/annotations/ThreadUsage;");
        mv.visitVarInsn(Opcodes.ALOAD, method.getParameterTypes().length + 1);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, actorState.getInternalName(), "queueMessage",
                "(Lorg/actorsguildframework/internal/MessageCaller;Lorg/actorsguildframework/annotations/ThreadUsage;[Ljava/lang/Object;)Lorg/actorsguildframework/internal/AsyncResultImpl;");
        mv.visitInsn(Opcodes.ARETURN);
        Label l4 = new Label();
        mv.visitLabel(l4);
        mv.visitLocalVariable("this", classNameDescriptor, null, l0, l4, 0);
        for (int j = 0; j < method.getParameterTypes().length; j++)
            mv.visitLocalVariable("arg" + j, Type.getDescriptor(method.getParameterTypes()[j]),
                    GenericTypeHelper.getSignatureIfGeneric(method.getGenericParameterTypes()[j]), l0, l4,
                    j + 1);
        mv.visitLocalVariable("args", "[Ljava/lang/Object;", null, l1, l4,
                method.getParameterTypes().length + 1);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
}

From source file:org.adjective.stout.loop.ExpressionCondition.java

License:Apache License

public Operation jumpWhenTrue(Label label) {
    return new JumpOperation(Opcodes.IFNE, _expression, label);
}

From source file:org.adjective.stout.operation.JumpOperation.java

License:Apache License

public void getInstructions(ExecutionStack stack, InstructionCollector collector) {
    switch (_op) {
    case Opcodes.IFEQ:
    case Opcodes.IFNE:
    case Opcodes.IFLT:
    case Opcodes.IFGE:
    case Opcodes.IFGT:
    case Opcodes.IFLE:
        checkExpression(TypeDescriptor.INT, stack);
        break;/*from   w  w w. j  a va  2 s.  c o  m*/
    case Opcodes.IFNULL:
    case Opcodes.IFNONNULL:
        checkExpression(TypeDescriptor.OBJECT, stack);
        break;
    default:
        throw new IllegalStateException("Do not know how to handle jump opcode " + getOpcodeDescription(_op));
    }
    _expression.getInstructions(stack, collector);
    collector.add(new JumpInstruction(_op, _label));
}

From source file:org.apache.lucene.expressions.js.JavascriptCompiler.java

License:Apache License

/**
 * Sends the bytecode of class file to {@link ClassWriter}.
 *///from w ww . j  a v a  2 s .  c om
private void generateClass(final ParseTree parseTree, final ClassWriter classWriter,
        final Map<String, Integer> externalsMap) throws ParseException {
    classWriter.visit(CLASSFILE_VERSION, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER | Opcodes.ACC_FINAL,
            COMPILED_EXPRESSION_INTERNAL, null, EXPRESSION_TYPE.getInternalName(), null);
    final String clippedSourceText = (sourceText.length() <= MAX_SOURCE_LENGTH) ? sourceText
            : (sourceText.substring(0, MAX_SOURCE_LENGTH - 3) + "...");
    classWriter.visitSource(clippedSourceText, null);

    final GeneratorAdapter constructor = new GeneratorAdapter(Opcodes.ACC_PUBLIC, EXPRESSION_CTOR, null, null,
            classWriter);
    constructor.loadThis();
    constructor.loadArgs();
    constructor.invokeConstructor(EXPRESSION_TYPE, EXPRESSION_CTOR);
    constructor.returnValue();
    constructor.endMethod();

    final GeneratorAdapter gen = new GeneratorAdapter(Opcodes.ACC_PUBLIC, EVALUATE_METHOD, null, null,
            classWriter);

    // to completely hide the ANTLR visitor we use an anonymous impl:
    new JavascriptBaseVisitor<Void>() {
        private final Deque<Type> typeStack = new ArrayDeque<>();

        @Override
        public Void visitCompile(JavascriptParser.CompileContext ctx) {
            typeStack.push(Type.DOUBLE_TYPE);
            visit(ctx.expression());
            typeStack.pop();

            return null;
        }

        @Override
        public Void visitPrecedence(JavascriptParser.PrecedenceContext ctx) {
            visit(ctx.expression());

            return null;
        }

        @Override
        public Void visitNumeric(JavascriptParser.NumericContext ctx) {
            if (ctx.HEX() != null) {
                pushLong(Long.parseLong(ctx.HEX().getText().substring(2), 16));
            } else if (ctx.OCTAL() != null) {
                pushLong(Long.parseLong(ctx.OCTAL().getText().substring(1), 8));
            } else if (ctx.DECIMAL() != null) {
                gen.push(Double.parseDouble(ctx.DECIMAL().getText()));
                gen.cast(Type.DOUBLE_TYPE, typeStack.peek());
            } else {
                throw new IllegalStateException("Unknown operation specified: " + ctx.getText());
            }

            return null;
        }

        @Override
        public Void visitExternal(JavascriptParser.ExternalContext ctx) {
            String text = ctx.VARIABLE().getText();
            int arguments = ctx.expression().size();
            boolean parens = ctx.LP() != null && ctx.RP() != null;
            Method method = parens ? functions.get(text) : null;

            try {
                if (method != null) {
                    int arity = method.getParameterTypes().length;

                    if (arguments != arity) {
                        throw new ParseException("Invalid expression '" + sourceText + "': Expected (" + arity
                                + ") arguments for function call (" + text + "), but found (" + arguments
                                + ").", ctx.start.getStartIndex());
                    }

                    typeStack.push(Type.DOUBLE_TYPE);

                    for (int argument = 0; argument < arguments; ++argument) {
                        visit(ctx.expression(argument));
                    }

                    typeStack.pop();

                    gen.invokeStatic(Type.getType(method.getDeclaringClass()),
                            org.objectweb.asm.commons.Method.getMethod(method));

                    gen.cast(Type.DOUBLE_TYPE, typeStack.peek());
                } else if (!parens || arguments == 0 && text.contains(".")) {
                    int index;

                    text = normalizeQuotes(ctx.getText());

                    if (externalsMap.containsKey(text)) {
                        index = externalsMap.get(text);
                    } else {
                        index = externalsMap.size();
                        externalsMap.put(text, index);
                    }

                    gen.loadArg(0);
                    gen.push(index);
                    gen.arrayLoad(FUNCTION_VALUES_TYPE);
                    gen.invokeVirtual(FUNCTION_VALUES_TYPE, DOUBLE_VAL_METHOD);
                    gen.cast(Type.DOUBLE_TYPE, typeStack.peek());
                } else {
                    throw new ParseException("Invalid expression '" + sourceText
                            + "': Unrecognized function call (" + text + ").", ctx.start.getStartIndex());
                }
                return null;
            } catch (ParseException e) {
                // The API doesn't allow checked exceptions here, so propagate up the stack. This is unwrapped
                // in getAntlrParseTree. 
                throw new RuntimeException(e);
            }
        }

        @Override
        public Void visitUnary(JavascriptParser.UnaryContext ctx) {
            if (ctx.BOOLNOT() != null) {
                Label labelNotTrue = new Label();
                Label labelNotReturn = new Label();

                typeStack.push(Type.INT_TYPE);
                visit(ctx.expression());
                typeStack.pop();
                gen.visitJumpInsn(Opcodes.IFEQ, labelNotTrue);
                pushBoolean(false);
                gen.goTo(labelNotReturn);
                gen.visitLabel(labelNotTrue);
                pushBoolean(true);
                gen.visitLabel(labelNotReturn);

            } else if (ctx.BWNOT() != null) {
                typeStack.push(Type.LONG_TYPE);
                visit(ctx.expression());
                typeStack.pop();
                gen.push(-1L);
                gen.visitInsn(Opcodes.LXOR);
                gen.cast(Type.LONG_TYPE, typeStack.peek());

            } else if (ctx.ADD() != null) {
                visit(ctx.expression());

            } else if (ctx.SUB() != null) {
                typeStack.push(Type.DOUBLE_TYPE);
                visit(ctx.expression());
                typeStack.pop();
                gen.visitInsn(Opcodes.DNEG);
                gen.cast(Type.DOUBLE_TYPE, typeStack.peek());

            } else {
                throw new IllegalStateException("Unknown operation specified: " + ctx.getText());
            }

            return null;
        }

        @Override
        public Void visitMuldiv(JavascriptParser.MuldivContext ctx) {
            int opcode;

            if (ctx.MUL() != null) {
                opcode = Opcodes.DMUL;
            } else if (ctx.DIV() != null) {
                opcode = Opcodes.DDIV;
            } else if (ctx.REM() != null) {
                opcode = Opcodes.DREM;
            } else {
                throw new IllegalStateException("Unknown operation specified: " + ctx.getText());
            }

            pushArith(opcode, ctx.expression(0), ctx.expression(1));

            return null;
        }

        @Override
        public Void visitAddsub(JavascriptParser.AddsubContext ctx) {
            int opcode;

            if (ctx.ADD() != null) {
                opcode = Opcodes.DADD;
            } else if (ctx.SUB() != null) {
                opcode = Opcodes.DSUB;
            } else {
                throw new IllegalStateException("Unknown operation specified: " + ctx.getText());
            }

            pushArith(opcode, ctx.expression(0), ctx.expression(1));

            return null;
        }

        @Override
        public Void visitBwshift(JavascriptParser.BwshiftContext ctx) {
            int opcode;

            if (ctx.LSH() != null) {
                opcode = Opcodes.LSHL;
            } else if (ctx.RSH() != null) {
                opcode = Opcodes.LSHR;
            } else if (ctx.USH() != null) {
                opcode = Opcodes.LUSHR;
            } else {
                throw new IllegalStateException("Unknown operation specified: " + ctx.getText());
            }

            pushShift(opcode, ctx.expression(0), ctx.expression(1));

            return null;
        }

        @Override
        public Void visitBoolcomp(JavascriptParser.BoolcompContext ctx) {
            int opcode;

            if (ctx.LT() != null) {
                opcode = GeneratorAdapter.LT;
            } else if (ctx.LTE() != null) {
                opcode = GeneratorAdapter.LE;
            } else if (ctx.GT() != null) {
                opcode = GeneratorAdapter.GT;
            } else if (ctx.GTE() != null) {
                opcode = GeneratorAdapter.GE;
            } else {
                throw new IllegalStateException("Unknown operation specified: " + ctx.getText());
            }

            pushCond(opcode, ctx.expression(0), ctx.expression(1));

            return null;
        }

        @Override
        public Void visitBooleqne(JavascriptParser.BooleqneContext ctx) {
            int opcode;

            if (ctx.EQ() != null) {
                opcode = GeneratorAdapter.EQ;
            } else if (ctx.NE() != null) {
                opcode = GeneratorAdapter.NE;
            } else {
                throw new IllegalStateException("Unknown operation specified: " + ctx.getText());
            }

            pushCond(opcode, ctx.expression(0), ctx.expression(1));

            return null;
        }

        @Override
        public Void visitBwand(JavascriptParser.BwandContext ctx) {
            pushBitwise(Opcodes.LAND, ctx.expression(0), ctx.expression(1));

            return null;
        }

        @Override
        public Void visitBwxor(JavascriptParser.BwxorContext ctx) {
            pushBitwise(Opcodes.LXOR, ctx.expression(0), ctx.expression(1));

            return null;
        }

        @Override
        public Void visitBwor(JavascriptParser.BworContext ctx) {
            pushBitwise(Opcodes.LOR, ctx.expression(0), ctx.expression(1));

            return null;
        }

        @Override
        public Void visitBooland(JavascriptParser.BoolandContext ctx) {
            Label andFalse = new Label();
            Label andEnd = new Label();

            typeStack.push(Type.INT_TYPE);
            visit(ctx.expression(0));
            gen.visitJumpInsn(Opcodes.IFEQ, andFalse);
            visit(ctx.expression(1));
            gen.visitJumpInsn(Opcodes.IFEQ, andFalse);
            typeStack.pop();
            pushBoolean(true);
            gen.goTo(andEnd);
            gen.visitLabel(andFalse);
            pushBoolean(false);
            gen.visitLabel(andEnd);

            return null;
        }

        @Override
        public Void visitBoolor(JavascriptParser.BoolorContext ctx) {
            Label orTrue = new Label();
            Label orEnd = new Label();

            typeStack.push(Type.INT_TYPE);
            visit(ctx.expression(0));
            gen.visitJumpInsn(Opcodes.IFNE, orTrue);
            visit(ctx.expression(1));
            gen.visitJumpInsn(Opcodes.IFNE, orTrue);
            typeStack.pop();
            pushBoolean(false);
            gen.goTo(orEnd);
            gen.visitLabel(orTrue);
            pushBoolean(true);
            gen.visitLabel(orEnd);

            return null;
        }

        @Override
        public Void visitConditional(JavascriptParser.ConditionalContext ctx) {
            Label condFalse = new Label();
            Label condEnd = new Label();

            typeStack.push(Type.INT_TYPE);
            visit(ctx.expression(0));
            typeStack.pop();
            gen.visitJumpInsn(Opcodes.IFEQ, condFalse);
            visit(ctx.expression(1));
            gen.goTo(condEnd);
            gen.visitLabel(condFalse);
            visit(ctx.expression(2));
            gen.visitLabel(condEnd);

            return null;
        }

        private void pushArith(int operator, ExpressionContext left, ExpressionContext right) {
            pushBinaryOp(operator, left, right, Type.DOUBLE_TYPE, Type.DOUBLE_TYPE, Type.DOUBLE_TYPE);
        }

        private void pushShift(int operator, ExpressionContext left, ExpressionContext right) {
            pushBinaryOp(operator, left, right, Type.LONG_TYPE, Type.INT_TYPE, Type.LONG_TYPE);
        }

        private void pushBitwise(int operator, ExpressionContext left, ExpressionContext right) {
            pushBinaryOp(operator, left, right, Type.LONG_TYPE, Type.LONG_TYPE, Type.LONG_TYPE);
        }

        private void pushBinaryOp(int operator, ExpressionContext left, ExpressionContext right, Type leftType,
                Type rightType, Type returnType) {
            typeStack.push(leftType);
            visit(left);
            typeStack.pop();
            typeStack.push(rightType);
            visit(right);
            typeStack.pop();
            gen.visitInsn(operator);
            gen.cast(returnType, typeStack.peek());
        }

        private void pushCond(int operator, ExpressionContext left, ExpressionContext right) {
            Label labelTrue = new Label();
            Label labelReturn = new Label();

            typeStack.push(Type.DOUBLE_TYPE);
            visit(left);
            visit(right);
            typeStack.pop();

            gen.ifCmp(Type.DOUBLE_TYPE, operator, labelTrue);
            pushBoolean(false);
            gen.goTo(labelReturn);
            gen.visitLabel(labelTrue);
            pushBoolean(true);
            gen.visitLabel(labelReturn);
        }

        private void pushBoolean(boolean truth) {
            switch (typeStack.peek().getSort()) {
            case Type.INT:
                gen.push(truth);
                break;
            case Type.LONG:
                gen.push(truth ? 1L : 0L);
                break;
            case Type.DOUBLE:
                gen.push(truth ? 1. : 0.);
                break;
            default:
                throw new IllegalStateException("Invalid expected type: " + typeStack.peek());
            }
        }

        private void pushLong(long i) {
            switch (typeStack.peek().getSort()) {
            case Type.INT:
                gen.push((int) i);
                break;
            case Type.LONG:
                gen.push(i);
                break;
            case Type.DOUBLE:
                gen.push((double) i);
                break;
            default:
                throw new IllegalStateException("Invalid expected type: " + typeStack.peek());
            }
        }
    }.visit(parseTree);

    gen.returnValue();
    gen.endMethod();

    classWriter.visitEnd();
}