golang.org/x/tools@v0.21.1-0.20240520172518-788d39e776b1/go/ssa/interp/reflect.go (about) 1 // Copyright 2013 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package interp 6 7 // Emulated "reflect" package. 8 // 9 // We completely replace the built-in "reflect" package. 10 // The only thing clients can depend upon are that reflect.Type is an 11 // interface and reflect.Value is an (opaque) struct. 12 13 import ( 14 "fmt" 15 "go/token" 16 "go/types" 17 "reflect" 18 "unsafe" 19 20 "golang.org/x/tools/go/ssa" 21 "golang.org/x/tools/internal/aliases" 22 ) 23 24 type opaqueType struct { 25 types.Type 26 name string 27 } 28 29 func (t *opaqueType) String() string { return t.name } 30 31 // A bogus "reflect" type-checker package. Shared across interpreters. 32 var reflectTypesPackage = types.NewPackage("reflect", "reflect") 33 34 // rtype is the concrete type the interpreter uses to implement the 35 // reflect.Type interface. 36 // 37 // type rtype <opaque> 38 var rtypeType = makeNamedType("rtype", &opaqueType{nil, "rtype"}) 39 40 // error is an (interpreted) named type whose underlying type is string. 41 // The interpreter uses it for all implementations of the built-in error 42 // interface that it creates. 43 // We put it in the "reflect" package for expedience. 44 // 45 // type error string 46 var errorType = makeNamedType("error", &opaqueType{nil, "error"}) 47 48 func makeNamedType(name string, underlying types.Type) *types.Named { 49 obj := types.NewTypeName(token.NoPos, reflectTypesPackage, name, nil) 50 return types.NewNamed(obj, underlying, nil) 51 } 52 53 func makeReflectValue(t types.Type, v value) value { 54 return structure{rtype{t}, v} 55 } 56 57 // Given a reflect.Value, returns its rtype. 58 func rV2T(v value) rtype { 59 return v.(structure)[0].(rtype) 60 } 61 62 // Given a reflect.Value, returns the underlying interpreter value. 63 func rV2V(v value) value { 64 return v.(structure)[1] 65 } 66 67 // makeReflectType boxes up an rtype in a reflect.Type interface. 68 func makeReflectType(rt rtype) value { 69 return iface{rtypeType, rt} 70 } 71 72 func ext۰reflect۰rtype۰Bits(fr *frame, args []value) value { 73 // Signature: func (t reflect.rtype) int 74 rt := args[0].(rtype).t 75 basic, ok := rt.Underlying().(*types.Basic) 76 if !ok { 77 panic(fmt.Sprintf("reflect.Type.Bits(%T): non-basic type", rt)) 78 } 79 return int(fr.i.sizes.Sizeof(basic)) * 8 80 } 81 82 func ext۰reflect۰rtype۰Elem(fr *frame, args []value) value { 83 // Signature: func (t reflect.rtype) reflect.Type 84 return makeReflectType(rtype{args[0].(rtype).t.Underlying().(interface { 85 Elem() types.Type 86 }).Elem()}) 87 } 88 89 func ext۰reflect۰rtype۰Field(fr *frame, args []value) value { 90 // Signature: func (t reflect.rtype, i int) reflect.StructField 91 st := args[0].(rtype).t.Underlying().(*types.Struct) 92 i := args[1].(int) 93 f := st.Field(i) 94 return structure{ 95 f.Name(), 96 f.Pkg().Path(), 97 makeReflectType(rtype{f.Type()}), 98 st.Tag(i), 99 0, // TODO(adonovan): offset 100 []value{}, // TODO(adonovan): indices 101 f.Anonymous(), 102 } 103 } 104 105 func ext۰reflect۰rtype۰In(fr *frame, args []value) value { 106 // Signature: func (t reflect.rtype, i int) int 107 i := args[1].(int) 108 return makeReflectType(rtype{args[0].(rtype).t.(*types.Signature).Params().At(i).Type()}) 109 } 110 111 func ext۰reflect۰rtype۰Kind(fr *frame, args []value) value { 112 // Signature: func (t reflect.rtype) uint 113 return uint(reflectKind(args[0].(rtype).t)) 114 } 115 116 func ext۰reflect۰rtype۰NumField(fr *frame, args []value) value { 117 // Signature: func (t reflect.rtype) int 118 return args[0].(rtype).t.Underlying().(*types.Struct).NumFields() 119 } 120 121 func ext۰reflect۰rtype۰NumIn(fr *frame, args []value) value { 122 // Signature: func (t reflect.rtype) int 123 return args[0].(rtype).t.Underlying().(*types.Signature).Params().Len() 124 } 125 126 func ext۰reflect۰rtype۰NumMethod(fr *frame, args []value) value { 127 // Signature: func (t reflect.rtype) int 128 return fr.i.prog.MethodSets.MethodSet(args[0].(rtype).t).Len() 129 } 130 131 func ext۰reflect۰rtype۰NumOut(fr *frame, args []value) value { 132 // Signature: func (t reflect.rtype) int 133 return args[0].(rtype).t.Underlying().(*types.Signature).Results().Len() 134 } 135 136 func ext۰reflect۰rtype۰Out(fr *frame, args []value) value { 137 // Signature: func (t reflect.rtype, i int) int 138 i := args[1].(int) 139 return makeReflectType(rtype{args[0].(rtype).t.Underlying().(*types.Signature).Results().At(i).Type()}) 140 } 141 142 func ext۰reflect۰rtype۰Size(fr *frame, args []value) value { 143 // Signature: func (t reflect.rtype) uintptr 144 return uintptr(fr.i.sizes.Sizeof(args[0].(rtype).t)) 145 } 146 147 func ext۰reflect۰rtype۰String(fr *frame, args []value) value { 148 // Signature: func (t reflect.rtype) string 149 return args[0].(rtype).t.String() 150 } 151 152 func ext۰reflect۰New(fr *frame, args []value) value { 153 // Signature: func (t reflect.Type) reflect.Value 154 t := args[0].(iface).v.(rtype).t 155 alloc := zero(t) 156 return makeReflectValue(types.NewPointer(t), &alloc) 157 } 158 159 func ext۰reflect۰SliceOf(fr *frame, args []value) value { 160 // Signature: func (t reflect.rtype) Type 161 return makeReflectType(rtype{types.NewSlice(args[0].(iface).v.(rtype).t)}) 162 } 163 164 func ext۰reflect۰TypeOf(fr *frame, args []value) value { 165 // Signature: func (t reflect.rtype) Type 166 return makeReflectType(rtype{args[0].(iface).t}) 167 } 168 169 func ext۰reflect۰ValueOf(fr *frame, args []value) value { 170 // Signature: func (interface{}) reflect.Value 171 itf := args[0].(iface) 172 return makeReflectValue(itf.t, itf.v) 173 } 174 175 func ext۰reflect۰Zero(fr *frame, args []value) value { 176 // Signature: func (t reflect.Type) reflect.Value 177 t := args[0].(iface).v.(rtype).t 178 return makeReflectValue(t, zero(t)) 179 } 180 181 func reflectKind(t types.Type) reflect.Kind { 182 switch t := t.(type) { 183 case *types.Named, *aliases.Alias: 184 return reflectKind(t.Underlying()) 185 case *types.Basic: 186 switch t.Kind() { 187 case types.Bool: 188 return reflect.Bool 189 case types.Int: 190 return reflect.Int 191 case types.Int8: 192 return reflect.Int8 193 case types.Int16: 194 return reflect.Int16 195 case types.Int32: 196 return reflect.Int32 197 case types.Int64: 198 return reflect.Int64 199 case types.Uint: 200 return reflect.Uint 201 case types.Uint8: 202 return reflect.Uint8 203 case types.Uint16: 204 return reflect.Uint16 205 case types.Uint32: 206 return reflect.Uint32 207 case types.Uint64: 208 return reflect.Uint64 209 case types.Uintptr: 210 return reflect.Uintptr 211 case types.Float32: 212 return reflect.Float32 213 case types.Float64: 214 return reflect.Float64 215 case types.Complex64: 216 return reflect.Complex64 217 case types.Complex128: 218 return reflect.Complex128 219 case types.String: 220 return reflect.String 221 case types.UnsafePointer: 222 return reflect.UnsafePointer 223 } 224 case *types.Array: 225 return reflect.Array 226 case *types.Chan: 227 return reflect.Chan 228 case *types.Signature: 229 return reflect.Func 230 case *types.Interface: 231 return reflect.Interface 232 case *types.Map: 233 return reflect.Map 234 case *types.Pointer: 235 return reflect.Ptr 236 case *types.Slice: 237 return reflect.Slice 238 case *types.Struct: 239 return reflect.Struct 240 } 241 panic(fmt.Sprint("unexpected type: ", t)) 242 } 243 244 func ext۰reflect۰Value۰Kind(fr *frame, args []value) value { 245 // Signature: func (reflect.Value) uint 246 return uint(reflectKind(rV2T(args[0]).t)) 247 } 248 249 func ext۰reflect۰Value۰String(fr *frame, args []value) value { 250 // Signature: func (reflect.Value) string 251 return toString(rV2V(args[0])) 252 } 253 254 func ext۰reflect۰Value۰Type(fr *frame, args []value) value { 255 // Signature: func (reflect.Value) reflect.Type 256 return makeReflectType(rV2T(args[0])) 257 } 258 259 func ext۰reflect۰Value۰Uint(fr *frame, args []value) value { 260 // Signature: func (reflect.Value) uint64 261 switch v := rV2V(args[0]).(type) { 262 case uint: 263 return uint64(v) 264 case uint8: 265 return uint64(v) 266 case uint16: 267 return uint64(v) 268 case uint32: 269 return uint64(v) 270 case uint64: 271 return uint64(v) 272 case uintptr: 273 return uint64(v) 274 } 275 panic("reflect.Value.Uint") 276 } 277 278 func ext۰reflect۰Value۰Len(fr *frame, args []value) value { 279 // Signature: func (reflect.Value) int 280 switch v := rV2V(args[0]).(type) { 281 case string: 282 return len(v) 283 case array: 284 return len(v) 285 case chan value: 286 return cap(v) 287 case []value: 288 return len(v) 289 case *hashmap: 290 return v.len() 291 case map[value]value: 292 return len(v) 293 default: 294 panic(fmt.Sprintf("reflect.(Value).Len(%v)", v)) 295 } 296 } 297 298 func ext۰reflect۰Value۰MapIndex(fr *frame, args []value) value { 299 // Signature: func (reflect.Value) Value 300 tValue := rV2T(args[0]).t.Underlying().(*types.Map).Key() 301 k := rV2V(args[1]) 302 switch m := rV2V(args[0]).(type) { 303 case map[value]value: 304 if v, ok := m[k]; ok { 305 return makeReflectValue(tValue, v) 306 } 307 308 case *hashmap: 309 if v := m.lookup(k.(hashable)); v != nil { 310 return makeReflectValue(tValue, v) 311 } 312 313 default: 314 panic(fmt.Sprintf("(reflect.Value).MapIndex(%T, %T)", m, k)) 315 } 316 return makeReflectValue(nil, nil) 317 } 318 319 func ext۰reflect۰Value۰MapKeys(fr *frame, args []value) value { 320 // Signature: func (reflect.Value) []Value 321 var keys []value 322 tKey := rV2T(args[0]).t.Underlying().(*types.Map).Key() 323 switch v := rV2V(args[0]).(type) { 324 case map[value]value: 325 for k := range v { 326 keys = append(keys, makeReflectValue(tKey, k)) 327 } 328 329 case *hashmap: 330 for _, e := range v.entries() { 331 for ; e != nil; e = e.next { 332 keys = append(keys, makeReflectValue(tKey, e.key)) 333 } 334 } 335 336 default: 337 panic(fmt.Sprintf("(reflect.Value).MapKeys(%T)", v)) 338 } 339 return keys 340 } 341 342 func ext۰reflect۰Value۰NumField(fr *frame, args []value) value { 343 // Signature: func (reflect.Value) int 344 return len(rV2V(args[0]).(structure)) 345 } 346 347 func ext۰reflect۰Value۰NumMethod(fr *frame, args []value) value { 348 // Signature: func (reflect.Value) int 349 return fr.i.prog.MethodSets.MethodSet(rV2T(args[0]).t).Len() 350 } 351 352 func ext۰reflect۰Value۰Pointer(fr *frame, args []value) value { 353 // Signature: func (v reflect.Value) uintptr 354 switch v := rV2V(args[0]).(type) { 355 case *value: 356 return uintptr(unsafe.Pointer(v)) 357 case chan value: 358 return reflect.ValueOf(v).Pointer() 359 case []value: 360 return reflect.ValueOf(v).Pointer() 361 case *hashmap: 362 return reflect.ValueOf(v.entries()).Pointer() 363 case map[value]value: 364 return reflect.ValueOf(v).Pointer() 365 case *ssa.Function: 366 return uintptr(unsafe.Pointer(v)) 367 case *closure: 368 return uintptr(unsafe.Pointer(v)) 369 default: 370 panic(fmt.Sprintf("reflect.(Value).Pointer(%T)", v)) 371 } 372 } 373 374 func ext۰reflect۰Value۰Index(fr *frame, args []value) value { 375 // Signature: func (v reflect.Value, i int) Value 376 i := args[1].(int) 377 t := rV2T(args[0]).t.Underlying() 378 switch v := rV2V(args[0]).(type) { 379 case array: 380 return makeReflectValue(t.(*types.Array).Elem(), v[i]) 381 case []value: 382 return makeReflectValue(t.(*types.Slice).Elem(), v[i]) 383 default: 384 panic(fmt.Sprintf("reflect.(Value).Index(%T)", v)) 385 } 386 } 387 388 func ext۰reflect۰Value۰Bool(fr *frame, args []value) value { 389 // Signature: func (reflect.Value) bool 390 return rV2V(args[0]).(bool) 391 } 392 393 func ext۰reflect۰Value۰CanAddr(fr *frame, args []value) value { 394 // Signature: func (v reflect.Value) bool 395 // Always false for our representation. 396 return false 397 } 398 399 func ext۰reflect۰Value۰CanInterface(fr *frame, args []value) value { 400 // Signature: func (v reflect.Value) bool 401 // Always true for our representation. 402 return true 403 } 404 405 func ext۰reflect۰Value۰Elem(fr *frame, args []value) value { 406 // Signature: func (v reflect.Value) reflect.Value 407 switch x := rV2V(args[0]).(type) { 408 case iface: 409 return makeReflectValue(x.t, x.v) 410 case *value: 411 var v value 412 if x != nil { 413 v = *x 414 } 415 return makeReflectValue(rV2T(args[0]).t.Underlying().(*types.Pointer).Elem(), v) 416 default: 417 panic(fmt.Sprintf("reflect.(Value).Elem(%T)", x)) 418 } 419 } 420 421 func ext۰reflect۰Value۰Field(fr *frame, args []value) value { 422 // Signature: func (v reflect.Value, i int) reflect.Value 423 v := args[0] 424 i := args[1].(int) 425 return makeReflectValue(rV2T(v).t.Underlying().(*types.Struct).Field(i).Type(), rV2V(v).(structure)[i]) 426 } 427 428 func ext۰reflect۰Value۰Float(fr *frame, args []value) value { 429 // Signature: func (reflect.Value) float64 430 switch v := rV2V(args[0]).(type) { 431 case float32: 432 return float64(v) 433 case float64: 434 return float64(v) 435 } 436 panic("reflect.Value.Float") 437 } 438 439 func ext۰reflect۰Value۰Interface(fr *frame, args []value) value { 440 // Signature: func (v reflect.Value) interface{} 441 return ext۰reflect۰valueInterface(fr, args) 442 } 443 444 func ext۰reflect۰Value۰Int(fr *frame, args []value) value { 445 // Signature: func (reflect.Value) int64 446 switch x := rV2V(args[0]).(type) { 447 case int: 448 return int64(x) 449 case int8: 450 return int64(x) 451 case int16: 452 return int64(x) 453 case int32: 454 return int64(x) 455 case int64: 456 return x 457 default: 458 panic(fmt.Sprintf("reflect.(Value).Int(%T)", x)) 459 } 460 } 461 462 func ext۰reflect۰Value۰IsNil(fr *frame, args []value) value { 463 // Signature: func (reflect.Value) bool 464 switch x := rV2V(args[0]).(type) { 465 case *value: 466 return x == nil 467 case chan value: 468 return x == nil 469 case map[value]value: 470 return x == nil 471 case *hashmap: 472 return x == nil 473 case iface: 474 return x.t == nil 475 case []value: 476 return x == nil 477 case *ssa.Function: 478 return x == nil 479 case *ssa.Builtin: 480 return x == nil 481 case *closure: 482 return x == nil 483 default: 484 panic(fmt.Sprintf("reflect.(Value).IsNil(%T)", x)) 485 } 486 } 487 488 func ext۰reflect۰Value۰IsValid(fr *frame, args []value) value { 489 // Signature: func (reflect.Value) bool 490 return rV2V(args[0]) != nil 491 } 492 493 func ext۰reflect۰Value۰Set(fr *frame, args []value) value { 494 // TODO(adonovan): implement. 495 return nil 496 } 497 498 func ext۰reflect۰valueInterface(fr *frame, args []value) value { 499 // Signature: func (v reflect.Value, safe bool) interface{} 500 v := args[0].(structure) 501 return iface{rV2T(v).t, rV2V(v)} 502 } 503 504 func ext۰reflect۰error۰Error(fr *frame, args []value) value { 505 return args[0] 506 } 507 508 // newMethod creates a new method of the specified name, package and receiver type. 509 func newMethod(pkg *ssa.Package, recvType types.Type, name string) *ssa.Function { 510 // TODO(adonovan): fix: hack: currently the only part of Signature 511 // that is needed is the "pointerness" of Recv.Type, and for 512 // now, we'll set it to always be false since we're only 513 // concerned with rtype. Encapsulate this better. 514 sig := types.NewSignature(types.NewVar(token.NoPos, nil, "recv", recvType), nil, nil, false) 515 fn := pkg.Prog.NewFunction(name, sig, "fake reflect method") 516 fn.Pkg = pkg 517 return fn 518 } 519 520 func initReflect(i *interpreter) { 521 i.reflectPackage = &ssa.Package{ 522 Prog: i.prog, 523 Pkg: reflectTypesPackage, 524 Members: make(map[string]ssa.Member), 525 } 526 527 // Clobber the type-checker's notion of reflect.Value's 528 // underlying type so that it more closely matches the fake one 529 // (at least in the number of fields---we lie about the type of 530 // the rtype field). 531 // 532 // We must ensure that calls to (ssa.Value).Type() return the 533 // fake type so that correct "shape" is used when allocating 534 // variables, making zero values, loading, and storing. 535 // 536 // TODO(adonovan): obviously this is a hack. We need a cleaner 537 // way to fake the reflect package (almost---DeepEqual is fine). 538 // One approach would be not to even load its source code, but 539 // provide fake source files. This would guarantee that no bad 540 // information leaks into other packages. 541 if r := i.prog.ImportedPackage("reflect"); r != nil { 542 rV := r.Pkg.Scope().Lookup("Value").Type().(*types.Named) 543 544 // delete bodies of the old methods 545 mset := i.prog.MethodSets.MethodSet(rV) 546 for j := 0; j < mset.Len(); j++ { 547 i.prog.MethodValue(mset.At(j)).Blocks = nil 548 } 549 550 tEface := types.NewInterface(nil, nil).Complete() 551 rV.SetUnderlying(types.NewStruct([]*types.Var{ 552 types.NewField(token.NoPos, r.Pkg, "t", tEface, false), // a lie 553 types.NewField(token.NoPos, r.Pkg, "v", tEface, false), 554 }, nil)) 555 } 556 557 i.rtypeMethods = methodSet{ 558 "Bits": newMethod(i.reflectPackage, rtypeType, "Bits"), 559 "Elem": newMethod(i.reflectPackage, rtypeType, "Elem"), 560 "Field": newMethod(i.reflectPackage, rtypeType, "Field"), 561 "In": newMethod(i.reflectPackage, rtypeType, "In"), 562 "Kind": newMethod(i.reflectPackage, rtypeType, "Kind"), 563 "NumField": newMethod(i.reflectPackage, rtypeType, "NumField"), 564 "NumIn": newMethod(i.reflectPackage, rtypeType, "NumIn"), 565 "NumMethod": newMethod(i.reflectPackage, rtypeType, "NumMethod"), 566 "NumOut": newMethod(i.reflectPackage, rtypeType, "NumOut"), 567 "Out": newMethod(i.reflectPackage, rtypeType, "Out"), 568 "Size": newMethod(i.reflectPackage, rtypeType, "Size"), 569 "String": newMethod(i.reflectPackage, rtypeType, "String"), 570 } 571 i.errorMethods = methodSet{ 572 "Error": newMethod(i.reflectPackage, errorType, "Error"), 573 } 574 }