/** * 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)); }
// Create or return HeapRef corresponding to this string public HeapReference createString(ClassFile stringType, ConstantPoolInfo_String stringConst) { // the reason this method exists is because I suck and can't seem // to properly output unicode characters without breaking everything string stringVal = stringConst.getValue(); if (stringMap[stringVal] == null){ HeapReference stringRef = newInstance(stringType); StackFrame stringFrame = new StackFrame(stringType.getConstantPool()); // Attempt to initialize using the character array MethodInfo stringInit = stringType.getMethod("<init>","([C)V"); if (stringInit == null){ throw new Exception("Unable to find init method for string"); } stringFrame.setMethod(stringType,stringInit); stringFrame.getLocalVariables()[0] = stringRef; stringFrame.getLocalVariables()[1] = stringConst; string printableChars = ""; //stringRef.isUnicode = true; // I suck char[] chars = stringVal.ToCharArray(); for (int i = 0; i < chars.Length; i++){ if (chars[i] > 13 && chars[i] < 127){ printableChars += chars[i]; } } if (log.IsDebugEnabled) log.DebugFormat("stringval1:{0}",printableChars); //if (log.IsDebugEnabled) log.DebugFormat(stringVal); // if (log.IsDebugEnabled) log.DebugFormat("U:" + stringRef.isUnicode); stringType.execute("<init>","([C)V",stringFrame); stringMap.Add(stringVal,stringRef); reverseStringMap.Add(stringRef,stringVal); } return (HeapReference) stringMap[stringVal]; }
/** * 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); }
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)); }
public HeapReference createString(ClassFile stringType, string stringVal) { if (stringMap[stringVal] == null){ HeapReference stringRef = newInstance(stringType); StackFrame stringFrame = new StackFrame(stringType.getConstantPool()); // Attempt to initialize using the character array MethodInfo stringInit = stringType.getMethod("<init>","([C)V"); if (stringInit == null){ throw new Exception("Unable to find init method for string"); } stringFrame.setMethod(stringType,stringInit); stringFrame.getLocalVariables()[0] = stringRef; stringFrame.getLocalVariables()[1] = stringVal; // stringRef.isUnicode = containsUnicode(stringVal); char[] chars = stringVal.ToCharArray(); string printableChars = ""; //stringRef.isUnicode = true; // I suck for (int i = 0; i < chars.Length; i++){ if (chars[i] > 13 && chars[i] < 127){ printableChars += chars[i]; } } if (log.IsDebugEnabled) log.DebugFormat("stringval2:{0}",printableChars); stringType.execute("<init>","([C)V",stringFrame); stringMap.Add(stringVal,stringRef); reverseStringMap.Add(stringRef,stringVal); } return (HeapReference) stringMap[stringVal]; }
/** * array copy: * this: void arraycopy(Object source,int start,Object dest,int start,int length) */ public static void arraycopy(StackFrame frame) { if (log.IsDebugEnabled) log.DebugFormat("Performing array copy"); Object source = frame.getLocalVariables()[0]; if (log.IsDebugEnabled) log.DebugFormat("Source is {0}",source); int start = (int)frame.getLocalVariables()[1]; Object target = frame.getLocalVariables()[2]; if (log.IsDebugEnabled) log.DebugFormat("target is {0}",target); int end = (int)frame.getLocalVariables()[3]; int length = (int)frame.getLocalVariables()[4]; Heap.HeapReference arrayRef = (Heap.HeapReference) target; if (log.IsDebugEnabled) log.DebugFormat("arrayref obj is {0}",arrayRef.obj); if (arrayRef.obj is System.Char[]){ char[] targetChars = (System.Char[])(arrayRef.obj); char[] sourceChars; if (source is string){ sourceChars = ((string)source).ToCharArray(); } else if (source is ConstantPoolInfo_String){ sourceChars = ((ConstantPoolInfo_String)source).getValue().ToCharArray(); } else if (source is Heap.HeapReference){ Heap.HeapReference heapRef = (Heap.HeapReference)source; if (heapRef.isArray && heapRef.isPrimitive && heapRef.primitiveType.FullName.Equals("System.Char")){ sourceChars = (System.Char[])heapRef.obj; } else { throw new ToyVMException("Can only handle char arrays, have " + heapRef,frame); } } else { throw new ToyVMException("Can only copy strings, have " + source.GetType(),frame); } System.Array.Copy(sourceChars,start,targetChars,end,length); string printableChars = ""; //stringRef.isUnicode = true; // I suck for (int i = 0; i < targetChars.Length; i++){ if (targetChars[i] > 13 && targetChars[i] < 127){ printableChars += targetChars[i]; } } //if (log.IsDebugEnabled) log.DebugFormat("Target is now: {0}",printableChars); } else if (arrayRef.obj is System.Byte[]){ byte[] targetBytes = (System.Byte[]) arrayRef.obj; Heap.HeapReference sourceRef = (Heap.HeapReference) source; byte[] sourceBytes = (System.Byte[]) sourceRef.obj; System.Array.Copy(sourceBytes,start,targetBytes,end,length); } else { throw new ToyVMException("Target is neither a byte or a char: " + arrayRef,frame); } }
/** * 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); } }
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())); }
/** * Sets the core default system properties */ public static void preInit(StackFrame sf) { Heap.HeapReference propsObj = (Heap.HeapReference) sf.getLocalVariables()[0]; ClassFile stringType = ToyVMClassLoader.loadClass("java/lang/String"); ClassFile propsClass = (ClassFile)(propsObj.type); string setterType = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"; string setterName = "setProperty"; MethodInfo method = propsClass.getMethod(setterName,setterType); if (method == null){ foreach (MethodInfo m in propsClass.getMethods()){ if (log.IsDebugEnabled) log.DebugFormat(m.ToString()); } throw new ToyVMException("Unable to find " + setterName + setterType,sf); } StackFrame frame = new StackFrame(sf); frame.setMethod(propsClass,method); Heap.HeapReference prop = Heap.GetInstance().createString(stringType,"java.version"); Heap.HeapReference val = Heap.GetInstance().createString(stringType,"5"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.boot.class.path"); val = Heap.GetInstance().createString(stringType,"/home/jdewald/ToyVM/ToyVM/openjdk"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.vendor"); val = Heap.GetInstance().createString(stringType,"jdewald"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.vendor.url"); val = Heap.GetInstance().createString(stringType,"http://quay.wordpress.com"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.vm.vendor"); val = Heap.GetInstance().createString(stringType,"jdewald"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.vm.name"); val = Heap.GetInstance().createString(stringType,"ToyVM"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.vm.vendor.url"); val = Heap.GetInstance().createString(stringType,"http://quay.wordpress.com"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.vm.specification.version"); val = Heap.GetInstance().createString(stringType,"2"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.vm.specification.vendor"); val = Heap.GetInstance().createString(stringType,"Sun"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.vm.specification.url"); val = Heap.GetInstance().createString(stringType,"http://quay.wordpress.com"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.vm.specification.version"); val = Heap.GetInstance().createString(stringType,"http://quay.wordpress.com"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.class.version"); val = Heap.GetInstance().createString(stringType,"49"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.home"); val = Heap.GetInstance().createString(stringType,"/home/jdewald/ToyVM/ToyVM"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.class.path"); val = Heap.GetInstance().createString(stringType,"/home/jdewald/ToyVM/ToyVM/openjdk"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.library.path"); val = Heap.GetInstance().createString(stringType,"/home/jdewald/nativelibs"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"java.io.tmpdir"); val = Heap.GetInstance().createString(stringType,"/tmp"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"os.name"); val = Heap.GetInstance().createString(stringType,"Linux"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"os.arch"); val = Heap.GetInstance().createString(stringType,"i386"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"file.separator"); val = Heap.GetInstance().createString(stringType,"/"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"path.separator"); val = Heap.GetInstance().createString(stringType,":"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"line.separator"); val = Heap.GetInstance().createString(stringType,"\n"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"user.name"); val = Heap.GetInstance().createString(stringType,"jdewald"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"user.home"); val = Heap.GetInstance().createString(stringType,"/home/jdewald"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"user.dir"); val = Heap.GetInstance().createString(stringType,Environment.CurrentDirectory); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); prop = Heap.GetInstance().createString(stringType,"gnu.cpu.endian"); val = Heap.GetInstance().createString(stringType,"little"); frame.getLocalVariables()[0] = propsObj; frame.getLocalVariables()[1] = prop; frame.getLocalVariables()[2] = val; propsClass.execute(setterName,setterType,frame); }