X-Git-Url: http://git.megacz.com/?p=nestedvm.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FUnixRuntime.java;h=f5b8745196c5c3427dfddfb6d6f8493ed852c4c9;hp=0b50ee30b65315cd3500d455d6b3bf71d33bf1e3;hb=8a4f765fabfbee269818c56e517b8a37fc394d7e;hpb=489abe99cb575492b62f51e6ea61aa10f391d3b6 diff --git a/src/org/ibex/nestedvm/UnixRuntime.java b/src/org/ibex/nestedvm/UnixRuntime.java index 0b50ee3..f5b8745 100644 --- a/src/org/ibex/nestedvm/UnixRuntime.java +++ b/src/org/ibex/nestedvm/UnixRuntime.java @@ -6,6 +6,7 @@ import org.ibex.classgen.util.Sort; import java.io.*; import java.util.*; import java.net.*; +import java.lang.reflect.*; // For lazily linked RuntimeCompiler // FEATURE: vfork @@ -19,6 +20,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { private GlobalState gs; public void setGlobalState(GlobalState gs) { if(state != STOPPED) throw new IllegalStateException("can't change GlobalState when running"); + if(gs == null) throw new NullPointerException("gs is null"); this.gs = gs; } @@ -360,43 +362,148 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { private int sys_exec(int cpath, int cargv, int cenvp) throws ErrnoException, FaultException { return exec(normalizePath(cstring(cpath)),readStringArray(cargv),readStringArray(cenvp)); } + + private final static Method runtimeCompilerCompile; + static { + Method m; + try { + m = Class.forName("org.ibex.nestedvm.RuntimeCompiler").getMethod("compile",new Class[]{Seekable.class,String.class}); + } catch(NoSuchMethodException e) { + m = null; + } catch(ClassNotFoundException e) { + m = null; + } + runtimeCompilerCompile = m; + } + + public Class runtimeCompile(Seekable s) throws IOException { + if(runtimeCompilerCompile == null) { + if(STDERR_DIAG) System.err.println("WARNING: Exec attempted but RuntimeCompiler not found!"); + return null; + } - private int exec(String normalizedPath, String[] argv, String[] envp) throws ErrnoException { + try { + return (Class) runtimeCompilerCompile.invoke(null,new Object[]{s,"unixruntime"}); + } catch(IllegalAccessException e) { + e.printStackTrace(); + return null; + } catch(InvocationTargetException e) { + Throwable t = e.getTargetException(); + if(t instanceof IOException) throw (IOException) t; + if(t instanceof RuntimeException) throw (RuntimeException) t; + if(t instanceof Error) throw (Error) t; + if(STDERR_DIAG) t.printStackTrace(); + return null; + } + } + + private int exec(String path, String[] argv, String[] envp) throws ErrnoException { if(argv.length == 0) argv = new String[]{""}; - + // HACK: Hideous hack to make a standalone busybox possible + if(path.equals("bin/busybox") && getClass().getName().endsWith("BusyBox")) + return execClass(getClass(),argv,envp); + // NOTE: For this little hack to work nestedvm.root MUST be "." /*try { System.err.println("Execing normalized path: " + normalizedPath); if(true) return exec(new Interpreter(normalizedPath),argv,envp); } catch(IOException e) { throw new Error(e); }*/ - Object o = gs.exec(this,normalizedPath); - if(o == null) return -ENOENT; - - if(o instanceof Class) { - Class c = (Class) o; - try { - UnixRuntime r = (UnixRuntime) c.getDeclaredConstructor(new Class[]{Boolean.TYPE}).newInstance(new Object[]{Boolean.TRUE}); - return exec(r,argv,envp); - } catch(Exception e) { - e.printStackTrace(); - return -ENOEXEC; + FStat fstat = gs.stat(this,path); + if(fstat == null) return -ENOENT; + GlobalState.CacheEnt ent = (GlobalState.CacheEnt) gs.execCache.get(path); + long mtime = fstat.mtime(); + long size = fstat.size(); + if(ent != null) { + //System.err.println("Found cached entry for " + path); + if(ent.time ==mtime && ent.size == size) { + if(ent.o instanceof Class) + return execClass((Class) ent.o,argv,envp); + if(ent.o instanceof String[]) + return execScript(path,(String[]) ent.o,argv,envp); + throw new Error("should never happen"); } - } else { - String[] command = (String[]) o; - String[] newArgv = new String[argv.length + command[1] != null ? 2 : 1]; - int p = command[0].lastIndexOf('/'); - newArgv[0] = p == -1 ? command[0] : command[0].substring(p+1); - p = 1; - if(command[1] != null) newArgv[p++] = command[1]; - newArgv[p++] = "/" + normalizedPath; - for(int i=1;i