1package main
2
3import (
4	"fmt"
5	"reflect"
6	_ "reflect"
7	"unsafe"
8)
9
10type Pair struct{ A, B int }
11
12func pair(a, b int) Pair { var p Pair; p.A = a; p.B = b; return p }
13
14type Triple struct {
15	Pair
16	C int
17}
18
19func (p Pair) First() int {
20	return p.A
21}
22
23func (p Pair) Last() int {
24	return p.B
25}
26
27func (t Triple) Last() int {
28	return t.C
29}
30
31func embedded_field() {
32	printChars()
33	inspectTriple()
34}
35
36func printChars() {
37	for i := 128; i <= 255; i++ {
38		fmt.Printf("%x %c\n", i, i)
39	}
40}
41
42func inspectTriple() {
43	t := Triple{Pair{1, 2}, 3}
44	inspect("declared:           ", t.Pair.First)
45	inspect("declared2:          ", t.Pair.First)
46	inspect("wrapped:            ", t.First)
47	inspect("wrapped2:           ", t.First)
48	inspect("declared  (reflect):", reflect.ValueOf(t.Pair).MethodByName("First").Interface().(func() int))
49	inspect("declared2 (reflect):", reflect.ValueOf(t.Pair).MethodByName("First").Interface().(func() int))
50	inspect("wrapped   (reflect):", reflect.ValueOf(t).MethodByName("First").Interface().(func() int))
51	inspect("wrapped2  (reflect):", reflect.ValueOf(t).MethodByName("First").Interface().(func() int))
52	fmt.Println()
53	inspect("declared:             ", t.Pair.Last)
54	inspect("declared2:            ", t.Pair.Last)
55	inspect("overridden:           ", t.Last)
56	inspect("overridden2:          ", t.Last)
57	inspect("declared    (reflect):", reflect.ValueOf(t.Pair).MethodByName("Last").Interface().(func() int))
58	inspect("declared2   (reflect):", reflect.ValueOf(t.Pair).MethodByName("Last").Interface().(func() int))
59	inspect("overridden  (reflect):", reflect.ValueOf(t).MethodByName("Last").Interface().(func() int))
60	inspect("overridden2 (reflect):", reflect.ValueOf(t).MethodByName("Last").Interface().(func() int))
61	fmt.Println()
62	/*
63		inspectMethod1(t, "First")
64		inspectMethod1(t.Pair, "First")
65		inspectMethod1(t, "Last")
66		inspectMethod1(t.Pair, "Last")
67	*/
68}
69
70func inspect(name string, x func() int) {
71	u := *(**uintptr)(unsafe.Pointer(&x))
72	u4 := *(**[16]uintptr)(unsafe.Pointer(&x))
73	fmt.Printf("%s %#v %#v %#v\n", name, x, u, *u4)
74}
75
76type UnsafeValue struct {
77	typ  *uintptr
78	ptr  unsafe.Pointer
79	flag uintptr
80}
81type UnsafeInterface struct {
82	typ *uintptr
83	ptr unsafe.Pointer
84}
85
86func inspectMethod(x interface{}, y interface{}, name string) {
87	mtd1 := reflect.ValueOf(x).MethodByName(name).Interface()
88	mtd2 := reflect.ValueOf(y).MethodByName(name).Interface()
89
90	inspectMethod1(mtd1, name)
91	inspectMethod1(mtd2, name)
92}
93
94func inspectMethod1(mtd interface{}, name string) {
95	fmt.Printf("%s:\t%#v\n", name, mtd)
96	uf := *(*UnsafeInterface)(unsafe.Pointer(&mtd))
97	fmt.Printf("%s:\tInterface = %#v\n", name, uf)
98	fptr := (**uintptr)(uf.ptr)
99	fmt.Printf("%s:\tInterface.ptr = %#v %#v\n", name, fptr, *fptr)
100}
101
102func inspectMethod2(x interface{}, name string) {
103	t := reflect.TypeOf(x)
104	mtd, _ := t.MethodByName(name)
105	fmt.Printf("%s:\t%v\n", name, mtd)
106	var f reflect.Value = mtd.Func
107	uf := *(*UnsafeValue)(unsafe.Pointer(&f))
108	fmt.Printf("%s:\tFunc = %#v\n", name, uf)
109	fptr := (**uintptr)(uf.ptr)
110	fmt.Printf("%s:\tFunc.ptr = %#v %#v %#v\n", name, fptr, *fptr, **fptr)
111}
112