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  }