(fn reflect.Type, method bool)
| 49 | } |
| 50 | |
| 51 | func TypedFuncIndex(fn reflect.Type, method bool) (int, bool) { |
| 52 | if fn == nil { |
| 53 | return 0, false |
| 54 | } |
| 55 | if fn.Kind() != reflect.Func { |
| 56 | return 0, false |
| 57 | } |
| 58 | // OnCallTyped doesn't work for functions with variadic arguments. |
| 59 | if fn.IsVariadic() { |
| 60 | return 0, false |
| 61 | } |
| 62 | // OnCallTyped doesn't work named function, like `type MyFunc func() int`. |
| 63 | if fn.PkgPath() != "" { // If PkgPath() is not empty, it means that function is named. |
| 64 | return 0, false |
| 65 | } |
| 66 | |
| 67 | fnNumIn := fn.NumIn() |
| 68 | fnInOffset := 0 |
| 69 | if method { |
| 70 | fnNumIn-- |
| 71 | fnInOffset = 1 |
| 72 | } |
| 73 | |
| 74 | funcTypes: |
| 75 | for i := range vm.FuncTypes { |
| 76 | if i == 0 { |
| 77 | continue |
| 78 | } |
| 79 | typed := reflect.ValueOf(vm.FuncTypes[i]).Elem().Type() |
| 80 | if typed.Kind() != reflect.Func { |
| 81 | continue |
| 82 | } |
| 83 | if typed.NumOut() != fn.NumOut() { |
| 84 | continue |
| 85 | } |
| 86 | for j := 0; j < typed.NumOut(); j++ { |
| 87 | if typed.Out(j) != fn.Out(j) { |
| 88 | continue funcTypes |
| 89 | } |
| 90 | } |
| 91 | if typed.NumIn() != fnNumIn { |
| 92 | continue |
| 93 | } |
| 94 | for j := 0; j < typed.NumIn(); j++ { |
| 95 | if typed.In(j) != fn.In(j+fnInOffset) { |
| 96 | continue funcTypes |
| 97 | } |
| 98 | } |
| 99 | return i, true |
| 100 | } |
| 101 | return 0, false |
| 102 | } |
| 103 | |
| 104 | func IsFastFunc(fn reflect.Type, method bool) bool { |
| 105 | if fn == nil { |
searching dependent graphs…