Package org.xmlvm.proc.out

Source Code of org.xmlvm.proc.out.JavaByteCodeOutputProcess

/* Copyright (c) 2002-2011 by XMLVM.org
*
* Project Info:  http://www.xmlvm.org
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
* USA.
*/

package org.xmlvm.proc.out;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.bcel.Constants;
import org.apache.bcel.generic.AALOAD;
import org.apache.bcel.generic.AASTORE;
import org.apache.bcel.generic.ACONST_NULL;
import org.apache.bcel.generic.ANEWARRAY;
import org.apache.bcel.generic.ARETURN;
import org.apache.bcel.generic.ARRAYLENGTH;
import org.apache.bcel.generic.ASTORE;
import org.apache.bcel.generic.ArrayType;
import org.apache.bcel.generic.BIPUSH;
import org.apache.bcel.generic.BranchInstruction;
import org.apache.bcel.generic.CHECKCAST;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.CompoundInstruction;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.D2F;
import org.apache.bcel.generic.D2I;
import org.apache.bcel.generic.DADD;
import org.apache.bcel.generic.DDIV;
import org.apache.bcel.generic.DLOAD;
import org.apache.bcel.generic.DMUL;
import org.apache.bcel.generic.DSTORE;
import org.apache.bcel.generic.DSUB;
import org.apache.bcel.generic.DUP;
import org.apache.bcel.generic.F2I;
import org.apache.bcel.generic.FADD;
import org.apache.bcel.generic.FCMPG;
import org.apache.bcel.generic.FCMPL;
import org.apache.bcel.generic.FLOAD;
import org.apache.bcel.generic.FMUL;
import org.apache.bcel.generic.FSTORE;
import org.apache.bcel.generic.FSUB;
import org.apache.bcel.generic.FieldGen;
import org.apache.bcel.generic.GOTO;
import org.apache.bcel.generic.I2B;
import org.apache.bcel.generic.I2F;
import org.apache.bcel.generic.I2L;
import org.apache.bcel.generic.IADD;
import org.apache.bcel.generic.ICONST;
import org.apache.bcel.generic.IDIV;
import org.apache.bcel.generic.IFEQ;
import org.apache.bcel.generic.IFNE;
import org.apache.bcel.generic.IF_ACMPNE;
import org.apache.bcel.generic.IF_ICMPGE;
import org.apache.bcel.generic.IF_ICMPGT;
import org.apache.bcel.generic.IF_ICMPLE;
import org.apache.bcel.generic.IF_ICMPLT;
import org.apache.bcel.generic.IF_ICMPNE;
import org.apache.bcel.generic.IINC;
import org.apache.bcel.generic.ILOAD;
import org.apache.bcel.generic.IMUL;
import org.apache.bcel.generic.IREM;
import org.apache.bcel.generic.ISTORE;
import org.apache.bcel.generic.ISUB;
import org.apache.bcel.generic.Instruction;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.L2I;
import org.apache.bcel.generic.LADD;
import org.apache.bcel.generic.LLOAD;
import org.apache.bcel.generic.LSTORE;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.NOP;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.POP;
import org.apache.bcel.generic.PUSH;
import org.apache.bcel.generic.Type;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.xmlvm.IllegalXMLVMException;
import org.xmlvm.Log;
import org.xmlvm.main.Arguments;
import org.xmlvm.proc.BundlePhase1;
import org.xmlvm.proc.BundlePhase2;
import org.xmlvm.proc.XmlvmProcessImpl;
import org.xmlvm.proc.XmlvmResource;
import org.xmlvm.proc.in.file.ClassFile;

/**
* This process takes XMLVM and turns it into Java ByteCode.
*/
public class JavaByteCodeOutputProcess extends XmlvmProcessImpl
{

  private static final class InstructionHandlerManager
  {

    private Map<Integer, InstructionHandle> mapID2InstructionHandle;
    private Map<Integer, List<BranchInstruction>> mapID2BranchInstructions;
    private ArrayList<Integer> currentIds;

    public InstructionHandlerManager()
    {
      mapID2InstructionHandle= new HashMap<Integer, InstructionHandle>();
      mapID2BranchInstructions= new HashMap<Integer, List<BranchInstruction>>();
      currentIds= new ArrayList<Integer>();
    }

    public void setLabelID(int id) throws IllegalXMLVMException
    {
      currentIds.add(id);
    }

