From 1fb0c2e49d65dfbd0b6d1ca31ea7828513ec2a7c Mon Sep 17 00:00:00 2001 From: visualfc Date: Wed, 19 Jun 2024 22:36:55 +0800 Subject: [PATCH] runtime: tracePanic --- c/bitcast/_cast/cast.c | 17 +++++++++++ c/bitcast/bitcast.go | 14 +++++++++ c/bitcast/llgo_autogen.lla | Bin 0 -> 405 bytes internal/runtime/z_rt.go | 61 ++++++++++++++++++++++++++++++++----- 4 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 c/bitcast/_cast/cast.c create mode 100644 c/bitcast/bitcast.go create mode 100644 c/bitcast/llgo_autogen.lla diff --git a/c/bitcast/_cast/cast.c b/c/bitcast/_cast/cast.c new file mode 100644 index 000000000..01e34b2c3 --- /dev/null +++ b/c/bitcast/_cast/cast.c @@ -0,0 +1,17 @@ +typedef union { + double d; + float f; + long v; +} castUnion; + +double bitcastToFloat64(long v) { + castUnion k; + k.v = v; + return k.d; +} + +float bitcastToFloat32(long v) { + castUnion k; + k.v = v; + return k.f; +} \ No newline at end of file diff --git a/c/bitcast/bitcast.go b/c/bitcast/bitcast.go new file mode 100644 index 000000000..a0a7b6f51 --- /dev/null +++ b/c/bitcast/bitcast.go @@ -0,0 +1,14 @@ +package bitcast + +import _ "unsafe" + +const ( + LLGoFiles = "_cast/cast.c" + LLGoPackage = "link" +) + +//go:linkname ToFloat64 C.bitcastToFloat64 +func ToFloat64(v uintptr) float64 + +//go:linkname ToFloat32 C.bitcastToFloat32 +func ToFloat32(v uintptr) float32 diff --git a/c/bitcast/llgo_autogen.lla b/c/bitcast/llgo_autogen.lla new file mode 100644 index 0000000000000000000000000000000000000000..e495204adde36d1c55db11d18e494bf5886676ae GIT binary patch literal 405 zcmWIWW@Zs#U|`^2*u3d-M9%rHT@Qi0JSGMPeg+waoSgLh_{7qZ{Pfg3y_}rT5Kac> z!k0y9#XwwI!Og(P@|BT+0c^n9iKnv;8wj|5|JBvK(vw@QY?F^h%0yrBzii5p$)N@t zd*tp;`B(kq$ijYKp0#08ZpG&lw;W%6x%1`Ij`TG>z4@MNt;<*SN?W$hy18T5>Z!eR zc?wmVy!S2Mw%w=MCQwf69j~a9%sacN+Xs)aPhN7}mCy9el$0C1RVN#@Jhr7BaO3dZ zE6efzT$WCcuH5_&inmr?HnV1&;_J3yvK6yd&qaOTS*-g@7@n%1-n8;Skl^AyMcekj z%CUUb~Vf%7I>hmdT%+4kA)Y86m{yX?@`8VI<-{NQYT**H)@6prUN0wVK2Y53w t$uZ*!D+yqzF)#oFgJDS{h=mbytdNjH3$*}mRyL4wMj#9Y(pn%B7y#$Cm>mEB literal 0 HcmV?d00001 diff --git a/internal/runtime/z_rt.go b/internal/runtime/z_rt.go index 9d9eea339..16a8f76ad 100644 --- a/internal/runtime/z_rt.go +++ b/internal/runtime/z_rt.go @@ -20,6 +20,7 @@ import ( "unsafe" "github.com/goplus/llgo/c" + "github.com/goplus/llgo/c/bitcast" "github.com/goplus/llgo/c/pthread" "github.com/goplus/llgo/internal/abi" ) @@ -58,7 +59,7 @@ func Panic(v any) { func Rethrow(link *Defer) { if ptr := excepKey.Get(); ptr != nil { if link == nil { - TracePanic(*(*Eface)(ptr)) + TracePanic(*(*any)(ptr)) c.Free(ptr) c.Exit(2) } else { @@ -77,14 +78,60 @@ func init() { // ----------------------------------------------------------------------------- +func unpackEface(i any) *eface { + return (*eface)(unsafe.Pointer(&i)) +} + +var ( + tyError = unpackEface((*interface{ Error() string })(nil))._type.Elem() +) + // TracePanic prints panic message. -func TracePanic(v Eface) { - kind := v._type.Kind() - switch { - case kind == abi.String: - stringTracef(c.Stderr, c.Str("panic: %s\n"), *(*String)(v.data)) +func TracePanic(v any) { + print("panic: ") + switch e := v.(type) { + case nil: + println("nil") + return + case (interface{ Error() string }): + println(e.Error()) + return + case (interface{ String() string }): + println(e.String()) + return + } + e := unpackEface(v) + switch e.Kind() { + case abi.Int, abi.Int8, abi.Int16, abi.Int32, abi.Int64: + if isDirectIface(e._type) { + println(int64(uintptr(e.data))) + } else { + println(*(*int64)(e.data)) + } + case abi.Uint, abi.Uint8, abi.Uint16, abi.Uint32, abi.Uint64, abi.Uintptr: + if isDirectIface(e._type) { + println(uint64(uintptr(e.data))) + } else { + println(*(*uint64)(e.data)) + } + case abi.Float32: + if isDirectIface(e._type) { + println(bitcast.ToFloat32((uintptr(e.data)))) + } else { + println(*(*float32)(e.data)) + } + case abi.Float64: + if isDirectIface(e._type) { + println(bitcast.ToFloat64(uintptr(e.data))) + } else { + println(*(*float64)(e.data)) + } + case abi.String: + println(*(*string)(e.data)) + default: + // TODO kind + println("(", e.Kind(), ")", e.data) } - // TODO(xsw): other message type } func stringTracef(fp c.FilePtr, format *c.Char, s String) {