/** * Put a class representation of the primitive type */ public static void getPrimitiveClass(StackFrame frame) { char typeChar = (char)((int)(frame.getLocalVariables())[0]); if (log.IsDebugEnabled) log.DebugFormat("Returning class for {0}",typeChar); switch (typeChar){ case 'I':{ frame.getPrev().pushOperand(Type.GetType("System.Int32")); break; } case 'Z':{ frame.getPrev().pushOperand(Type.GetType("System.Boolean")); break; } case 'C':{ frame.getPrev().pushOperand(Type.GetType("System.Char")); break; } default: { throw new ToyVMException("Not handling " + typeChar,frame); } } }
/** * Returns full path to file based on short name of lib */ public static void mapLibraryName(StackFrame frame) { Heap.HeapReference nameRef = (Heap.HeapReference) frame.getLocalVariables()[0]; string shortName = Heap.GetInstance().GetStringVal(nameRef); string fullName = "lib"+shortName+".so"; frame.getPrev().pushOperand(Heap.GetInstance().createString(ToyVMClassLoader.loadClass("java/lang/String"),fullName)); }
/** * "native" implementation of Class[] VMStackWalker::getClassContext() */ public static void getClassContext(StackFrame frame) { // should be an array ref Heap.HeapReference heapRef = Heap.GetInstance().newArray(ToyVMClassLoader.loadClass("java/lang/Class"),4); ((ArrayList)heapRef.obj).Add(frame.getThis()); ((ArrayList)heapRef.obj).Add(frame.getThis()); ((ArrayList)heapRef.obj).Add(frame.getThis()); // since this is a method call we are just // storing the return value frame.getPrev().pushOperand(heapRef); }
public static void isFile(StackFrame frame) { Heap.HeapReference fileRef = (Heap.HeapReference) frame.getLocalVariables()[0]; ToyVMObject fileObj = (ToyVMObject)fileRef.obj; Heap.HeapReference filenameCharRef = (Heap.HeapReference)fileObj.getFieldValue("value",ConstantPoolInfo_FieldRef.TYPE_REF); System.Char[] filenameChars = (System.Char[]) filenameCharRef.obj; string filename = new string(filenameChars); if (log.IsDebugEnabled) log.DebugFormat("Determining if {0} is a file or not",filename); FileInfo file = new FileInfo(filename); frame.getPrev().pushOperand(((file.Exists && (file.Attributes & FileAttributes.Directory) == 0) ? 1 : 0)); }
// Thread currentThread() public static void currentThread(StackFrame frame) { Thread thread = Thread.CurrentThread; // will return or create new java.lang.Thread instance holding the current Thread frame.getPrev().pushOperand(Heap.GetInstance().createThread(thread)); }
/** * Calculate hash code... currently uses C# version * this: int identityHashCode(Object obj) */ public static void identityHashCode(StackFrame frame) { if (log.IsDebugEnabled) log.DebugFormat("Calculating hash for {0}",frame.getLocalVariables()[0]); Object obj = frame.getLocalVariables()[0]; // valid? if (obj is NullValue){ frame.getPrev().pushOperand(0); } else { frame.getPrev().pushOperand(((Heap.HeapReference)obj).address); } }
/* * Pretend to load a library, but not really * since we will use DllImport for now */ public static void nativeLoad(StackFrame frame) { //loadNio(); frame.getPrev().pushOperand(1); // "success" }
// TODO: reflection, bitches public bool handleNative(MethodInfo method,StackFrame frame) { if (this.GetName().StartsWith("gnu/classpath")){ if (this.GetName().Equals("gnu/classpath/VMStackWalker")){ if (method.getMethodName().Equals("getClassContext")){ VMStackWalker.getClassContext(frame); return true; } if (method.getMethodName().Equals("getClassLoader")){ VMStackWalker.getClassLoader(frame); return true; } } else if (this.GetName().Equals("gnu/classpath/VMSystemProperties")){ if (method.getMethodName().Equals("preInit")){ VMSystemProperties.preInit(frame); return true; } } } else if (this.GetName().StartsWith("gnu/java")){ if (this.GetName().Equals("gnu/java/nio/VMChannel")){ if (method.getMethodName().Equals("initIDs")){ if (log.IsDebugEnabled) log.DebugFormat("DOING NOTHING FOR initIDs"); /*unsafe { void * jniEnv = null; void * jclass = null; javanio.Java_gnu_java_nio_VMChannel_initIDs(jniEnv,jclass); } */ return true; } if (method.getMethodName().Equals("stdin_fd")){ if (log.IsDebugEnabled) log.DebugFormat("RETURNING 1 FOR stdin_fd"); /*unsafe { void * jniEnv = null; void * jclass = null; javanio.Java_gnu_java_nio_VMChannel_initIDs(jniEnv,jclass); } */ frame.getPrev().pushOperand(1); return true; } else if (method.getMethodName().Equals("stdout_fd")){ VMChannel.stdout_fd(frame); return true; } else if (method.getMethodName().Equals("stderr_fd")){ VMChannel.stderr_fd(frame); return true; } else if (method.getMethodName().Equals("write")){ VMChannel.write(frame); return true; } } } else if (this.GetName().StartsWith("java/lang")){ if (this.GetName().Equals("java/lang/VMSystem")){ if (method.getMethodName().Equals("identityHashCode")){ VMSystem.identityHashCode(frame); return true; } else if (method.getMethodName().Equals("arraycopy")){ VMSystem.arraycopy(frame); return true; } } else if (this.GetName().Equals("java/lang/VMObject")){ if (method.getMethodName().Equals("clone")){ VMObject.clone(frame); return true; } if (method.getMethodName().Equals("getClass")){ VMObject.getClass(frame); return true; } } else if (this.GetName().Equals("java/lang/VMClass")){ if (method.getMethodName().Equals("getName")){ VMClass.getName(frame); return true; } } else if (this.GetName().Equals("java/lang/VMClassLoader")){ if (method.getMethodName().Equals("getPrimitiveClass")){ VMClassLoader.getPrimitiveClass(frame); return true; } } else if (this.GetName().Equals("java/lang/VMRuntime")){ if (method.getMethodName().Equals("mapLibraryName")){ VMRuntime.mapLibraryName(frame); return true; } if (method.getMethodName().Equals("nativeLoad")){ VMRuntime.nativeLoad(frame); return true; } } else if (this.GetName().Equals("java/lang/VMThread")){ if (method.getMethodName().Equals("currentThread")){ VMThread.currentThread(frame); return true; } } } else if (this.GetName().StartsWith("java/io")){ if (this.GetName().Equals("java/io/VMFile")){ if (method.getMethodName().Equals("isDirectory")){ VMFile.isDirectory(frame); return true; } if (method.getMethodName().Equals("isFile")){ VMFile.isDirectory(frame); return true; } } } return false; }
public static void getName(StackFrame frame) { ClassFile clazz = (ClassFile) frame.getLocalVariables()[0]; frame.getPrev().pushOperand(Heap.GetInstance().createString(ToyVMClassLoader.loadClass("java/lang/String"),clazz.GetName())); }
/** * int write(int fd,ByteBuffer src) */ public static void write(StackFrame frame) { int fd = (int)frame.getLocalVariables()[1]; Heap.HeapReference byteBufRef = (Heap.HeapReference) frame.getLocalVariables()[2]; if (fd != 2){ throw new ToyVMException("Can only handle stdout(2), have " + fd, frame); } // need to get the actual byte array StackFrame frame2 = new StackFrame(frame); ClassFile byteBufferClass = byteBufRef.type; string getterType = "()[B"; string getterName = "array"; MethodInfo method = byteBufferClass.getMethod(getterName,getterType); if (method == null){ foreach (MethodInfo m in byteBufferClass.getMethods()){ if (log.IsDebugEnabled) log.DebugFormat(m.ToString()); } throw new ToyVMException("Unable to find " + getterName + getterType,frame); } frame2.setMethod(byteBufferClass,method); frame2.getLocalVariables()[0] = byteBufRef; byteBufferClass.execute(getterName,getterType,frame2); Heap.HeapReference byteArrRef = (Heap.HeapReference) frame.popOperand(); byte[] bytes = (byte[]) byteArrRef.obj; for (int i = 0; i < bytes.Length; i++){ Console.Write((char)bytes[i]); } frame.getPrev().pushOperand(bytes.Length); }
/** * Returns the file descriptor for stdout, note this is "supposed" to be using actual c code */ public static void stdout_fd(StackFrame frame) { frame.getPrev().pushOperand(2); }
public static void stderr_fd(StackFrame frame) { frame.getPrev().pushOperand(3); }
// TODO: Right now we always assume bootstrap loader public static void getClassLoader(StackFrame frame) { frame.getPrev().pushOperand(NullValue.INSTANCE); }