All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xmlvm.proc.out.JavaByteCodeOutputProcess Maven / Gradle / Ivy

There is a newer version: 0.96-beta4
Show newest version
/* 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 mapID2InstructionHandle;
		private Map> mapID2BranchInstructions;
		private ArrayList currentIds;

		public InstructionHandlerManager()
		{
			mapID2InstructionHandle= new HashMap();
			mapID2BranchInstructions= new HashMap>();
			currentIds= new ArrayList();
		}

		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 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 l= mapID2BranchInstructions.get(id);
			if (l == null)
				l= new ArrayList();
			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 createBytecode(Document document, String path) throws IllegalXMLVMException, IOException
	{
		List result= new ArrayList();
		Element root= document.getRootElement();
		if (!root.getName().equals("xmlvm"))
			throw new IllegalXMLVMException("Root element needs to be ");
		@SuppressWarnings("unchecked")
		List 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= "";
			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 params= signature.getChildren("parameter", nsXMLVM);
		if (params.isEmpty())
			return Type.NO_ARGS;
		List argTypes= new ArrayList();
		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 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();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy