Compare commits
4 Commits
xgopilot/c
...
feature/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a74ca940e2 | ||
|
|
0c68ae00c9 | ||
|
|
8d6d1b76f2 | ||
|
|
e47728b053 |
49
_demo/go/reflectindirect/reflect-indirect.go
Normal file
49
_demo/go/reflectindirect/reflect-indirect.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
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")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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")
|
||||||
|
}
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
//go:build go1.23
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import "unique"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var h1 = unique.Make(int(42))
|
|
||||||
var h2 = unique.Make(int(42))
|
|
||||||
if h1 != h2 {
|
|
||||||
panic("h1 and h2 should be equal")
|
|
||||||
}
|
|
||||||
var v1 = h1.Value()
|
|
||||||
var v2 = h2.Value()
|
|
||||||
if v1 != v2 || v1 != 42 {
|
|
||||||
panic("values should be equal to 42")
|
|
||||||
}
|
|
||||||
|
|
||||||
var h3 = unique.Make("hello")
|
|
||||||
var h4 = unique.Make("hello")
|
|
||||||
if h3 != h4 {
|
|
||||||
panic("h3 and h4 should be equal")
|
|
||||||
}
|
|
||||||
var s1 = h3.Value()
|
|
||||||
var s2 = h4.Value()
|
|
||||||
if s1 != s2 || s1 != "hello" {
|
|
||||||
panic("values should be equal to 'hello'")
|
|
||||||
}
|
|
||||||
|
|
||||||
var h5 = unique.Make(int(100))
|
|
||||||
var h6 = unique.Make(int(200))
|
|
||||||
if h5 == h6 {
|
|
||||||
panic("h5 and h6 should not be equal")
|
|
||||||
}
|
|
||||||
var n1 = h5.Value()
|
|
||||||
var n2 = h6.Value()
|
|
||||||
if n1 != 100 || n2 != 200 {
|
|
||||||
panic("values should be 100 and 200 respectively")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -149,64 +149,16 @@ func (p *context) compileType(pkg llssa.Package, t *ssa.Type) {
|
|||||||
if debugInstr {
|
if debugInstr {
|
||||||
log.Println("==> NewType", name, typ)
|
log.Println("==> NewType", name, typ)
|
||||||
}
|
}
|
||||||
if named, ok := typ.(*types.Named); ok {
|
|
||||||
if tp := named.TypeParams(); tp != nil && tp.Len() > 0 {
|
|
||||||
if ta := named.TypeArgs(); ta == nil || ta.Len() == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p.compileMethods(pkg, typ)
|
p.compileMethods(pkg, typ)
|
||||||
p.compileMethods(pkg, types.NewPointer(typ))
|
p.compileMethods(pkg, types.NewPointer(typ))
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasGenericTypeParam(typ types.Type) bool {
|
|
||||||
switch t := typ.(type) {
|
|
||||||
case *types.TypeParam:
|
|
||||||
return true
|
|
||||||
case *types.Named:
|
|
||||||
if tp := t.TypeParams(); tp != nil && tp.Len() > 0 {
|
|
||||||
if ta := t.TypeArgs(); ta == nil || ta.Len() == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ta := t.TypeArgs(); ta != nil {
|
|
||||||
for i := 0; i < ta.Len(); i++ {
|
|
||||||
if hasGenericTypeParam(ta.At(i)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hasGenericTypeParam(t.Underlying())
|
|
||||||
case *types.Pointer:
|
|
||||||
return hasGenericTypeParam(t.Elem())
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *context) compileMethods(pkg llssa.Package, typ types.Type) {
|
func (p *context) compileMethods(pkg llssa.Package, typ types.Type) {
|
||||||
if hasGenericTypeParam(typ) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var typPkg *types.Package
|
|
||||||
if named, ok := typ.(*types.Named); ok {
|
|
||||||
typPkg = named.Obj().Pkg()
|
|
||||||
} else if ptr, ok := typ.(*types.Pointer); ok {
|
|
||||||
if named, ok := ptr.Elem().(*types.Named); ok {
|
|
||||||
typPkg = named.Obj().Pkg()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if typPkg != nil && typPkg != p.goTyps {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
prog := p.goProg
|
prog := p.goProg
|
||||||
mthds := prog.MethodSets.MethodSet(typ)
|
mthds := prog.MethodSets.MethodSet(typ)
|
||||||
for i, n := 0, mthds.Len(); i < n; i++ {
|
for i, n := 0, mthds.Len(); i < n; i++ {
|
||||||
mthd := mthds.At(i)
|
mthd := mthds.At(i)
|
||||||
if ssaMthd := prog.MethodValue(mthd); ssaMthd != nil {
|
if ssaMthd := prog.MethodValue(mthd); ssaMthd != nil {
|
||||||
if ssaMthd.TypeParams() != nil || ssaMthd.TypeArgs() != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
p.compileFuncDecl(pkg, ssaMthd)
|
p.compileFuncDecl(pkg, ssaMthd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1759,6 +1759,16 @@ func ValueOf(i any) Value {
|
|||||||
return unpackEface(i)
|
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,
|
// arrayAt returns the i-th element of p,
|
||||||
// an array whose elements are eltSize bytes wide.
|
// an array whose elements are eltSize bytes wide.
|
||||||
// The array pointed at by p must have at least i+1 elements:
|
// The array pointed at by p must have at least i+1 elements:
|
||||||
|
|||||||
Reference in New Issue
Block a user