func free(address int64) { if _, ok := _allocated[address]; ok { delete(_allocated, address) } else { jutil.Panicf("memory was not allocated: %v", address) } }
// todo ugly code func newConstantInfo(tag uint8, cp *ConstantPool) ConstantInfo { switch tag { case CONSTANT_Integer: return &ConstantIntegerInfo{} case CONSTANT_Float: return &ConstantFloatInfo{} case CONSTANT_Long: return &ConstantLongInfo{} case CONSTANT_Double: return &ConstantDoubleInfo{} case CONSTANT_Utf8: return &ConstantUtf8Info{} case CONSTANT_String: return &ConstantStringInfo{cp: cp} case CONSTANT_Class: return &ConstantClassInfo{cp: cp} case CONSTANT_Fieldref: return &ConstantFieldrefInfo{ConstantMemberrefInfo{cp: cp}} case CONSTANT_Methodref: return &ConstantMethodrefInfo{ConstantMemberrefInfo{cp: cp}} case CONSTANT_InterfaceMethodref: return &ConstantInterfaceMethodrefInfo{ConstantMemberrefInfo{cp: cp}} case CONSTANT_NameAndType: return &ConstantNameAndTypeInfo{} case CONSTANT_MethodType: return &ConstantMethodTypeInfo{} case CONSTANT_MethodHandle: return &ConstantMethodHandleInfo{} case CONSTANT_InvokeDynamic: return &ConstantInvokeDynamicInfo{cp: cp} default: // todo jutil.Panicf("BAD constant pool tag: %v", tag) return nil } }
func memoryAt(address int64) []byte { for startAddress, mem := range _allocated { endAddress := startAddress + int64(len(mem)) if address >= startAddress && address < endAddress { offset := address - startAddress return mem[offset:] } } jutil.Panicf("invalid address: %v", address) return nil }
func _getEntryBytes(jzentry int64, _type int32) []byte { entry := getEntryFile(jzentry) switch _type { case JZENTRY_NAME: return []byte(entry.Name) case JZENTRY_EXTRA: return entry.Extra case JZENTRY_COMMENT: return []byte(entry.Comment) } jutil.Panicf("BAD type: %v", _type) return nil }
func (self *LDC2_W) Execute(frame *rtda.Frame) { stack := frame.OperandStack() cp := frame.ConstantPool() c := cp.GetConstant(self.Index) switch c.(type) { case int64: stack.PushLong(c.(int64)) case float64: stack.PushDouble(c.(float64)) default: jutil.Panicf("ldc2_w! %v", c) } }
func (self *ConstantFieldref) resolveInstanceField() { fromClass := bootLoader.LoadClass(self.className) for class := fromClass; class != nil; class = class.superClass { field := class.getField(self.name, self.descriptor, false) if field != nil { self.field = field return } } // todo jutil.Panicf("instance field not found! %v", self) }
func (self *ConstantFieldref) resolveStaticField() { fromClass := bootLoader.LoadClass(self.className) for class := fromClass; class != nil; class = class.superClass { field := class.getField(self.name, self.descriptor, true) if field != nil { self.field = field return } if self._findInterfaceField(class) { return } } // todo jutil.Panicf("static field not found! %v", self) }
// boxing primitive types // primitive value must be on the top of operand stack func Box(frame *rtda.Frame, primitiveDescriptor byte) { switch primitiveDescriptor { case 'Z': _callValueOf(frame, "Z", "java/lang/Boolean") case 'B': _callValueOf(frame, "B", "java/lang/Byte") case 'C': _callValueOf(frame, "C", "java/lang/Character") case 'S': _callValueOf(frame, "S", "java/lang/Short") case 'I': _callValueOf(frame, "I", "java/lang/Integer") case 'J': _callValueOf(frame, "J", "java/lang/Long") case 'F': _callValueOf(frame, "F", "java/lang/Float") case 'D': _callValueOf(frame, "D", "java/lang/Double") default: jutil.Panicf("Not primitive type: %v", primitiveDescriptor) } }
func ArrayCopy(src, dst *Obj, srcPos, dstPos, length int32) { switch src.fields.(type) { case []int8: _src := src.fields.([]int8)[srcPos : srcPos+length] _dst := dst.fields.([]int8)[dstPos : dstPos+length] copy(_dst, _src) case []int16: _src := src.fields.([]int16)[srcPos : srcPos+length] _dst := dst.fields.([]int16)[dstPos : dstPos+length] copy(_dst, _src) case []int32: _src := src.fields.([]int32)[srcPos : srcPos+length] _dst := dst.fields.([]int32)[dstPos : dstPos+length] copy(_dst, _src) case []int64: _src := src.fields.([]int64)[srcPos : srcPos+length] _dst := dst.fields.([]int64)[dstPos : dstPos+length] copy(_dst, _src) case []uint16: _src := src.fields.([]uint16)[srcPos : srcPos+length] _dst := dst.fields.([]uint16)[dstPos : dstPos+length] copy(_dst, _src) case []float32: _src := src.fields.([]float32)[srcPos : srcPos+length] _dst := dst.fields.([]float32)[dstPos : dstPos+length] copy(_dst, _src) case []float64: _src := src.fields.([]float64)[srcPos : srcPos+length] _dst := dst.fields.([]float64)[dstPos : dstPos+length] copy(_dst, _src) case []*Obj: _src := src.fields.([]*Obj)[srcPos : srcPos+length] _dst := dst.fields.([]*Obj)[dstPos : dstPos+length] copy(_dst, _src) default: jutil.Panicf("Not array: %v!", src) } }
func ArrayLength(arr *Obj) int32 { switch arr.fields.(type) { case []int8: return int32(len(arr.fields.([]int8))) case []int16: return int32(len(arr.fields.([]int16))) case []int32: return int32(len(arr.fields.([]int32))) case []int64: return int32(len(arr.fields.([]int64))) case []uint16: return int32(len(arr.fields.([]uint16))) case []float32: return int32(len(arr.fields.([]float32))) case []float64: return int32(len(arr.fields.([]float64))) case []*Obj: return int32(len(arr.fields.([]*Obj))) default: jutil.Panicf("Not array: %v!", arr) return -1 } }
func NewPrimitiveArray(atype uint8, count uint) *Obj { switch atype { case AT_BOOLEAN: return newObj(bootLoader.getClass("[Z"), make([]int8, count), nil) case AT_BYTE: return newObj(bootLoader.getClass("[B"), make([]int8, count), nil) case AT_CHAR: return newObj(bootLoader.getClass("[C"), make([]uint16, count), nil) case AT_SHORT: return newObj(bootLoader.getClass("[S"), make([]int16, count), nil) case AT_INT: return newObj(bootLoader.getClass("[I"), make([]int32, count), nil) case AT_LONG: return newObj(bootLoader.getClass("[J"), make([]int64, count), nil) case AT_FLOAT: return newObj(bootLoader.getClass("[F"), make([]float32, count), nil) case AT_DOUBLE: return newObj(bootLoader.getClass("[D"), make([]float64, count), nil) default: jutil.Panicf("BAD atype: %v!", atype) return nil } }
func _newPrimitiveArray(arrClass *Class, count uint) *Obj { switch arrClass.Name() { case "[Z": return newObj(arrClass, make([]int8, count), nil) case "[B": return newObj(arrClass, make([]int8, count), nil) case "[C": return newObj(arrClass, make([]uint16, count), nil) case "[S": return newObj(arrClass, make([]int16, count), nil) case "[I": return newObj(arrClass, make([]int32, count), nil) case "[L": return newObj(arrClass, make([]int64, count), nil) case "[F": return newObj(arrClass, make([]float32, count), nil) case "[D": return newObj(arrClass, make([]float64, count), nil) default: jutil.Panicf("Not primitive array: %v!", arrClass) return nil } }
func _ldc(frame *rtda.Frame, index uint) { stack := frame.OperandStack() cp := frame.ConstantPool() c := cp.GetConstant(index) switch c.(type) { case int32: stack.PushInt(c.(int32)) case float32: stack.PushFloat(c.(float32)) case string: internedStr := rtda.JString(c.(string)) stack.PushRef(internedStr) case *heap.ConstantClass: kClass := c.(*heap.ConstantClass) classObj := kClass.Class().JClass() stack.PushRef(classObj) default: // todo // ref to MethodType or MethodHandle jutil.Panicf("todo: ldc! %v", c) } }
func newInstruction(opcode byte) Instruction { switch opcode { case 0x00: return _nop case 0x01: return _aconst_null case 0x02: return _iconst_m1 case 0x03: return _iconst_0 case 0x04: return _iconst_1 case 0x05: return _iconst_2 case 0x06: return _iconst_3 case 0x07: return _iconst_4 case 0x08: return _iconst_5 case 0x09: return _lconst_0 case 0x0a: return _lconst_1 case 0x0b: return _fconst_0 case 0x0c: return _fconst_1 case 0x0d: return _fconst_2 case 0x0e: return _dconst_0 case 0x0f: return _dconst_1 case 0x10: return &bipush{} case 0x11: return &sipush{} case 0x12: return &ldc{} case 0x13: return &ldc_w{} case 0x14: return &ldc2_w{} case 0x15: return &iload{} case 0x16: return &lload{} case 0x17: return &fload{} case 0x18: return &dload{} case 0x19: return &aload{} case 0x1a: return _iload_0 case 0x1b: return _iload_1 case 0x1c: return _iload_2 case 0x1d: return _iload_3 case 0x1e: return _lload_0 case 0x1f: return _lload_1 case 0x20: return _lload_2 case 0x21: return _lload_3 case 0x22: return _fload_0 case 0x23: return _fload_1 case 0x24: return _fload_2 case 0x25: return _fload_3 case 0x26: return _dload_0 case 0x27: return _dload_1 case 0x28: return _dload_2 case 0x29: return _dload_3 case 0x2a: return _aload_0 case 0x2b: return _aload_1 case 0x2c: return _aload_2 case 0x2d: return _aload_3 case 0x2e: return _iaload case 0x2f: return _laload case 0x30: return _faload case 0x31: return _daload case 0x32: return _aaload case 0x33: return _baload case 0x34: return _caload case 0x35: return _saload case 0x36: return &istore{} case 0x37: return &lstore{} case 0x38: return &fstore{} case 0x39: return &dstore{} case 0x3a: return &astore{} case 0x3b: return _istore_0 case 0x3c: return _istore_1 case 0x3d: return _istore_2 case 0x3e: return _istore_3 case 0x3f: return _lstore_0 case 0x40: return _lstore_1 case 0x41: return _lstore_2 case 0x42: return _lstore_3 case 0x43: return _fstore_0 case 0x44: return _fstore_1 case 0x45: return _fstore_2 case 0x46: return _fstore_3 case 0x47: return _dstore_0 case 0x48: return _dstore_1 case 0x49: return _dstore_2 case 0x4a: return _dstore_3 case 0x4b: return _astore_0 case 0x4c: return _astore_1 case 0x4d: return _astore_2 case 0x4e: return _astore_3 case 0x4f: return _iastore case 0x50: return _lastore case 0x51: return _fastore case 0x52: return _dastore case 0x53: return _aastore case 0x54: return _bastore case 0x55: return _castore case 0x56: return _sastore case 0x57: return _pop case 0x58: return _pop2 case 0x59: return _dup case 0x5a: return _dup_x1 case 0x5b: return _dup_x2 case 0x5c: return _dup2 case 0x5d: return _dup2_x1 case 0x5e: return _dup2_x2 case 0x5f: return _swap case 0x60: return _iadd case 0x61: return _ladd case 0x62: return _fadd case 0x63: return _dadd case 0x64: return _isub case 0x65: return _lsub case 0x66: return _fsub case 0x67: return _dsub case 0x68: return _imul case 0x69: return _lmul case 0x6a: return _fmul case 0x6b: return _dmul case 0x6c: return _idiv case 0x6d: return _ldiv case 0x6e: return _fdiv case 0x6f: return _ddiv case 0x70: return _irem case 0x71: return _lrem case 0x72: return _frem case 0x73: return _drem case 0x74: return _ineg case 0x75: return _lneg case 0x76: return _fneg case 0x77: return _dneg case 0x78: return _ishl case 0x79: return _lshl case 0x7a: return _ishr case 0x7b: return _lshr case 0x7c: return _iushr case 0x7d: return _lushr case 0x7e: return _iand case 0x7f: return _land case 0x80: return _ior case 0x81: return _lor case 0x82: return _ixor case 0x83: return _lxor case 0x84: return &iinc{} case 0x85: return _i2l case 0x86: return _i2f case 0x87: return _i2d case 0x88: return _l2i case 0x89: return _l2f case 0x8a: return _l2d case 0x8b: return _f2i case 0x8c: return _f2l case 0x8d: return _f2d case 0x8e: return _d2i case 0x8f: return _d2l case 0x90: return _d2f case 0x91: return _i2b case 0x92: return _i2c case 0x93: return _i2s case 0x94: return _lcmp case 0x95: return _fcmpl case 0x96: return _fcmpg case 0x97: return _dcmpl case 0x98: return _dcmpg case 0x99: return &ifeq{} case 0x9a: return &ifne{} case 0x9b: return &iflt{} case 0x9c: return &ifge{} case 0x9d: return &ifgt{} case 0x9e: return &ifle{} case 0x9f: return &if_icmpeq{} case 0xa0: return &if_icmpne{} case 0xa1: return &if_icmplt{} case 0xa2: return &if_icmpge{} case 0xa3: return &if_icmpgt{} case 0xa4: return &if_icmple{} case 0xa5: return &if_acmpeq{} case 0xa6: return &if_acmpne{} case 0xa7: return &goto_{} case 0xa8: return &jsr{} case 0xa9: return &ret{} case 0xaa: return &tableswitch{} case 0xab: return &lookupswitch{} case 0xac: return _ireturn case 0xad: return _lreturn case 0xae: return _freturn case 0xaf: return _dreturn case 0xb0: return _areturn case 0xb1: return _return_ case 0xb2: return &getstatic{} case 0xb3: return &putstatic{} case 0xb4: return &getfield{} case 0xb5: return &putfield{} case 0xb6: return &invokevirtual{} case 0xb7: return &invokespecial{} case 0xb8: return &invokestatic{} case 0xb9: return &invokeinterface{} case 0xba: return &invokedynamic{} case 0xbb: return &new_{} case 0xbc: return &newarray{} case 0xbd: return &anewarray{} case 0xbe: return _arraylength case 0xbf: return _athrow case 0xc0: return &checkcast{} case 0xc1: return &instanceof{} case 0xc2: return _monitorenter case 0xc3: return _monitorexit case 0xc4: return &wide{} case 0xc5: return &multianewarray{} case 0xc6: return &ifnull{} case 0xc7: return &ifnonnull{} case 0xc8: return &goto_w{} case 0xc9: return &jsr_w{} //case 0xca: todo breakpoint case 0xfe: return _invoke_native // impdep1 case 0xff: return &bootstrap{} // impdep2 default: jutil.Panicf("BAD opcode: %v!", opcode) return nil } }
func newInstruction(opcode byte) base.Instruction { switch opcode { case 0x00: return nop case 0x01: return aconst_null case 0x02: return iconst_m1 case 0x03: return iconst_0 case 0x04: return iconst_1 case 0x05: return iconst_2 case 0x06: return iconst_3 case 0x07: return iconst_4 case 0x08: return iconst_5 case 0x09: return lconst_0 case 0x0a: return lconst_1 case 0x0b: return fconst_0 case 0x0c: return fconst_1 case 0x0d: return fconst_2 case 0x0e: return dconst_0 case 0x0f: return dconst_1 case 0x10: return &BIPUSH{} case 0x11: return &SIPUSH{} case 0x12: return &LDC{} case 0x13: return &LDC_W{} case 0x14: return &LDC2_W{} case 0x15: return &ILOAD{} case 0x16: return &LLOAD{} case 0x17: return &FLOAD{} case 0x18: return &DLOAD{} case 0x19: return &ALOAD{} case 0x1a: return iload_0 case 0x1b: return iload_1 case 0x1c: return iload_2 case 0x1d: return iload_3 case 0x1e: return lload_0 case 0x1f: return lload_1 case 0x20: return lload_2 case 0x21: return lload_3 case 0x22: return fload_0 case 0x23: return fload_1 case 0x24: return fload_2 case 0x25: return fload_3 case 0x26: return dload_0 case 0x27: return dload_1 case 0x28: return dload_2 case 0x29: return dload_3 case 0x2a: return aload_0 case 0x2b: return aload_1 case 0x2c: return aload_2 case 0x2d: return aload_3 case 0x2e: return iaload case 0x2f: return laload case 0x30: return faload case 0x31: return daload case 0x32: return aaload case 0x33: return baload case 0x34: return caload case 0x35: return saload case 0x36: return &ISTORE{} case 0x37: return &LSTORE{} case 0x38: return &FSTORE{} case 0x39: return &DSTORE{} case 0x3a: return &ASTORE{} case 0x3b: return istore_0 case 0x3c: return istore_1 case 0x3d: return istore_2 case 0x3e: return istore_3 case 0x3f: return lstore_0 case 0x40: return lstore_1 case 0x41: return lstore_2 case 0x42: return lstore_3 case 0x43: return fstore_0 case 0x44: return fstore_1 case 0x45: return fstore_2 case 0x46: return fstore_3 case 0x47: return dstore_0 case 0x48: return dstore_1 case 0x49: return dstore_2 case 0x4a: return dstore_3 case 0x4b: return astore_0 case 0x4c: return astore_1 case 0x4d: return astore_2 case 0x4e: return astore_3 case 0x4f: return iastore case 0x50: return lastore case 0x51: return fastore case 0x52: return dastore case 0x53: return aastore case 0x54: return bastore case 0x55: return castore case 0x56: return sastore case 0x57: return pop case 0x58: return pop2 case 0x59: return dup case 0x5a: return dup_x1 case 0x5b: return dup_x2 case 0x5c: return dup2 case 0x5d: return dup2_x1 case 0x5e: return dup2_x2 case 0x5f: return swap case 0x60: return iadd case 0x61: return ladd case 0x62: return fadd case 0x63: return dadd case 0x64: return isub case 0x65: return lsub case 0x66: return fsub case 0x67: return dsub case 0x68: return imul case 0x69: return lmul case 0x6a: return fmul case 0x6b: return dmul case 0x6c: return idiv case 0x6d: return ldiv case 0x6e: return fdiv case 0x6f: return ddiv case 0x70: return irem case 0x71: return lrem case 0x72: return frem case 0x73: return drem case 0x74: return ineg case 0x75: return lneg case 0x76: return fneg case 0x77: return dneg case 0x78: return ishl case 0x79: return lshl case 0x7a: return ishr case 0x7b: return lshr case 0x7c: return iushr case 0x7d: return lushr case 0x7e: return iand case 0x7f: return land case 0x80: return ior case 0x81: return lor case 0x82: return ixor case 0x83: return lxor case 0x84: return &IINC{} case 0x85: return i2l case 0x86: return i2f case 0x87: return i2d case 0x88: return l2i case 0x89: return l2f case 0x8a: return l2d case 0x8b: return f2i case 0x8c: return f2l case 0x8d: return f2d case 0x8e: return d2i case 0x8f: return d2l case 0x90: return d2f case 0x91: return i2b case 0x92: return i2c case 0x93: return i2s case 0x94: return lcmp case 0x95: return fcmpl case 0x96: return fcmpg case 0x97: return dcmpl case 0x98: return dcmpg case 0x99: return &IFEQ{} case 0x9a: return &IFNE{} case 0x9b: return &IFLT{} case 0x9c: return &IFGE{} case 0x9d: return &IFGT{} case 0x9e: return &IFLE{} case 0x9f: return &IF_ICMPEQ{} case 0xa0: return &IF_ICMPNE{} case 0xa1: return &IF_ICMPLT{} case 0xa2: return &IF_ICMPGE{} case 0xa3: return &IF_ICMPGT{} case 0xa4: return &IF_ICMPLE{} case 0xa5: return &IF_ACMPEQ{} case 0xa6: return &IF_ACMPNE{} case 0xa7: return &GOTO{} case 0xa8: return &JSR{} case 0xa9: return &RET{} case 0xaa: return &TABLE_SWITCH{} case 0xab: return &LOOKUP_SWITCH{} case 0xac: return ireturn case 0xad: return lreturn case 0xae: return freturn case 0xaf: return dreturn case 0xb0: return areturn case 0xb1: return _return case 0xb2: return &GET_STATIC{} case 0xb3: return &PUT_STATIC{} case 0xb4: return &GET_FIELD{} case 0xb5: return &PUT_FIELD{} case 0xb6: return &INVOKE_VIRTUAL{} case 0xb7: return &INVOKE_SPECIAL{} case 0xb8: return &INVOKE_STATIC{} case 0xb9: return &INVOKE_INTERFACE{} case 0xba: return &INVOKE_DYNAMIC{} case 0xbb: return &NEW{} case 0xbc: return &NEW_ARRAY{} case 0xbd: return &ANEW_ARRAY{} case 0xbe: return arraylength case 0xbf: return athrow case 0xc0: return &CHECK_CAST{} case 0xc1: return &INSTANCE_OF{} case 0xc2: return monitorenter case 0xc3: return monitorexit case 0xc4: return &WIDE{} case 0xc5: return &MULTI_ANEW_ARRAY{} case 0xc6: return &IFNULL{} case 0xc7: return &IFNONNULL{} case 0xc8: return &GOTO_W{} case 0xc9: return &JSR_W{} //case 0xca: todo breakpoint case 0xfe: return invoke_native // impdep1 case 0xff: return &BOOTSTRAP{} // impdep2 default: jutil.Panicf("BAD opcode: %v!", opcode) return nil } }