github.com/switchupcb/yaegi@v0.10.2/internal/unsafe2/unsafe.go (about) 1 package unsafe2 2 3 import ( 4 "reflect" 5 "unsafe" 6 ) 7 8 type dummy struct{} 9 10 // DummyType represents a stand-in for a recursive type. 11 var DummyType = reflect.TypeOf(dummy{}) 12 13 // the following type sizes must match their original definition in Go src/reflect/type.go. 14 15 type rtype struct { 16 _ uintptr 17 _ uintptr 18 _ uint32 19 _ uint32 20 _ uintptr 21 _ uintptr 22 _ uint32 23 _ uint32 24 } 25 26 type emptyInterface struct { 27 typ *rtype 28 _ unsafe.Pointer 29 } 30 31 type structField struct { 32 _ uintptr 33 typ *rtype 34 _ uintptr 35 } 36 37 type structType struct { 38 rtype 39 _ uintptr 40 fields []structField 41 } 42 43 // SwapFieldType swaps the type of the struct field with the given type. 44 // 45 // The struct type must have been created at runtime. This is very unsafe. 46 func SwapFieldType(s reflect.Type, idx int, t reflect.Type) { 47 if s.Kind() != reflect.Struct || idx >= s.NumField() { 48 return 49 } 50 51 rtyp := unpackType(s) 52 styp := (*structType)(unsafe.Pointer(rtyp)) 53 f := styp.fields[idx] 54 f.typ = unpackType(t) 55 styp.fields[idx] = f 56 } 57 58 func unpackType(t reflect.Type) *rtype { 59 v := reflect.New(t).Elem().Interface() 60 return (*emptyInterface)(unsafe.Pointer(&v)).typ 61 }