/** * Generates Dalvik bytecode equivalent to the following method. public static void hello() { int * a = 0xabcd; int b = 0xaaaa; int c = a - b; String s = Integer.toHexString(c); * System.out.println(s); int i=Function.run(); return; } */ private static void generateHelloMethod(DexMaker dexMaker, TypeId<?> declaringType) { // Lookup some types we'll need along the way. TypeId<System> systemType = TypeId.get(System.class); TypeId<PrintStream> printStreamType = TypeId.get(PrintStream.class); // TypeId<Function> function=TypeId.get(Function.class); // Identify the 'hello()' method on declaringType. MethodId hello = declaringType.getMethod(TypeId.VOID, "hello"); // Declare that method on the dexMaker. Use the returned Code instance // as a builder that we can append instructions to. Code code = dexMaker.declare(hello, Modifier.STATIC | Modifier.PUBLIC); // Declare all the locals we'll need up front. The API requires this. Local<Integer> a = code.newLocal(TypeId.INT); Local<Integer> b = code.newLocal(TypeId.INT); Local<Integer> c = code.newLocal(TypeId.INT); Local<String> s = code.newLocal(TypeId.STRING); Local<PrintStream> localSystemOut = code.newLocal(printStreamType); Local<Integer> i = code.newLocal(TypeId.INT); // Local<Function> localFunction=code.newLocal(function); // int a = 0xabcd; code.loadConstant(a, 0xabcd); // int b = 0xaaaa; code.loadConstant(b, 0xaaad); // int c = a - b; code.op(BinaryOp.SUBTRACT, c, a, b); // String s = Integer.toHexString(c); MethodId<Integer, String> toHexString = TypeId.get(Integer.class).getMethod(TypeId.STRING, "toHexString", TypeId.INT); code.invokeStatic(toHexString, s, c); // int i=Function.run(); MethodId<Function, Integer> run = TypeId.get(Function.class).getMethod(TypeId.INT, "run", TypeId.INT); code.invokeStatic(run, i, b); // System.out.println(s); FieldId<System, PrintStream> systemOutField = systemType.getField(printStreamType, "out"); code.sget(systemOutField, localSystemOut); MethodId<PrintStream, Void> printlnMethod = printStreamType.getMethod(TypeId.VOID, "println", TypeId.STRING); code.invokeVirtual(printlnMethod, null, localSystemOut, s); // code.invokeVirtual(printlnMethod, null, localSystemOut, s); // return; code.returnVoid(); }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DexMaker dexMaker = new DexMaker(); File dexOutputDir = getDir("dex", 0); System.out.println("create dexmaker"); System.out.println(Environment.getExternalStorageDirectory().toString()); // Generate a HelloWorld class. TypeId<?> helloWorld = TypeId.get("LHelloWorld;"); dexMaker.declare(helloWorld, "HelloWorld.generated", Modifier.PUBLIC, TypeId.OBJECT); generateHelloMethod(dexMaker, helloWorld); // Create the dex file and load it. File outputDir = new File(dexOutputDir.getAbsolutePath()); ClassLoader loader; try { System.out.println("load class"); loader = dexMaker.generateAndLoad(this.getClassLoader(), outputDir); Class<?> helloWorldClass = loader.loadClass("HelloWorld"); // Execute our newly-generated code in-process. helloWorldClass.getMethod("hello").invoke(null); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
public static void main(String[] args) throws Exception { DexMaker dexMaker = new DexMaker(); // Generate a HelloWorld class. TypeId<?> helloWorld = TypeId.get("LHelloWorld;"); dexMaker.declare(helloWorld, "HelloWorld.generated", Modifier.PUBLIC, TypeId.OBJECT); generateHelloMethod(dexMaker, helloWorld); // Create the dex file and load it. File outputDir = Environment.getExternalStorageDirectory(); ClassLoader loader = dexMaker.generateAndLoad(HelloWorldMaker.class.getClassLoader(), outputDir); Class<?> helloWorldClass = loader.loadClass("HelloWorld"); // Execute our newly-generated code in-process. Log.d("helloWorldClass.getMethod(\"hello\").invoke(null);"); helloWorldClass.getMethod("hello").invoke(null); }