runtime: tracePanic
This commit is contained in:
@@ -171,7 +171,6 @@ Common Go syntax is already supported. Except for the following, which needs to
|
||||
|
||||
* map (Very limited support)
|
||||
* chan (Not supported yet)
|
||||
* generics (Not supported yet)
|
||||
|
||||
Here are some examples related to Go syntax:
|
||||
|
||||
@@ -212,7 +211,7 @@ Here are the Go packages that can be imported correctly:
|
||||
* [strconv](https://pkg.go.dev/strconv)
|
||||
* [syscall](https://pkg.go.dev/syscall) (partially)
|
||||
* [sync](https://pkg.go.dev/sync) (partially)
|
||||
* [sync/atomic](https://pkg.go.dev/sync/atomic) (partially)
|
||||
* [sync/atomic](https://pkg.go.dev/sync/atomic)
|
||||
|
||||
|
||||
## Dependencies
|
||||
|
||||
17
c/bitcast/_cast/cast.c
Normal file
17
c/bitcast/_cast/cast.c
Normal file
@@ -0,0 +1,17 @@
|
||||
typedef union {
|
||||
double d;
|
||||
float f;
|
||||
long v;
|
||||
} castUnion;
|
||||
|
||||
double llgoToFloat64(long v) {
|
||||
castUnion k;
|
||||
k.v = v;
|
||||
return k.d;
|
||||
}
|
||||
|
||||
float llgoToFloat32(long v) {
|
||||
castUnion k;
|
||||
k.v = v;
|
||||
return k.f;
|
||||
}
|
||||
30
c/bitcast/bitcast.go
Normal file
30
c/bitcast/bitcast.go
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package bitcast
|
||||
|
||||
import _ "unsafe"
|
||||
|
||||
const (
|
||||
LLGoFiles = "_cast/cast.c"
|
||||
LLGoPackage = "link"
|
||||
)
|
||||
|
||||
//go:linkname ToFloat64 C.llgoToFloat64
|
||||
func ToFloat64(v uintptr) float64
|
||||
|
||||
//go:linkname ToFloat32 C.llgoToFloat32
|
||||
func ToFloat32(v uintptr) float32
|
||||
BIN
c/bitcast/llgo_autogen.lla
Normal file
BIN
c/bitcast/llgo_autogen.lla
Normal file
Binary file not shown.
@@ -16,7 +16,6 @@
|
||||
|
||||
package atomic
|
||||
|
||||
// llgo:skipall
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
@@ -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,57 @@ func init() {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
func unpackEface(i any) *eface {
|
||||
return (*eface)(unsafe.Pointer(&i))
|
||||
}
|
||||
|
||||
// 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 to e._type.Str_
|
||||
print("(", e.Kind(), ") ")
|
||||
println(e.data)
|
||||
}
|
||||
// TODO(xsw): other message type
|
||||
}
|
||||
|
||||
func stringTracef(fp c.FilePtr, format *c.Char, s String) {
|
||||
|
||||
Reference in New Issue
Block a user