github.com/zerosnake0/jzon@v0.0.9-0.20230801092939-1b135cb83f7f/eface_test.go (about) 1 package jzon 2 3 import ( 4 "log" 5 "reflect" 6 "runtime/debug" 7 "testing" 8 "unsafe" 9 10 "github.com/stretchr/testify/require" 11 ) 12 13 func TestEface(t *testing.T) { 14 f := func(o interface{}) *eface { 15 return (*eface)(unsafe.Pointer(&o)) 16 } 17 a := 1 18 b := 2 19 ef1 := f(&a) 20 ef2 := f(&b) 21 require.Equal(t, ef1.rtype, ef2.rtype) 22 // require.Equal(t, uintptr(strconv.IntSize/8), uintptr(ef2.data)-uintptr(ef1.data)) 23 t.Logf("%x %x", ef1.rtype, ef1.data) 24 t.Logf("%x %x", ef2.rtype, ef2.data) 25 26 // with reflect 27 r := reflect.TypeOf(&a) 28 ef3 := (*eface)(unsafe.Pointer(&r)) 29 require.Equal(t, ef1.rtype, uintptr(ef3.data)) 30 require.Equal(t, ef1.rtype, rtypeOfType(r)) 31 32 // pack 33 packed := packEFace(rtype(ef3.data), ef1.data) 34 t.Logf("%+v", packed) 35 v, ok := packed.(*int) 36 t.Logf("%+v %+v", v, ok) 37 require.True(t, ok) 38 require.Equal(t, &a, v) 39 } 40 41 func TestEface2(t *testing.T) { 42 func() { 43 i := 1 44 var o interface{} = i 45 ef := packEFace(rtypeOfType(reflect.TypeOf(i)), unsafe.Pointer(&i)) 46 47 t.Log("o", o) 48 t.Log("ef", ef) 49 i2 := ef.(int) 50 t.Log("i2", i2) 51 52 i = 2 53 t.Log("o", o) 54 t.Log("ef", ef) 55 t.Log("i2", i2) 56 }() 57 debug.FreeOSMemory() 58 } 59 60 type testEFstruct struct { 61 a int 62 } 63 64 func (t testEFstruct) Foo() { 65 log.Printf("calling %x", unsafe.Pointer(&t)) 66 t.a++ 67 } 68 69 func (t testEFstruct) Int() int { 70 return t.a 71 } 72 73 func TestEface3(t *testing.T) { 74 var f func(o interface{}, i int) 75 f = func(o interface{}, i int) { 76 ef := (*eface)(unsafe.Pointer(&o)) 77 log.Println("->", i, ef.data) 78 if i > 0 { 79 f(o, i-1) 80 } 81 } 82 f2 := func(o interface{}) { 83 v := reflect.ValueOf(o) 84 o2 := v.Interface() 85 f(o2, 1) 86 } 87 func() { 88 var st testEFstruct 89 f(st, 1) 90 log.Printf("&st, %p", &st) 91 log.Printf("st.a, %d", st.a) 92 93 f2(st) 94 95 type ifoo interface { 96 Foo() 97 Int() int 98 } 99 100 var foo ifoo = st 101 log.Println("iface data", (*iface)(unsafe.Pointer(&foo)).data) 102 foo.Foo() 103 log.Printf("st.a, %d", st.a) 104 log.Printf("foo.Int(), %d", foo.Int()) 105 foo.Foo() 106 log.Printf("foo.Int(), %d", foo.Int()) 107 108 ef := packEFace(rtypeOfType(reflect.TypeOf(st)), unsafe.Pointer(&st)) 109 foo = ef.(ifoo) 110 foo.Foo() 111 log.Printf("st.a, %d", st.a) 112 }() 113 debug.FreeOSMemory() 114 }