    public void registerInstructionHandle(InstructionHandle ih)
    {
      if (currentIds.size() == 0)
        return;

      for (Integer currentID : currentIds)
      {
        mapID2InstructionHandle.put(currentID, ih);
        List<BranchInstruction> l= mapID2BranchInstructions.get(currentID);
        if (l != null)
        {
          // We encountered some branch instructions earlier before we
          // registered this instruction handle
          for (BranchInstruction bi : l)
          {
            bi.setTarget(ih);
          }
          mapID2BranchInstructions.remove(currentID);
        }

      }
      currentIds.clear();

    }

    public void registerBranchInstruction(BranchInstruction g, int id)
    {
      InstructionHandle ih= mapID2InstructionHandle.get(id);
      if (ih != null)
      {
        // Instruction handle was registered before
        g.setTarget(ih);
        return;
      }
      // We haven't seen the instruction handle yet. Remember this branch
      // instruction
      List<BranchInstruction> l= mapID2BranchInstructions.get(id);
      if (l == null)
        l= new ArrayList<BranchInstruction>();
      l.add(g);
      mapID2BranchInstructions.put(id, l);
    }

    public void checkConsistency()
    {
      // At the end of processing the byte code of a method,
      // mapID2BranchInstructions
      // should be empty.
      if (mapID2BranchInstructions.size() != 0)
      {
        System.err.println("Following label IDs could not be resolved: " + mapID2BranchInstructions.keySet());
        ;
        System.exit(-1);
      }
    }
  }

  private static final Namespace nsXMLVM= Namespace.getNamespace("vm", "http://xmlvm.org");

  private InstructionFactory factory;
  private InstructionList instructionList;
  private ConstantPoolGen constantPoolGen;
  private ClassGen classGen;
  private InstructionHandlerManager instructionHandlerManager;
  private String fullQualifiedClassName;

  public JavaByteCodeOutputProcess(Arguments arguments)
  {
    super(arguments);
    addAllXmlvmEmittingProcessesAsInput();
  }

  public boolean processPhase1(BundlePhase1 bundle)
  {
    return true;
  }

  public boolean processPhase2(BundlePhase2 bundle)
  {
    for (XmlvmResource xmlvmResource : bundle.getResources())
    {
      try
      {
        bundle.addOutputFiles(createBytecode(xmlvmResource.getXmlvmDocument(), arguments.option_out()));
      }
      catch (IOException ex)
      {
        ex.printStackTrace();
        Log.error("Could not create class file for: " + xmlvmResource.getName());
        return false;
      }
      catch (IllegalXMLVMException ex)
      {
        ex.printStackTrace();
        Log.error("Could not create class file for: " + xmlvmResource.getName());
        return false;
      }
    }
    return true;
  }

  /**
   * Creates Java binary files from the org.jdom.Document that is associated
   * with this object. The location for the binary files is determined by the
   * given string path.
   */
  private List<OutputFile> createBytecode(Document document, String path) throws IllegalXMLVMException, IOException
  {
    List<OutputFile> result= new ArrayList<OutputFile>();
    Element root= document.getRootElement();
    if (!root.getName().equals("xmlvm"))
      throw new IllegalXMLVMException("Root element needs to be <xmlvm>");
    @SuppressWarnings("unchecked")
    List<Element> clazzes= root.getChildren("class", nsXMLVM);

    for (Element clazz : clazzes)
    {
      if (clazz == null)
        throw new IllegalXMLVMException("XMLVM contains no class");
      createClass(clazz);
      for (Object o : clazz.getChildren())
      {
        Element decl= (Element) o;
        String tag= decl.getName();
        if (tag.equals("method"))
          createMethod(decl);
        else if (tag.equals("field"))
          createField(decl);
        else
          throw new IllegalXMLVMException("Unknown class declaration '" + tag + "'");
      }

      String packageName= clazz.getAttributeValue("package");

      // If there is a package name, then create necessary
      // folders for that package.
      if (packageName != null && packageName != "")
      {
        packageName= File.separatorChar + packageName.replace('.', File.separatorChar);
        new File(path + File.separatorChar + packageName).mkdirs();
      }
      else
      {
        packageName= "";
      }

      String className= clazz.getAttributeValue("name");

      OutputFile outputFile= new OutputFile(classGen.getJavaClass().getBytes());
      outputFile.setFileName(className + ClassFile.CLASS_ENDING);
      outputFile.setLocation(path + File.separatorChar + packageName);
      result.add(outputFile);
    }
    return result;
  }

  private void createClass(Element clazz)
  {
    String packageName= clazz.getAttributeValue("package");
    packageName= packageName == null ? "" : packageName;
    String clazzName= clazz.getAttributeValue("name");
    String fileName= clazzName + ".java";
    fullQualifiedClassName= packageName.equals("") ? clazzName : packageName + "." + clazzName;
    String baseClazz= clazz.getAttributeValue("extends");
    // TODO Read interfaces
    String[] interfaces= new String[] {};
    short accessFlags= getAccessFlags(clazz);
    classGen= new ClassGen(fullQualifiedClassName, baseClazz, fileName, accessFlags, interfaces);
    constantPoolGen= classGen.getConstantPool();
    factory= new InstructionFactory(classGen, constantPoolGen);
  }

  private void createMethod(Element method) throws IllegalXMLVMException
  {
    instructionList= new InstructionList();
    instructionHandlerManager= new InstructionHandlerManager();
    String methodName= method.getAttributeValue("name");

    Element signature= method.getChild("signature", nsXMLVM);
    Type retType= collectReturnType(signature);
    Type[] argTypes= collectArgumentTypes(signature);
    short accessFlags= getAccessFlags(method);

    if (methodName.equals(".cctor")) // Same concept, different names in
    // .net/JVM. Note we are doing init of
    // statics for a class
    {
      methodName= "<clinit>";
      accessFlags= 0x8; // static
    }

    MethodGen m= new MethodGen(accessFlags, retType, argTypes, null, methodName, fullQualifiedClassName, instructionList, constantPoolGen);
    Element code= method.getChild("code", nsXMLVM);
    createCode(code);
    instructionHandlerManager.checkConsistency();
    m.setMaxLocals();
    m.setMaxStack();
    classGen.addMethod(m.getMethod());
    instructionList.dispose();
  }

  private void createField(Element field) throws IllegalXMLVMException
  {
    String name= field.getAttributeValue("name");
    Type t= parseTypeString(field.getAttributeValue("type"));
    short flags= getAccessFlags(field);
    FieldGen f= new FieldGen(flags, t, name, constantPoolGen);
    classGen.addField(f.getField());
  }

  private Type collectReturnType(Element signature) throws IllegalXMLVMException
  {
    Element ret= signature.getChild("return", nsXMLVM);
    String t= ret.getAttributeValue("type");
    if (t.equals("void"))
      return Type.VOID;
    return parseTypeString(t);
  }

  private Type[] collectArgumentTypes(Element signature) throws IllegalXMLVMException
  {
    List<Element> params= signature.getChildren("parameter", nsXMLVM);
    if (params.isEmpty())
      return Type.NO_ARGS;
    List<Type> argTypes= new ArrayList<Type>();
    for (Element p : params)
    {
      String type= p.getAttributeValue("type");
      argTypes.add(parseTypeString(type));
    }
    return argTypes.toArray(new Type[0]);
  }

  private Type parseTypeString(String type) throws IllegalXMLVMException
  {
    int arrayDimension= 0;
    while (type.endsWith("[]"))
    {
      arrayDimension++;
      type= type.substring(0, type.length() - 2);
    }
    Type baseType= null;
    if (type.equals("java.lang.String"))
      baseType= Type.STRING;
    if (type.equals("boolean"))
      baseType= Type.BOOLEAN;
    if (type.equals("byte"))
      baseType= Type.BYTE;
    if (type.equals("short"))
      baseType= Type.SHORT;
    if (type.equals("int"))
      baseType= Type.INT;
    if (type.equals("long"))
      baseType= Type.LONG;
    if (type.equals("float"))
      baseType= Type.FLOAT;
    if (type.equals("double"))
      baseType= Type.DOUBLE;
    if (type.equals("char"))
      baseType= Type.CHAR;
    if (type.equals("java.lang.Object"))
      baseType= Type.OBJECT;
    if (baseType == null)
      baseType= new ObjectType(type);
    if (arrayDimension == 0)
      return baseType;
    else
      return new ArrayType(baseType, arrayDimension);
  }

