func createStackTraceElements(tObj *heap.Object, 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 }
// Object[] -> []interface{} func convertArgs(this, argArr *heap.Object, method *heap.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 _getGoField(fieldObj *heap.Object) *heap.Field { extra := fieldObj.Extra() if extra != nil { return extra.(*heap.Field) } root := fieldObj.GetFieldValue("root", "Ljava/lang/reflect/Field;").(*heap.Object) return root.Extra().(*heap.Field) }
func checkArrayCopy(src, dest *heap.Object) 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 *heap.Object, fields []interface{}, offset int64, expected, newVal *heap.Object) 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 *heap.Object) { self.stack.clear() sysClass := heap.BootLoader().LoadClass("java/lang/System") sysErr := sysClass.GetStaticValue("out", "Ljava/io/PrintStream;").(*heap.Object) 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 *heap.Object) *rtda.Thread { threadObj.RLockState() defer threadObj.RUnlockState() extra := threadObj.Extra() if extra == nil { return nil } else { return extra.(*rtda.Thread) } }
func _getGoMethod(methodObj *heap.Object, isConstructor bool) *heap.Method { extra := methodObj.Extra() if extra != nil { return extra.(*heap.Method) } if isConstructor { root := methodObj.GetFieldValue("root", "Ljava/lang/reflect/Constructor;").(*heap.Object) return root.Extra().(*heap.Method) } else { root := methodObj.GetFieldValue("root", "Ljava/lang/reflect/Method;").(*heap.Object) return root.Extra().(*heap.Method) } }
func Unbox(obj *heap.Object, primitiveDescriptor string) interface{} { return obj.GetFieldValue("value", primitiveDescriptor) }
func _getPath(fileObj *heap.Object) string { pathStr := fileObj.GetFieldValue("path", "Ljava/lang/String;").(*heap.Object) return rtda.GoString(pathStr) }
// todo func isAppClassLoader(loader *heap.Object) bool { return loader.Class().Name() == "sun/misc/Launcher$AppClassLoader" }
// java.lang.String -> go string func GoString(jStr *heap.Object) string { charArr := jStr.GetFieldValue("value", "[C").(*heap.Object) return _utf16ToString(charArr.Chars()) }