fabc21b1e4009022e395ca52d8bafd38aa9a9b24
[nestedvm.git] / src / org / ibex / nestedvm / RuntimeCompiler.java
1 // Copyright 2000-2005 the Contributors, as shown in the revision logs.
2 // Licensed under the Apache License 2.0 ("the License").
3 // You may not use this file except in compliance with the License.
4
5 package org.ibex.nestedvm;
6
7 import java.io.*;
8
9 import org.ibex.nestedvm.util.*;
10
11 // This need a lot of work to support binaries spanned across many classes
12 public class RuntimeCompiler {  
13     public static Class compile(Seekable data) throws IOException, Compiler.Exn { return compile(data,null); }
14     public static Class compile(Seekable data, String extraoptions) throws IOException, Compiler.Exn { return compile(data,extraoptions,null); }
15     
16     public static Class compile(Seekable data, String extraoptions, String sourceName) throws IOException, Compiler.Exn {
17         String className = "nestedvm.runtimecompiled";
18         byte[] bytecode;
19         try {
20             bytecode = runCompiler(data,className,extraoptions,sourceName,null);
21         } catch(Compiler.Exn e) {
22             if(e.getMessage() != null || e.getMessage().indexOf("constant pool full")  != -1)
23                 bytecode = runCompiler(data,className,extraoptions,sourceName,"lessconstants");
24             else
25                 throw e;
26         }
27         return new SingleClassLoader().fromBytes(className,bytecode);
28     }
29     
30     private static byte[] runCompiler(Seekable data, String name, String options, String sourceName, String moreOptions) throws IOException, Compiler.Exn {
31         ByteArrayOutputStream baos = new ByteArrayOutputStream();
32         
33         try {
34             ClassFileCompiler c = new ClassFileCompiler(data,name,baos);
35             c.parseOptions("nosupportcall,maxinsnpermethod=256");
36             c.setSource(sourceName);
37             if(options != null) c.parseOptions(options);
38             if(moreOptions != null) c.parseOptions(moreOptions);
39             c.go();
40         } finally {
41             data.seek(0);
42         }
43         
44         baos.close();
45         return baos.toByteArray();        
46     }
47     
48     private static class SingleClassLoader extends ClassLoader {
49         public Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
50             //System.err.println(this + ": loadClass(\"" + name + "," + resolve + ");");
51             return super.loadClass(name,resolve);
52         }
53         public Class fromBytes(String name, byte[] b) { return fromBytes(name,b,0,b.length); }
54         public Class fromBytes(String name, byte[] b, int off, int len) {
55             Class c = super.defineClass(name,b,off,len);
56             resolveClass(c);
57             return c;
58         }
59     }
60     
61     public static void main(String[] args) throws Exception {
62         if(args.length == 0) {
63             System.err.println("Usage: RuntimeCompiler mipsbinary");
64             System.exit(1);
65         }
66         UnixRuntime r = (UnixRuntime) compile(new Seekable.File(args[0]),"unixruntime").newInstance();
67         System.err.println("Instansiated: "+ r);
68         System.exit(UnixRuntime.runAndExec(r,args));
69     }
70     
71     private RuntimeCompiler() { }
72 }