// Object[] -> []interface{} func convertArgs(this, argArr *rtc.Obj, method *rtc.Method) []interface{} { if method.ArgSlotCount() == 0 { return nil } if method.ArgSlotCount() == 1 && !method.IsStatic() { return []interface{}{this} } argObjs := argArr.Refs() argTypes := method.ParsedDescriptor().ParameterTypes() args := make([]interface{}, method.ArgSlotCount()) j := 0 if !method.IsStatic() { args[0] = this j = 1 } for i, argType := range argTypes { argObj := argObjs[i] if argType.IsBaseType() { // todo unboxed := box.Unbox(argObj, argType.Descriptor()) args[i+j] = unboxed if argType.IsLongOrDouble() { j++ } } else { args[i+j] = argObj } } return args }
func createStackTraceElements(tObj *rtc.Obj, frame *rtda.Frame) []*StackTraceElement { thread := frame.Thread() depth := thread.StackDepth() // skip unrelated frames i := uint(1) for k := tObj.Class(); k != nil; k = k.SuperClass() { i++ } if thread.TopFrameN(i).Method().Name() == "<athrow>" { i++ } stes := make([]*StackTraceElement, 0, depth) for ; i < depth; i++ { frameN := thread.TopFrameN(i) methodN := frameN.Method() classN := methodN.Class() if classN.Name() != "~shim" { // skip shim frame lineNumber := methodN.GetLineNumber(frameN.NextPC() - 1) ste := &StackTraceElement{ declaringClass: classN.NameJlsFormat(), methodName: methodN.Name(), fileName: classN.SourceFile(), lineNumber: lineNumber, } stes = append(stes, ste) } } return stes }
func _getGoField(fieldObj *rtc.Obj) *rtc.Field { extra := fieldObj.Extra() if extra != nil { return extra.(*rtc.Field) } root := fieldObj.GetFieldValue("root", "Ljava/lang/reflect/Field;").(*rtc.Obj) return root.Extra().(*rtc.Field) }
func checkArrayCopy(src, dest *rtc.Obj) bool { srcClass := src.Class() destClass := dest.Class() if !srcClass.IsArray() || !destClass.IsArray() { return false } if srcClass.IsPrimitiveArray() || destClass.IsPrimitiveArray() { return srcClass == destClass } return true }
func _casObj(obj *rtc.Obj, fields []interface{}, offset int64, expected, newVal *rtc.Obj) bool { // todo obj.LockState() defer obj.UnlockState() current := _getObj(fields, offset) if current == expected { fields[offset] = newVal return true } else { return false } }
func (self *Thread) HandleUncaughtException(ex *rtc.Obj) { self.stack.clear() sysClass := rtc.BootLoader().LoadClass("java/lang/System") sysErr := sysClass.GetStaticValue("out", "Ljava/io/PrintStream;").(*rtc.Obj) printStackTrace := ex.Class().GetInstanceMethod("printStackTrace", "(Ljava/io/PrintStream;)V") // call ex.printStackTrace(System.err) newFrame := self.NewFrame(printStackTrace) vars := newFrame.localVars vars.SetRef(0, ex) vars.SetRef(1, sysErr) self.PushFrame(newFrame) // // printString := sysErr.Class().GetInstanceMethod("print", "(Ljava/lang/String;)V") // newFrame = self.NewFrame(printString) // vars = newFrame.localVars // vars.SetRef(0, sysErr) // vars.SetRef(1, JString("Exception in thread \"main\" ", newFrame)) // self.PushFrame(newFrame) }
func _extraThread(threadObj *rtc.Obj) *rtda.Thread { threadObj.RLockState() defer threadObj.RUnlockState() extra := threadObj.Extra() if extra == nil { return nil } else { return extra.(*rtda.Thread) } }
func _getGoMethod(methodObj *rtc.Obj, isConstructor bool) *rtc.Method { extra := methodObj.Extra() if extra != nil { return extra.(*rtc.Method) } if isConstructor { root := methodObj.GetFieldValue("root", "Ljava/lang/reflect/Constructor;").(*rtc.Obj) return root.Extra().(*rtc.Method) } else { root := methodObj.GetFieldValue("root", "Ljava/lang/reflect/Method;").(*rtc.Obj) return root.Extra().(*rtc.Method) } }
// todo func isAppClassLoader(loader *rtc.Obj) bool { return loader.Class().Name() == "sun/misc/Launcher$AppClassLoader" }
func Unbox(obj *rtc.Obj, primitiveDescriptor string) interface{} { return obj.GetFieldValue("value", primitiveDescriptor) }
// java.lang.String -> go string func GoString(jStr *rtc.Obj) string { charArr := jStr.GetFieldValue("value", "[C").(*rtc.Obj) return _utf16ToString(charArr.Chars()) }
func _getPath(fileObj *rtc.Obj) string { pathStr := fileObj.GetFieldValue("path", "Ljava/lang/String;").(*rtc.Obj) return rtda.GoString(pathStr) }