From e47728b05374fd84926be4be931bda3fe4a82fea Mon Sep 17 00:00:00 2001 From: xgopilot Date: Fri, 17 Oct 2025 08:06:30 +0000 Subject: [PATCH 1/4] feat(reflect): add Indirect function Implements reflect.Indirect function to support pointer dereferencing. This function returns the value that a pointer points to, or returns the value unchanged if it's not a pointer. Fixes #1354 Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: luoliwoshang --- _cmptest/reflect_indirect/test.go | 24 ++++++++++++++++++++++++ runtime/internal/lib/reflect/value.go | 10 ++++++++++ 2 files changed, 34 insertions(+) create mode 100644 _cmptest/reflect_indirect/test.go diff --git a/_cmptest/reflect_indirect/test.go b/_cmptest/reflect_indirect/test.go new file mode 100644 index 00000000..29fcf750 --- /dev/null +++ b/_cmptest/reflect_indirect/test.go @@ -0,0 +1,24 @@ +package main + +import ( + "fmt" + "reflect" +) + +func main() { + x := 42 + p := &x + + // Test 1: Non-pointer value - should return same value + v1 := reflect.Indirect(reflect.ValueOf(x)) + fmt.Printf("Non-pointer: %v\n", v1.Interface()) + + // Test 2: Pointer - should dereference + v2 := reflect.Indirect(reflect.ValueOf(p)) + fmt.Printf("Pointer: %v\n", v2.Interface()) + + // Test 3: Nil pointer + var nilPtr *int + v3 := reflect.Indirect(reflect.ValueOf(nilPtr)) + fmt.Printf("Nil pointer valid: %v\n", v3.IsValid()) +} diff --git a/runtime/internal/lib/reflect/value.go b/runtime/internal/lib/reflect/value.go index 4cec494d..f1657ab5 100644 --- a/runtime/internal/lib/reflect/value.go +++ b/runtime/internal/lib/reflect/value.go @@ -1759,6 +1759,16 @@ func ValueOf(i any) Value { return unpackEface(i) } +// Indirect returns the value that v points to. +// If v is a nil pointer, Indirect returns a zero Value. +// If v is not a pointer, Indirect returns v. +func Indirect(v Value) Value { + if v.Kind() != Pointer { + return v + } + return v.Elem() +} + // arrayAt returns the i-th element of p, // an array whose elements are eltSize bytes wide. // The array pointed at by p must have at least i+1 elements: From 8d6d1b76f25875303d5f0d893741d86f148a6d36 Mon Sep 17 00:00:00 2001 From: xgopilot Date: Fri, 17 Oct 2025 09:06:09 +0000 Subject: [PATCH 2/4] refactor: move reflect.Indirect test to _demo and use panic() - Moved test from _cmptest/reflect_indirect/ to _demo/go/reflect-indirect/ - Refactored to use panic() for validation instead of fmt.Println - Added proper assertions for all test cases Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: luoliwoshang --- _cmptest/reflect_indirect/test.go | 24 -------------- _demo/go/reflect-indirect/reflect-indirect.go | 31 +++++++++++++++++++ 2 files changed, 31 insertions(+), 24 deletions(-) delete mode 100644 _cmptest/reflect_indirect/test.go create mode 100644 _demo/go/reflect-indirect/reflect-indirect.go diff --git a/_cmptest/reflect_indirect/test.go b/_cmptest/reflect_indirect/test.go deleted file mode 100644 index 29fcf750..00000000 --- a/_cmptest/reflect_indirect/test.go +++ /dev/null @@ -1,24 +0,0 @@ -package main - -import ( - "fmt" - "reflect" -) - -func main() { - x := 42 - p := &x - - // Test 1: Non-pointer value - should return same value - v1 := reflect.Indirect(reflect.ValueOf(x)) - fmt.Printf("Non-pointer: %v\n", v1.Interface()) - - // Test 2: Pointer - should dereference - v2 := reflect.Indirect(reflect.ValueOf(p)) - fmt.Printf("Pointer: %v\n", v2.Interface()) - - // Test 3: Nil pointer - var nilPtr *int - v3 := reflect.Indirect(reflect.ValueOf(nilPtr)) - fmt.Printf("Nil pointer valid: %v\n", v3.IsValid()) -} diff --git a/_demo/go/reflect-indirect/reflect-indirect.go b/_demo/go/reflect-indirect/reflect-indirect.go new file mode 100644 index 00000000..4deb79e8 --- /dev/null +++ b/_demo/go/reflect-indirect/reflect-indirect.go @@ -0,0 +1,31 @@ +package main + +import ( + "reflect" +) + +func main() { + x := 42 + p := &x + + // Test 1: Non-pointer value - should return same value + v1 := reflect.Indirect(reflect.ValueOf(x)) + if !v1.IsValid() || v1.Interface() != 42 { + panic("Non-pointer test failed: expected 42") + } + + // Test 2: Pointer - should dereference + v2 := reflect.Indirect(reflect.ValueOf(p)) + if !v2.IsValid() || v2.Interface() != 42 { + panic("Pointer dereference test failed: expected 42") + } + + // Test 3: Nil pointer - should return invalid Value + var nilPtr *int + v3 := reflect.Indirect(reflect.ValueOf(nilPtr)) + if v3.IsValid() { + panic("Nil pointer test failed: expected invalid Value") + } + + println("PASS") +} From 0c68ae00c9a4845e20dfa25c778d5fb532325403 Mon Sep 17 00:00:00 2001 From: xgopilot Date: Fri, 17 Oct 2025 09:19:20 +0000 Subject: [PATCH 3/4] refactor: rename reflect-indirect to reflectindirect Follow naming convention of other demo folders (reflectfunc, gotime, etc.) Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: luoliwoshang --- .../go/{reflect-indirect => reflectindirect}/reflect-indirect.go | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename _demo/go/{reflect-indirect => reflectindirect}/reflect-indirect.go (100%) diff --git a/_demo/go/reflect-indirect/reflect-indirect.go b/_demo/go/reflectindirect/reflect-indirect.go similarity index 100% rename from _demo/go/reflect-indirect/reflect-indirect.go rename to _demo/go/reflectindirect/reflect-indirect.go From a74ca940e2859cc43c53bc459db25dd36c6118c0 Mon Sep 17 00:00:00 2001 From: xgopilot Date: Mon, 20 Oct 2025 02:29:18 +0000 Subject: [PATCH 4/4] feat(reflect): add struct test cases for Indirect function Generated with [codeagent](https://github.com/qbox/codeagent) Co-authored-by: luoliwoshang --- _demo/go/reflectindirect/reflect-indirect.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/_demo/go/reflectindirect/reflect-indirect.go b/_demo/go/reflectindirect/reflect-indirect.go index 4deb79e8..69332a47 100644 --- a/_demo/go/reflectindirect/reflect-indirect.go +++ b/_demo/go/reflectindirect/reflect-indirect.go @@ -27,5 +27,23 @@ func main() { panic("Nil pointer test failed: expected invalid Value") } + // Test 4: Struct value - should return same value + type Person struct { + Name string + Age int + } + person := Person{Name: "Alice", Age: 30} + v4 := reflect.Indirect(reflect.ValueOf(person)) + if !v4.IsValid() || v4.Interface().(Person).Name != "Alice" || v4.Interface().(Person).Age != 30 { + panic("Struct value test failed: expected Person{Name: Alice, Age: 30}") + } + + // Test 5: Struct pointer - should dereference + personPtr := &Person{Name: "Bob", Age: 25} + v5 := reflect.Indirect(reflect.ValueOf(personPtr)) + if !v5.IsValid() || v5.Interface().(Person).Name != "Bob" || v5.Interface().(Person).Age != 25 { + panic("Struct pointer test failed: expected Person{Name: Bob, Age: 25}") + } + println("PASS") }