From e1b8aefe898e73654052cdd2e86813eb4e4dd019 Mon Sep 17 00:00:00 2001 From: visualfc Date: Fri, 3 Jul 2026 19:36:47 +0800 Subject: [PATCH] runtime/internal/lib/reflect: fix toFFIArg interface itab --- .github/workflows/test_demo.sh | 2 ++ _demo/go/reflectifacecall/main.go | 20 ++++++++++++++++++++ runtime/internal/lib/reflect/value.go | 20 ++++++++++++++------ 3 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 _demo/go/reflectifacecall/main.go diff --git a/.github/workflows/test_demo.sh b/.github/workflows/test_demo.sh index a4f1be84f5..98bd726383 100755 --- a/.github/workflows/test_demo.sh +++ b/.github/workflows/test_demo.sh @@ -107,6 +107,7 @@ ignore_esp32=( "./_demo/go/reflectempty" # panic: internal/bytealg selected .s files require plan9asm translation "./_demo/go/reflectfunc" # panic: internal/bytealg selected .s files require plan9asm translation "./_demo/go/reflectfnconv" # panic: internal/bytealg selected .s files require plan9asm translation + "./_demo/go/reflectifacecall" # panic: internal/bytealg selected .s files require plan9asm translation "./_demo/go/reflectindirect" # panic: internal/bytealg selected .s files require plan9asm translation "./_demo/go/reflectmake" # panic: internal/bytealg selected .s files require plan9asm translation "./_demo/go/reflectmethod" # panic: internal/bytealg selected .s files require plan9asm translation @@ -185,6 +186,7 @@ ignore_esp32c3_basic=( "./_demo/go/reflectconv" # panic: internal/bytealg selected .s files require plan9asm translation "./_demo/go/reflectfunc" # panic: internal/bytealg selected .s files require plan9asm translation "./_demo/go/reflectfnconv" # panic: internal/bytealg selected .s files require plan9asm translation + "./_demo/go/reflectifacecall" # panic: internal/bytealg selected .s files require plan9asm translation "./_demo/go/reflectindirect" # panic: internal/bytealg selected .s files require plan9asm translation "./_demo/go/reflectcopy" # panic: internal/bytealg selected .s files require plan9asm translation "./_demo/go/reflectempty" # panic: internal/bytealg selected .s files require plan9asm translation diff --git a/_demo/go/reflectifacecall/main.go b/_demo/go/reflectifacecall/main.go new file mode 100644 index 0000000000..501183d402 --- /dev/null +++ b/_demo/go/reflectifacecall/main.go @@ -0,0 +1,20 @@ +package main + +import ( + "reflect" +) + +func main() { + fn := reflect.ValueOf(reflect.New) + typ := reflect.TypeOf(0) + v := reflect.ValueOf(typ) + r := fn.Call([]reflect.Value{v}) + e := r[0].Interface().(reflect.Value).Elem() + if e.Kind() != reflect.Int { + panic("error kind") + } + e.SetInt(100) + if e.Interface().(int) != 100 { + panic("error value") + } +} diff --git a/runtime/internal/lib/reflect/value.go b/runtime/internal/lib/reflect/value.go index 23aaf9f6d7..312732a9fc 100644 --- a/runtime/internal/lib/reflect/value.go +++ b/runtime/internal/lib/reflect/value.go @@ -243,11 +243,10 @@ type emptyInterface struct { type nonEmptyInterface struct { // see ../runtime/iface.go:/Itab itab *struct { - ityp *abi.Type // static interface type - typ *abi.Type // dynamic concrete type - hash uint32 // copy of typ.hash - _ [4]byte - fun [100000]unsafe.Pointer // method table + inter *abi.InterfaceType + typ *abi.Type + hash uint32 // copy of _type.hash. Used for type switches. + fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter. } word unsafe.Pointer } @@ -2313,7 +2312,16 @@ func toFFIArg(v Value, typ *abi.Type) unsafe.Pointer { return unsafe.Pointer(&v.ptr) case abi.Interface: i := v.Interface() - return unsafe.Pointer(&i) + iface := typ.InterfaceType() + if len(iface.Methods) == 0 { + return unsafe.Pointer(&i) + } + itab := runtime.NewItab(iface, v.typ()) + data := struct { + itab *runtime.Itab + data unsafe.Pointer + }{itab, (*emptyInterface)(unsafe.Pointer(&i)).word} + return unsafe.Pointer(&data) case abi.Map: return toFFIWordArg(v) case abi.Pointer: