// File RTCG4.java --- the power example // sestoft@itu.dk * 2002-09 // Using the gnu.bytecode package from http://www.gnu.org/software/kawa import gnu.bytecode.*; import java.io.*; public class RTCG4 { public static void main(String[] args) throws IOException, NoSuchMethodException, IllegalAccessException, java.lang.reflect.InvocationTargetException { int count = Integer.parseInt(args[0]); int n = 16; ClassType co = new ClassType("MyClass"); co.setSuper("java.lang.Object"); co.setModifiers(Access.PUBLIC); { // Build: public static int MyPower(int x) { ... } Method mo = co.addMethod("MyPower"); mo.setSignature("(I)I"); mo.setModifiers(Access.PUBLIC | Access.STATIC); mo.initCode(); PowerGen(mo, n); } // Output class file in human-readable format: ClassTypeWriter.print(co, System.out, 0); // Output class file to array: byte[] classFile = co.writeToArray(); // Load the class file from byte array into the JVM Class ty = new ArrayClassLoader().loadClass("MyClass", classFile); // Get the MyMethod(int): java.lang.reflect.Method m = ty.getMethod("MyPower", new Class[] { int.class }); // Call the method: System.out.println(m.invoke(null, new Object[] { new Integer(3) })); } public static int Power(int n, int x) { int p; p = 1; while (n > 0) { if (n % 2 == 0) { x = x * x; n = n / 2; } else { p = p * x; n = n - 1; } } return p; } public static void PowerGen(Method mo, int n) { CodeAttr jvmg = mo.getCode(); Scope scope = mo.pushScope(); Variable varx = scope.addVariable(jvmg, Type.int_type, "x"); Variable varp = scope.addVariable(jvmg, Type.int_type, "p"); jvmg.emitPushInt(1); jvmg.emitStore(varp); // p = 1; while (n > 0) { if (n % 2 == 0) { jvmg.emitLoad(varx); // x is arg_0 jvmg.emitLoad(varx); jvmg.emitMul(); jvmg.emitStore(varx); // x = x * x n = n / 2; } else { jvmg.emitLoad(varp); // load p jvmg.emitLoad(varx); // load x (arg_0) jvmg.emitMul(); jvmg.emitStore(varp); // p = p * x n = n - 1; } } jvmg.emitLoad(varp); jvmg.emitReturn(); // return p; mo.popScope(); } } // This is needed because defineClass is protected in java.lang.ClassLoader: class ArrayClassLoader extends ClassLoader { public Class loadClass(String name, byte[] classFile) { return defineClass(name, classFile, 0, classFile.length); } }