  private void createCode(Element code) throws IllegalXMLVMException
  {
    List<Element> instructions= code.getChildren();
    for (Element inst : instructions)
    {
      String name= inst.getName();
      String opcMethodName= "createInstruction" + name.substring(0, 1).toUpperCase() + name.substring(1);
      Class<?> appClazz;
      Method opcMeth;
      Class<?>[] paramTypes= { Element.class };
      Object[] params= { inst };
      appClazz= this.getClass();
      Object newInstr= null;
      try
      {
        opcMeth= appClazz.getDeclaredMethod(opcMethodName, paramTypes);
        newInstr= opcMeth.invoke(this, params);
      }
      catch (NoSuchMethodException ex)
      {
        throw new IllegalXMLVMException("Illegal instruction 1, unable to find method " + opcMethodName + " for '" + name + "'");
      }
      catch (InvocationTargetException ex)
      {
        ex.printStackTrace();
        throw new IllegalXMLVMException("Illegal instruction 2 '" + name + "'");
      }
      catch (IllegalAccessException ex)
      {
        throw new IllegalXMLVMException("Illegal instruction 3 '" + name + "'");
      }
      if (newInstr != null)
      {
        InstructionHandle ih= null;
        if (newInstr instanceof BranchInstruction)
          ih= instructionList.append((BranchInstruction) newInstr);
        else if (newInstr instanceof CompoundInstruction)
          ih= instructionList.append((CompoundInstruction) newInstr);
        else if (newInstr instanceof Instruction)
          ih= instructionList.append((Instruction) newInstr);
        instructionHandlerManager.registerInstructionHandle(ih);

      }
    }
  }

  private short getAccessFlags(Element elem)
  {
    short af= 0;
    af|= checkAccessFlag(elem, "isPublic", Constants.ACC_PUBLIC);
    af|= checkAccessFlag(elem, "isPrivate", Constants.ACC_PRIVATE);
    af|= checkAccessFlag(elem, "isProtected", Constants.ACC_PROTECTED);
    af|= checkAccessFlag(elem, "isSynchronized", Constants.ACC_SYNCHRONIZED);
    af|= checkAccessFlag(elem, "isStatic", Constants.ACC_STATIC);
    return af;
  }

  private short checkAccessFlag(Element elem, String flag, short jvmFlag)
  {
    String val= elem.getAttributeValue(flag);
    if (val == null)
      return 0;
    return val.equals("true") ? jvmFlag : 0;
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionVar(Element inst)
  {
    return null;
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionCheckcast(Element inst) throws IllegalXMLVMException
  {
    String classType= inst.getAttributeValue("type");
    return new CHECKCAST(constantPoolGen.addClass(classType));
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionF2i(Element inst)
  {
    return new F2I();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionFmul(Element inst)
  {
    return new FMUL();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionFcmpl(Element inst)
  {
    return new FCMPL();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionFcmpg(Element inst)
  {
    return new FCMPG();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionFsub(Element inst)
  {
    return new FSUB();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionDup(Element inst)
  {
    return new DUP();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionLabel(Element inst) throws IllegalXMLVMException
  {
    int id= Integer.parseInt(inst.getAttributeValue("id"));
    instructionHandlerManager.setLabelID(id);
    return null;
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionGoto(Element inst)
  {
    int id= Integer.parseInt(inst.getAttributeValue("label"));
    BranchInstruction bi= new GOTO(null);
    instructionHandlerManager.registerBranchInstruction(bi, id);
    return bi;
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionD2f(Element inst)
  {
    return new D2F();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionI2f(Element inst)
  {
    return new I2F();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionD2i(Element inst)
  {
    return new D2I();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionArraylength(Element inst)
  {
    return new ARRAYLENGTH();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIf_acmpne(Element inst)
  {
    int id= Integer.parseInt(inst.getAttributeValue("label"));
    BranchInstruction bi= new IF_ACMPNE(null);
    instructionHandlerManager.registerBranchInstruction(bi, id);
    return bi;
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIf_icmplt(Element inst)
  {
    int id= Integer.parseInt(inst.getAttributeValue("label"));
    BranchInstruction bi= new IF_ICMPLT(null);
    instructionHandlerManager.registerBranchInstruction(bi, id);
    return bi;
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIf_icmpgt(Element inst)
  {
    int id= Integer.parseInt(inst.getAttributeValue("label"));
    BranchInstruction bi= new IF_ICMPGT(null);
    instructionHandlerManager.registerBranchInstruction(bi, id);
    return bi;
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIf_icmpge(Element inst)
  {
    int id= Integer.parseInt(inst.getAttributeValue("label"));
    BranchInstruction bi= new IF_ICMPGE(null);
    instructionHandlerManager.registerBranchInstruction(bi, id);
    return bi;
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIf_icmple(Element inst)
  {
    int id= Integer.parseInt(inst.getAttributeValue("label"));
    BranchInstruction bi= new IF_ICMPLE(null);
    instructionHandlerManager.registerBranchInstruction(bi, id);
    return bi;
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIf_icmpne(Element inst)
  {
    int id= Integer.parseInt(inst.getAttributeValue("label"));
    BranchInstruction bi= new IF_ICMPNE(null);
    instructionHandlerManager.registerBranchInstruction(bi, id);
    return bi;
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIfeq(Element inst)
  {
    int id= Integer.parseInt(inst.getAttributeValue("label"));
    BranchInstruction bi= new IFEQ(null);
    instructionHandlerManager.registerBranchInstruction(bi, id);
    return bi;
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIfne(Element inst)
  {
    int id= Integer.parseInt(inst.getAttributeValue("label"));
    BranchInstruction bi= new IFNE(null);
    instructionHandlerManager.registerBranchInstruction(bi, id);
    return bi;
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionAconst_null(Element inst) throws IllegalXMLVMException
  {
    return new ACONST_NULL();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionAload(Element inst) throws IllegalXMLVMException
  {
    String t= inst.getAttributeValue("type");
    Type type= parseTypeString(t);
    int idx= Integer.parseInt(inst.getAttributeValue("index"));
    return factory.createLoad(type, idx);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionInvokespecial(Element inst) throws IllegalXMLVMException
  {
    return createInvokeInstruction(inst, Constants.INVOKESPECIAL);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionInvokevirtual(Element inst) throws IllegalXMLVMException
  {
    return createInvokeInstruction(inst, Constants.INVOKEVIRTUAL);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionInvokestatic(Element inst) throws IllegalXMLVMException
  {
    return createInvokeInstruction(inst, Constants.INVOKESTATIC);
  }

  private Instruction createInvokeInstruction(Element inst, short kind) throws IllegalXMLVMException
  {
    String classType= inst.getAttributeValue("class-type");
    String methodName= inst.getAttributeValue("method");
    Element signature= inst.getChild("signature", nsXMLVM);
    Type retType= collectReturnType(signature);
    Type[] argTypes= collectArgumentTypes(signature);
    return factory.createInvoke(classType, methodName, retType, argTypes, kind);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionReturn(Element inst)
  {
    return factory.createReturn(Type.VOID);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIreturn(Element inst)
  {
    return factory.createReturn(Type.INT);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionDreturn(Element inst)
  {
    return factory.createReturn(Type.DOUBLE);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionFreturn(Element inst)
  {
    return factory.createReturn(Type.FLOAT);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionLreturn(Element inst)
  {
    return factory.createReturn(Type.LONG);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionGetstatic(Element inst) throws IllegalXMLVMException
  {
    String classType= inst.getAttributeValue("class-type");
    String field= inst.getAttributeValue("field");
    Type type= parseTypeString(inst.getAttributeValue("type"));
    return factory.createFieldAccess(classType, field, type, Constants.GETSTATIC);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private CompoundInstruction createInstructionLdc(Element inst) throws IllegalXMLVMException
  {
    return createInstructionPush(inst);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private CompoundInstruction createInstructionLdc2_w(Element inst) throws IllegalXMLVMException
  {
    return createInstructionPush(inst);
  }

  private CompoundInstruction createInstructionPush(Element inst) throws IllegalXMLVMException
  {
    String t= inst.getAttributeValue("type");
    Type type= parseTypeString(t);
    String value= inst.getAttributeValue("value");
    if (type == Type.STRING)
      return new PUSH(constantPoolGen, value);
    else if (type == Type.INT)
      return new PUSH(constantPoolGen, Integer.parseInt(value));
    else if (type == Type.FLOAT)
      return new PUSH(constantPoolGen, Float.parseFloat(value));
    else if (type == Type.DOUBLE)
      return new PUSH(constantPoolGen, Double.parseDouble(value));
    else if (type == Type.LONG)
      return new PUSH(constantPoolGen, Long.parseLong(value));
    else
      throw new IllegalXMLVMException(inst.getName() + " with bad type '" + t + "'");
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIconst(Element inst)
  {
    int value= Integer.parseInt(inst.getAttributeValue("value"));
    return new ICONST(value);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIinc(Element inst)
  {
    int index= Integer.parseInt(inst.getAttributeValue("index"));
    int incr= Integer.parseInt(inst.getAttributeValue("incr"));
    return new IINC(index, incr);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionBipush(Element inst)
  {
    byte val= (byte) Integer.parseInt(inst.getAttributeValue("value"));
    return new BIPUSH(val);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIstore(Element inst) throws IllegalXMLVMException
  {
    int idx= Integer.parseInt(inst.getAttributeValue("index"));
    return new ISTORE(idx);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionLstore(Element inst) throws IllegalXMLVMException
  {
    // BCEL's LSTORE creation instruction only takes an integer!!!
    int idx= Integer.parseInt(inst.getAttributeValue("index"));
    return new LSTORE(idx);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIload(Element inst) throws IllegalXMLVMException
  {
    int idx= Integer.parseInt(inst.getAttributeValue("index"));
    return new ILOAD(idx);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionLload(Element inst) throws IllegalXMLVMException
  {
    int idx= Integer.parseInt(inst.getAttributeValue("index"));
    return new LLOAD(idx);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionAstore(Element inst)
  {
    int idx= Integer.parseInt(inst.getAttributeValue("index"));
    return new ASTORE(idx);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionFstore(Element inst) throws IllegalXMLVMException
  {
    int idx= Integer.parseInt(inst.getAttributeValue("index"));
    return new FSTORE(idx);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionFload(Element inst) throws IllegalXMLVMException
  {
    int idx= Integer.parseInt(inst.getAttributeValue("index"));
    return new FLOAD(idx);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionDstore(Element inst) throws IllegalXMLVMException
  {
    int idx= Integer.parseInt(inst.getAttributeValue("index"));
    return new DSTORE(idx);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionDload(Element inst) throws IllegalXMLVMException
  {
    int idx= Integer.parseInt(inst.getAttributeValue("index"));
    return new DLOAD(idx);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIadd(Element inst) throws IllegalXMLVMException
  {
    return new IADD();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionLadd(Element inst) throws IllegalXMLVMException
  {
    return new LADD();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIsub(Element inst) throws IllegalXMLVMException
  {
    return new ISUB();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionDsub(Element inst) throws IllegalXMLVMException
  {
    return new DSUB();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionAaload(Element inst) throws IllegalXMLVMException
  {
    return new AALOAD();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionDadd(Element inst) throws IllegalXMLVMException
  {
    return new DADD();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionFadd(Element inst) throws IllegalXMLVMException
  {
    return new FADD();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionImul(Element inst) throws IllegalXMLVMException
  {
    return new IMUL();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionDmul(Element inst) throws IllegalXMLVMException
  {
    return new DMUL();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIdiv(Element inst) throws IllegalXMLVMException
  {
    return new IDIV();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionDdiv(Element inst) throws IllegalXMLVMException
  {
    return new DDIV();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionIrem(Element inst) throws IllegalXMLVMException
  {
    return new IREM();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionNew(Element inst)
  {
    String t= inst.getAttributeValue("type");
    return factory.createNew(t);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionPutfield(Element inst) throws IllegalXMLVMException
  {
    String classType= inst.getAttributeValue("class-type");
    String field= inst.getAttributeValue("field");
    String type= inst.getAttributeValue("type");
    Type t= parseTypeString(type);
    return factory.createPutField(classType, field, t);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionPutstatic(Element inst) throws IllegalXMLVMException
  {
    String classType= inst.getAttributeValue("class-type");
    String field= inst.getAttributeValue("field");
    String type= inst.getAttributeValue("type");
    Type t= parseTypeString(type);
    return factory.createPutStatic(classType, field, t);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionPop(Element inst) throws IllegalXMLVMException
  {
    return new POP();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionGetfield(Element inst) throws IllegalXMLVMException
  {
    String classType= inst.getAttributeValue("class-type");
    String field= inst.getAttributeValue("field");
    String type= inst.getAttributeValue("type");
    Type t= parseTypeString(type);
    return factory.createGetField(classType, field, t);
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionAreturn(Element inst)
  {
    return new ARETURN();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionAnewarray(Element inst)
  {
    String classType= inst.getAttributeValue("elementType");
    return new ANEWARRAY(constantPoolGen.addClass(classType));
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionAastore(Element inst)
  {
    return new AASTORE();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionNop(Element inst)
  {
    return new NOP();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionI2b(Element inst)
  {
    return new I2B();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionI2l(Element inst)
  {
    return new I2L();
  }

  @SuppressWarnings("unused")
  // Called using reflection
  private Instruction createInstructionL2i(Element inst)
  {
    return new L2I();
  }
}
TOP

Related Classes of org.xmlvm.proc.out.JavaByteCodeOutputProcess

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.