Package st.gravel.support.compiler

Source Code of st.gravel.support.compiler.ASMMethodWriter

package st.gravel.support.compiler;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import st.gravel.support.compiler.jvm.ALoad;
import st.gravel.support.compiler.jvm.AReturn;
import st.gravel.support.compiler.jvm.AStore;
import st.gravel.support.compiler.jvm.AThrow;
import st.gravel.support.compiler.jvm.AndThenElse;
import st.gravel.support.compiler.jvm.ArrayLength;
import st.gravel.support.compiler.jvm.ByteArrayStore;
import st.gravel.support.compiler.jvm.CastArrayToObject;
import st.gravel.support.compiler.jvm.CastBooleanToObject;
import st.gravel.support.compiler.jvm.CastByteToObject;
import st.gravel.support.compiler.jvm.CastCharToObject;
import st.gravel.support.compiler.jvm.CastDefinedToObject;
import st.gravel.support.compiler.jvm.CastDoubleToObject;
import st.gravel.support.compiler.jvm.CastFloatToObject;
import st.gravel.support.compiler.jvm.CastIntToObject;
import st.gravel.support.compiler.jvm.CastLongToObject;
import st.gravel.support.compiler.jvm.CastObjectToArray;
import st.gravel.support.compiler.jvm.CastObjectToBoolean;
import st.gravel.support.compiler.jvm.CastObjectToByte;
import st.gravel.support.compiler.jvm.CastObjectToChar;
import st.gravel.support.compiler.jvm.CastObjectToDefined;
import st.gravel.support.compiler.jvm.CastObjectToDouble;
import st.gravel.support.compiler.jvm.CastObjectToFloat;
import st.gravel.support.compiler.jvm.CastObjectToInt;
import st.gravel.support.compiler.jvm.CastObjectToLong;
import st.gravel.support.compiler.jvm.CastObjectToShort;
import st.gravel.support.compiler.jvm.Dup;
import st.gravel.support.compiler.jvm.DupX1;
import st.gravel.support.compiler.jvm.DupX2;
import st.gravel.support.compiler.jvm.DynamicCreateInstance;
import st.gravel.support.compiler.jvm.DynamicFieldRead;
import st.gravel.support.compiler.jvm.DynamicFieldWrite;
import st.gravel.support.compiler.jvm.DynamicGlobalRead;
import st.gravel.support.compiler.jvm.DynamicGlobalWrite;
import st.gravel.support.compiler.jvm.DynamicLiteralBlockMessageSend;
import st.gravel.support.compiler.jvm.DynamicMessageSend;
import st.gravel.support.compiler.jvm.DynamicSuperSend;
import st.gravel.support.compiler.jvm.Frame;
import st.gravel.support.compiler.jvm.GetField;
import st.gravel.support.compiler.jvm.GetStatic;
import st.gravel.support.compiler.jvm.ILoad;
import st.gravel.support.compiler.jvm.IStore;
import st.gravel.support.compiler.jvm.IdentityCast;
import st.gravel.support.compiler.jvm.IfBooleanObjectThenElse;
import st.gravel.support.compiler.jvm.IfBooleanValueThenElse;
import st.gravel.support.compiler.jvm.IfObjectIsNullThenElse;
import st.gravel.support.compiler.jvm.IfObjectsEqualThenElse;
import st.gravel.support.compiler.jvm.IncrementLocal;
import st.gravel.support.compiler.jvm.InvokeInterface;
import st.gravel.support.compiler.jvm.InvokeSpecial;
import st.gravel.support.compiler.jvm.InvokeStatic;
import st.gravel.support.compiler.jvm.InvokeVirtual;
import st.gravel.support.compiler.jvm.JVMInstruction;
import st.gravel.support.compiler.jvm.JVMInstructionVisitor;
import st.gravel.support.compiler.jvm.JVMLocalDeclaration;
import st.gravel.support.compiler.jvm.JVMMethod;
import st.gravel.support.compiler.jvm.LabelLineNumber;
import st.gravel.support.compiler.jvm.NewArray;
import st.gravel.support.compiler.jvm.NewInstance;
import st.gravel.support.compiler.jvm.ObjectArrayLoad;
import st.gravel.support.compiler.jvm.ObjectArrayStore;
import st.gravel.support.compiler.jvm.OrThenElse;
import st.gravel.support.compiler.jvm.Pop;
import st.gravel.support.compiler.jvm.PushChar;
import st.gravel.support.compiler.jvm.PushDouble;
import st.gravel.support.compiler.jvm.PushFalse;
import st.gravel.support.compiler.jvm.PushFloat;
import st.gravel.support.compiler.jvm.PushInt;
import st.gravel.support.compiler.jvm.PushNull;
import st.gravel.support.compiler.jvm.PushString;
import st.gravel.support.compiler.jvm.PushTrue;
import st.gravel.support.compiler.jvm.PutField;
import st.gravel.support.compiler.jvm.PutStatic;
import st.gravel.support.compiler.jvm.Return;
import st.gravel.support.compiler.jvm.Subtract;
import st.gravel.support.compiler.jvm.TryCatch;
import st.gravel.support.compiler.jvm.WhileFalseLoop;
import st.gravel.support.compiler.jvm.WhileGreaterThanLoop;
import st.gravel.support.compiler.jvm.WhileLessThanLoop;
import st.gravel.support.compiler.jvm.WhileTrueLoop;
import st.gravel.support.jvm.ArrayExtensions;
import st.gravel.support.jvm.Block1;

