@@ -2424,3 +2424,86 @@ func rewriteStructStore(v *Value) *Value {
2424
2424
2425
2425
return mem
2426
2426
}
2427
+
2428
+ // isDirectType reports whether v represents a type
2429
+ // (a *runtime._type) whose value is stored directly in an
2430
+ // interface (i.e., is pointer or pointer-like).
2431
+ func isDirectType (v * Value ) bool {
2432
+ return isDirectType1 (v )
2433
+ }
2434
+
2435
+ // v is a type
2436
+ func isDirectType1 (v * Value ) bool {
2437
+ switch v .Op {
2438
+ case OpITab :
2439
+ return isDirectType2 (v .Args [0 ])
2440
+ case OpAddr :
2441
+ lsym := v .Aux .(* obj.LSym )
2442
+ if lsym .Extra == nil {
2443
+ return false
2444
+ }
2445
+ if ti , ok := (* lsym .Extra ).(* obj.TypeInfo ); ok {
2446
+ return types .IsDirectIface (ti .Type .(* types.Type ))
2447
+ }
2448
+ }
2449
+ return false
2450
+ }
2451
+
2452
+ // v is an empty interface
2453
+ func isDirectType2 (v * Value ) bool {
2454
+ switch v .Op {
2455
+ case OpIMake :
2456
+ return isDirectType1 (v .Args [0 ])
2457
+ }
2458
+ return false
2459
+ }
2460
+
2461
+ // isDirectIface reports whether v represents an itab
2462
+ // (a *runtime._itab) for a type whose value is stored directly
2463
+ // in an interface (i.e., is pointer or pointer-like).
2464
+ func isDirectIface (v * Value ) bool {
2465
+ return isDirectIface1 (v , 9 )
2466
+ }
2467
+
2468
+ // v is an itab
2469
+ func isDirectIface1 (v * Value , depth int ) bool {
2470
+ if depth == 0 {
2471
+ return false
2472
+ }
2473
+ switch v .Op {
2474
+ case OpITab :
2475
+ return isDirectIface2 (v .Args [0 ], depth - 1 )
2476
+ case OpAddr :
2477
+ lsym := v .Aux .(* obj.LSym )
2478
+ if lsym .Extra == nil {
2479
+ return false
2480
+ }
2481
+ if ii , ok := (* lsym .Extra ).(* obj.ItabInfo ); ok {
2482
+ return types .IsDirectIface (ii .Type .(* types.Type ))
2483
+ }
2484
+ case OpConstNil :
2485
+ // We can treat this as direct, because if the itab is
2486
+ // nil, the data field must be nil also.
2487
+ return true
2488
+ }
2489
+ return false
2490
+ }
2491
+
2492
+ // v is an interface
2493
+ func isDirectIface2 (v * Value , depth int ) bool {
2494
+ if depth == 0 {
2495
+ return false
2496
+ }
2497
+ switch v .Op {
2498
+ case OpIMake :
2499
+ return isDirectIface1 (v .Args [0 ], depth - 1 )
2500
+ case OpPhi :
2501
+ for _ , a := range v .Args {
2502
+ if ! isDirectIface2 (a , depth - 1 ) {
2503
+ return false
2504
+ }
2505
+ }
2506
+ return true
2507
+ }
2508
+ return false
2509
+ }
0 commit comments