github.com/tencent/goom@v1.0.1/internal/iface/make_method.go (about) 1 // Package iface 生成 interface 的实例对象, 通过 fake iface 结果获得 2 package iface 3 4 import ( 5 "unsafe" 6 7 "github.com/tencent/goom/internal/bytecode" 8 "github.com/tencent/goom/internal/bytecode/stub" 9 "github.com/tencent/goom/internal/logger" 10 ) 11 12 // interfaceJumpDataLen 默认接口跳转数据长度, 经验数值, 一般采用 icache line 长度(12)的倍数 13 const interfaceJumpDataLen = 48 14 15 // MakeMethodCaller 构造 interface 的方法调用并放到 stub 区 16 // to 桩函数跳转到的地址 17 func MakeMethodCaller(to unsafe.Pointer) (uintptr, error) { 18 space, err := stub.Acquire(interfaceJumpDataLen) 19 if err != nil { 20 return 0, err 21 } 22 23 code := jmpWithRdx(uintptr(to)) 24 if err := stub.Write(space, code); err != nil { 25 return 0, err 26 } 27 bytecode.PrintInst("gen stub", space.Addr, bytecode.PrintMiddle, logger.DebugLevel) 28 return space.Addr, nil 29 } 30 31 // MakeMethodCallerWithCtx 构造 interface 的方法调用并放到 stub 区 32 // ctx make Func 对象的上下文地址,即 @see reflect.makeFuncImpl 33 // to 桩函数最终跳转到另一个地址 34 func MakeMethodCallerWithCtx(ctx unsafe.Pointer, to uintptr) (uintptr, error) { 35 space, err := stub.Acquire(interfaceJumpDataLen) 36 if err != nil { 37 return 0, err 38 } 39 40 code := jmpWithRdx(uintptr(ctx)) 41 if err := stub.Write(space, code); err != nil { 42 return 0, err 43 } 44 45 bytecode.PrintInst("gen stub", space.Addr, bytecode.PrintLong, logger.DebugLevel) 46 bytecode.PrintInst("jump to", to, bytecode.PrintLong, logger.DebugLevel) 47 return space.Addr, nil 48 }