public class ASMMethodWriter extends JVMInstructionVisitor<Void> implements
    Opcodes {

  private ClassWriter cw;
  private MethodVisitor mv;

  public ASMMethodWriter(ClassWriter cw) {
    this.cw = cw;
  }

  @Override
  protected Object clone() throws CloneNotSupportedException {
    throw new UnsupportedOperationException("Not Implemented Yet");
  }

  public double fromage(Object x) {
    return (Double) x;
  }

  public void logToErr(final String string) {
    mv.visitFieldInsn(GETSTATIC, "java/lang/System", "err",
        "Ljava/io/PrintStream;");
    mv.visitLdcInsn(string);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
        "(Ljava/lang/String;)V");
  }

  private void produceLocalVariableInfo(Label startLabel,
      JVMLocalDeclaration[] jvmLocalDeclarations) {
    Label varLabel = new Label();
    mv.visitLabel(varLabel);
    for (JVMLocalDeclaration local : jvmLocalDeclarations) {
      mv.visitLocalVariable(local.varName(), local.type()
          .descriptorString(), null, startLabel, varLabel, local
          .index());
    }
  }

  public void pushDouble(double value) {
    if (value == 0.0d) {
      mv.visitInsn(DCONST_0);
      return;
    }
    if (value == 1.0d) {
      mv.visitInsn(DCONST_1);
      return;
    }
    mv.visitLdcInsn(value);
    return;
  }

  public void pushFloat(float value) {
    if (value == 0.0f) {
      mv.visitInsn(FCONST_0);
      return;
    }
    if (value == 1.0f) {
      mv.visitInsn(FCONST_1);
      return;
    }
    if (value == 2.0f) {
      mv.visitInsn(FCONST_2);
      return;
    }
    mv.visitLdcInsn(value);
    return;
  }

  public void pushInt(int i) {
    switch (i) {
    case (0):
      mv.visitInsn(ICONST_0);
      return;
    case (1):
      mv.visitInsn(ICONST_1);
      return;
    case (2):
      mv.visitInsn(ICONST_2);
      return;
    case (3):
      mv.visitInsn(ICONST_3);
      return;
    case (4):
      mv.visitInsn(ICONST_4);
      return;
    case (5):
      mv.visitInsn(ICONST_5);
      return;
    }
    if (i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE) {
      mv.visitIntInsn(BIPUSH, i);
      return;
    }
    if (i >= Short.MIN_VALUE && i <= Short.MAX_VALUE) {
      mv.visitIntInsn(SIPUSH, i);
      return;
    }
    mv.visitLdcInsn(i);
  }

  public Void visit_(JVMInstruction node) {
    // logToErr("Start: " + node);
    node.accept_(this);
    return null;
  }

  @Override
  public Void visitALoad_(ALoad node) {
    mv.visitVarInsn(ALOAD, node.index());
    return null;
  }

  @Override
  public Void visitAndThenElse_(AndThenElse node) {
    Label falseLabel = new Label();
    Label endLabel = new Label();
    visit_(node.left());
    mv.visitJumpInsn(IFEQ, falseLabel);
    visit_(node.right());
    mv.visitJumpInsn(IFEQ, falseLabel);
    visit_(node.trueFrame());
    mv.visitJumpInsn(GOTO, endLabel);
    mv.visitLabel(falseLabel);
    visit_(node.falseFrame());
    mv.visitLabel(endLabel);
    return null;
  }

  @Override
  public Void visitAReturn_(AReturn node) {
    mv.visitInsn(ARETURN);
    return null;
  }

  @Override
  public Void visitArrayLength_(ArrayLength node) {
    mv.visitInsn(ARRAYLENGTH);
    return null;
  }

  @Override
  public Void visitAStore_(AStore node) {
    mv.visitVarInsn(ASTORE, node.index());
    return null;
  }

  @Override
  public Void visitAThrow_(AThrow node) {
    mv.visitInsn(ATHROW);
    return null;
  }

  @Override
  public Void visitByteArrayStore_(ByteArrayStore node) {
    mv.visitInsn(BASTORE);
    return null;
  }

  @Override
  public Void visitCastArrayToObject_(CastArrayToObject node) {
    return null;
  }

  @Override
  public Void visitCastBooleanToObject_(CastBooleanToObject node) {
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf",
        "(Z)Ljava/lang/Boolean;");
    return null;
  }

  @Override
  public Void visitCastByteToObject_(CastByteToObject node) {
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf",
        "(I)Ljava/lang/Integer;");
    return null;
  }

  @Override
  public Void visitCastCharToObject_(CastCharToObject node) {
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf",
        "(C)Ljava/lang/Character;");
    return null;
  }

  @Override
  public Void visitCastDefinedToObject_(CastDefinedToObject node) {
    return null;
  }

  @Override
  public Void visitCastDoubleToObject_(CastDoubleToObject node) {
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf",
        "(D)Ljava/lang/Double;");
    return null;
  }

  @Override
  public Void visitCastFloatToObject_(CastFloatToObject node) {
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf",
        "(F)Ljava/lang/Float;");
    return null;
  }

  @Override
  public Void visitCastIntToObject_(CastIntToObject node) {
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf",
        "(I)Ljava/lang/Integer;");
    return null;
  }

  @Override
  public Void visitCastLongToObject_(CastLongToObject _anObject) {
    mv.visitMethodInsn(INVOKESTATIC, "java/math/BigInteger", "valueOf",
        "(J)Ljava/math/BigInteger;");
    return null;
  }

  @Override
  public Void visitCastObjectToArray_(CastObjectToArray node) {
    mv.visitTypeInsn(CHECKCAST, "[" + node.elementType().descriptorString());
    return null;
  }

  @Override
  public Void visitCastObjectToBoolean_(CastObjectToBoolean _anObject) {
    mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue",
        "()Z");
    return null;
  }

  @Override
  public Void visitCastObjectToByte_(CastObjectToByte _anObject) {
    mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue",
        "()I");
    return null;
  }

  @Override
  public Void visitCastObjectToChar_(CastObjectToChar _anObject) {
    mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue",
        "()C");
    return null;
  }

  @Override
  public Void visitCastObjectToDefined_(CastObjectToDefined node) {
    mv.visitTypeInsn(CHECKCAST, node.type().className());
    return null;
  }

  @Override
  public Void visitCastObjectToDouble_(CastObjectToDouble node) {
    mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue",
        "()D");
    return null;
  }

  @Override
  public Void visitCastObjectToFloat_(CastObjectToFloat _anObject) {
    mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue",
        "()F");
    return null;
  }

  @Override
  public Void visitCastObjectToInt_(CastObjectToInt node) {
    mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue",
        "()I");
    return null;
  }

  @Override
  public Void visitCastObjectToLong_(CastObjectToLong _anObject) {
    mv.visitMethodInsn(INVOKESTATIC,
        "st/gravel/support/jvm/IntegerExtensions", "asLong",
        "(Ljava/lang/Object;)J");
    return null;
  }

  @Override
  public Void visitCastObjectToShort_(CastObjectToShort _anObject) {
    mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue",
        "()S");
    return null;
  }

  @Override
  public Void visitDup_(Dup _anObject) {
    mv.visitInsn(DUP);
    return null;
  }

  @Override
  public Void visitDupX1_(DupX1 _anObject) {
    mv.visitInsn(DUP_X1);
    return null;
  }

  @Override
  public Void visitDupX2_(DupX2 _anObject) {
    mv.visitInsn(DUP_X2);
    return null;
  }

  @Override
  public Void visitDynamicCreateInstance_(DynamicCreateInstance node) {
    mv.visitInvokeDynamicInsn("new", node.methodType()
        .descriptorString(), BootstrapHandles.constructorBootstrap, node.reference());
    return null;
  }

  @Override
  public Void visitDynamicFieldRead_(DynamicFieldRead node) {
    mv.visitInvokeDynamicInsn(node.name(), node.methodType()
        .descriptorString(), BootstrapHandles.fieldReadBootstrap);
    return null;
  }

  @Override
  public Void visitDynamicFieldWrite_(DynamicFieldWrite node) {
    mv.visitInvokeDynamicInsn(node.name(), node.methodType()
        .descriptorString(), BootstrapHandles.fieldWriteBootstrap);
    return null;

  }

  @Override
  public Void visitDynamicGlobalRead_(DynamicGlobalRead node) {
    mv.visitInvokeDynamicInsn(node.name(), node.methodType()
        .descriptorString(), BootstrapHandles.globalReadBootstrap, node
        .namespace());
    return null;
  }

  @Override
  public Void visitDynamicGlobalWrite_(DynamicGlobalWrite node) {
    mv.visitInvokeDynamicInsn(node.name(), node.methodType()
        .descriptorString(), BootstrapHandles.globalWriteBootstrap,
        node.namespace());
    return null;
  }

  @Override
  public Void visitDynamicLiteralBlockMessageSend_(
      DynamicLiteralBlockMessageSend node) {
    String astConstantsString = ArrayExtensions.join_(
        node.blockSendConstants(), new Block1<String, String>() {

          @Override
          public String value_(String arg1) {
            return (arg1 == null ? "" : arg1) + ';';
          }
        });

    String copiedArgumentsString = ArrayExtensions.join_(
        node.copiedArguments(), new Block1<String, String>() {

          @Override
          public String value_(String arg1) {
            return arg1 + ';';
          }
        });
    mv.visitInvokeDynamicInsn(node.functionName(), node.signature()
        .descriptorString(),
        BootstrapHandles.literalBlockSendBootstrap, node
            .constantOwner().dottedClassName(), astConstantsString,
        copiedArgumentsString);
    return null;
  }

  @Override
  public Void visitDynamicMessageSend_(DynamicMessageSend node) {
    mv.visitInvokeDynamicInsn(node.functionName(), node.signature()
        .descriptorString(), BootstrapHandles.bootstrap);
    return null;
  }

  @Override
  public Void visitDynamicSuperSend_(DynamicSuperSend node) {

    mv.visitInvokeDynamicInsn(node.functionName(), node.signature()
        .descriptorString(), BootstrapHandles.superBootstrap, node
        .superReference());
    return null;
  }

  @Override
  public Void visitFrame_(Frame frame) {
    for (JVMInstruction insn : frame.instructions())
      visit_(insn);
    return null;
  }

  @Override
  public Void visitGetField_(GetField node) {
    mv.visitFieldInsn(GETFIELD, node.ownerType().className(), node.name(),
        node.type().descriptorString());
    return null;
  }

  @Override
  public Void visitGetStatic_(GetStatic node) {
    mv.visitFieldInsn(GETSTATIC, node.ownerType().className(), node.name(),
        node.type().descriptorString());
    return null;
  }

  @Override
  public Void visitIdentityCast_(IdentityCast _anObject) {
    return null;
  }

  @Override
  public Void visitIfBooleanObjectThenElse_(IfBooleanObjectThenElse node) {
    mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue",
        "()Z");
    Label elseLabel = new Label();
    mv.visitJumpInsn(IFEQ, elseLabel);
    visit_(node.trueFrame());
    Label end = new Label();
    mv.visitJumpInsn(GOTO, end);
    mv.visitLabel(elseLabel);
    visit_(node.falseFrame());
    mv.visitLabel(end);
    return null;
  }

  @Override
  public Void visitIfBooleanValueThenElse_(IfBooleanValueThenElse node) {
    Label elseLabel = new Label();
    mv.visitJumpInsn(IFEQ, elseLabel);
    visit_(node.trueFrame());
    Label end = new Label();
    mv.visitJumpInsn(GOTO, end);
    mv.visitLabel(elseLabel);
    visit_(node.falseFrame());
    mv.visitLabel(end);
    return null;
  }

  @Override
  public Void visitIfObjectIsNullThenElse_(IfObjectIsNullThenElse node) {
    Label elseLabel = new Label();
    mv.visitJumpInsn(IFNONNULL, elseLabel);
    visit_(node.trueFrame());
    Label end = new Label();
    mv.visitJumpInsn(GOTO, end);
    mv.visitLabel(elseLabel);
    visit_(node.falseFrame());
    mv.visitLabel(end);
    return null;
  }

  @Override
  public Void visitIfObjectsEqualThenElse_(IfObjectsEqualThenElse node) {
    Label elseLabel = new Label();
    mv.visitJumpInsn(IF_ACMPNE, elseLabel);
    visit_(node.trueFrame());
    Label end = new Label();
    mv.visitJumpInsn(GOTO, end);
    mv.visitLabel(elseLabel);
    visit_(node.falseFrame());
    mv.visitLabel(end);
    return null;
  }

  @Override
  public Void visitILoad_(ILoad node) {
    mv.visitVarInsn(ILOAD, node.index());
    return null;
  }

  @Override
  public Void visitIncrementLocal_(IncrementLocal node) {
    mv.visitIincInsn(node.local().index(), node.increment());
    return null;
  }

  @Override
  public Void visitInvokeInterface_(InvokeInterface node) {
    mv.visitMethodInsn(INVOKEINTERFACE, node.ownerType().className(),
        node.name(), node.signature().descriptorString());
    return null;
  }

  @Override
  public Void visitInvokeSpecial_(InvokeSpecial node) {
    mv.visitMethodInsn(INVOKESPECIAL, node.ownerType().className(),
        node.name(), node.signature().descriptorString());
    return null;
  }

  @Override
  public Void visitInvokeStatic_(InvokeStatic node) {
    mv.visitMethodInsn(INVOKESTATIC, node.ownerType().className(),
        node.name(), node.signature().descriptorString());
    return null;
  }

  @Override
  public Void visitInvokeVirtual_(InvokeVirtual node) {
    mv.visitMethodInsn(INVOKEVIRTUAL, node.ownerType().className(),
        node.name(), node.signature().descriptorString());
    return null;
  }

  @Override
  public Void visitIStore_(IStore node) {
    mv.visitVarInsn(ISTORE, node.index());
    return null;
  }

  @Override
  public Void visitLabelLineNumber_(LabelLineNumber node) {
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitLineNumber(node.line(), l1);
    return null;
  }

  @Override
  public Void visitNewArray_(NewArray node) {
    if (node.elementType().isObjectType())
      mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
    else if (node.elementType().isByteType())
      mv.visitIntInsn(NEWARRAY, T_BYTE);
    return null;
  }

  @Override
  public Void visitNewInstance_(NewInstance node) {
    mv.visitTypeInsn(NEW, node.type().className());
    return null;
  }

  @Override
  public Void visitObjectArrayLoad_(ObjectArrayLoad node) {
    mv.visitInsn(AALOAD);
    return null;
  }

  @Override
  public Void visitObjectArrayStore_(ObjectArrayStore node) {
    mv.visitInsn(AASTORE);
    return null;
  }

  @Override
  public Void visitOrThenElse_(OrThenElse node) {
    Label trueLabel = new Label();
    Label endLabel = new Label();
    visit_(node.left());
    mv.visitJumpInsn(IFNE, trueLabel);
    visit_(node.right());
    mv.visitJumpInsn(IFNE, trueLabel);
    visit_(node.falseFrame());
    mv.visitJumpInsn(GOTO, endLabel);
    mv.visitLabel(trueLabel);
    visit_(node.trueFrame());
    mv.visitLabel(endLabel);
    return null;
  }

  @Override
  public Void visitPop_(Pop node) {
    mv.visitInsn(POP);
    return null;
  }

  @Override
  public Void visitPushChar_(PushChar node) {
    mv.visitIntInsn(BIPUSH, node.value());
    return null;
  }

  @Override
  public Void visitPushDouble_(PushDouble node) {
    pushDouble(node.value());
    return null;
  }

  @Override
  public Void visitPushFalse_(PushFalse node) {
    mv.visitInsn(ICONST_0);
    return null;
  }

  @Override
  public Void visitPushFloat_(PushFloat node) {
    pushFloat(node.value());
    return null;
  }

  @Override
  public Void visitPushInt_(PushInt node) {
    pushInt(node.value());
    return null;
  }

  @Override
  public Void visitPushNull_(PushNull node) {
    mv.visitInsn(ACONST_NULL);
    return null;
  }

  @Override
  public Void visitPushString_(PushString node) {
    mv.visitLdcInsn(node.value());
    return null;
  }

  @Override
  public Void visitPushTrue_(PushTrue node) {
    mv.visitInsn(ICONST_1);
    return null;
  }

  @Override
  public Void visitPutField_(PutField node) {
    mv.visitFieldInsn(PUTFIELD, node.ownerType().className(), node.name(),
        node.type().descriptorString());
    return null;
  }

  @Override
  public Void visitPutStatic_(PutStatic node) {
    mv.visitFieldInsn(PUTSTATIC, node.ownerType().className(), node.name(),
        node.type().descriptorString());
    return null;
  }

  @Override
  public Void visitReturn_(Return node) {
    mv.visitInsn(RETURN);
    return null;
  }

  @Override
  public Void visitSubtract_(Subtract node) {
    mv.visitInsn(ISUB);
    return null;
  }

  @Override
  public Void visitTryCatch_(TryCatch node) {
    Label nlrTryStart = new Label();
    Label nlrTryEnd = new Label();
    Label nlrTryHandler = new Label();
    mv.visitTryCatchBlock(nlrTryStart, nlrTryEnd, nlrTryHandler, node
        .exception().className());
    mv.visitLabel(nlrTryStart);
    visit_(node.tryFrame());
    mv.visitLabel(nlrTryEnd);
    Label endLabel = new Label();
    if (node.doFrame() != null) {
      visit_(node.doFrame());
    }
    mv.visitJumpInsn(GOTO, endLabel);
    mv.visitLabel(nlrTryHandler);
    visit_(node.catchFrame());
    mv.visitLabel(endLabel);
    return null;
  }
 
  @Override
  public Void visitWhileFalseLoop_(WhileFalseLoop node) {
    Label topLabel = new Label();
    Label doLabel = new Label();
    Label endLabel = new Label();
    mv.visitLabel(topLabel);

    visit_(node.testFrame());
    mv.visitJumpInsn(IFEQ, doLabel);
    mv.visitJumpInsn(GOTO, endLabel);
    mv.visitLabel(doLabel);
    visit_(node.doFrame());
    mv.visitJumpInsn(GOTO, topLabel);
    mv.visitLabel(endLabel);
    return null;
  }

  @Override
  public Void visitWhileGreaterThanLoop_(WhileGreaterThanLoop node) {
    Label testLabel = new Label();
    Label endLabel = new Label();
    mv.visitLabel(testLabel);
    visit_(node.testFrame());
    mv.visitJumpInsn(IF_ICMPLT, endLabel);
    visit_(node.doFrame());
    mv.visitJumpInsn(GOTO, testLabel);
    mv.visitLabel(endLabel);
    return null;
  }

  @Override
  public Void visitWhileLessThanLoop_(WhileLessThanLoop node) {
    Label testLabel = new Label();
    Label endLabel = new Label();
    mv.visitLabel(testLabel);
    visit_(node.testFrame());
    mv.visitJumpInsn(IF_ICMPGT, endLabel);
    visit_(node.doFrame());
    mv.visitJumpInsn(GOTO, testLabel);
    mv.visitLabel(endLabel);
    return null;
  }

  @Override
  public Void visitWhileTrueLoop_(WhileTrueLoop node) {
    Label topLabel = new Label();
    Label doLabel = new Label();
    Label endLabel = new Label();
    mv.visitLabel(topLabel);

    visit_(node.testFrame());
    mv.visitJumpInsn(IFNE, doLabel);
    mv.visitJumpInsn(GOTO, endLabel);
    mv.visitLabel(doLabel);
    visit_(node.doFrame());
    mv.visitJumpInsn(GOTO, topLabel);
    mv.visitLabel(endLabel);
    return null;
  }

  public void write(JVMMethod method) {
    mv = cw.visitMethod(ACC_PUBLIC + (method.isStatic() ? ACC_STATIC : 0),
        method.name(), method.signature().descriptorString(), null,
        null);
    mv.visitCode();
    // logToErr("Method: " + method);

    Label startLabel = new Label();
    mv.visitLabel(startLabel);

    for (JVMInstruction inst : method.instructions()) {
      inst.accept_(this);
    }
    produceLocalVariableInfo(startLabel, method.locals());
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }
}
TOP

Related Classes of st.gravel.support.compiler.ASMMethodWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.