// OpCallIndirect using table index located in result register. func (mach X86) OpCallIndirect(code gen.Coder, tableLen, sigIndex int32) int32 { var outOfBounds links.L var checksOut links.L mach.opCompareBounds(code, regResult, tableLen) Jle.rel8.opStub(code) // TODO: is this the correct comparison? outOfBounds.AddSite(code.Len()) Mov.opFromAddr(code, types.I64, regResult, 3, regResult, code.RODataAddr()+gen.ROTableAddr) Mov.opFromReg(code, types.I32, regScratch, regResult) // zero-extended function address ShrImm.op(code, types.I64, regResult, 32) // signature index Cmp.opImm(code, types.I32, regResult, sigIndex) Je.rel8.opStub(code) checksOut.AddSite(code.Len()) code.OpTrapCall(traps.IndirectCallSignature) outOfBounds.Addr = code.Len() mach.updateBranches8(code, &outOfBounds) code.OpTrapCall(traps.IndirectCallIndex) checksOut.Addr = code.Len() mach.updateBranches8(code, &checksOut) Add.opFromReg(code, types.I64, regScratch, regTextBase) Call.opReg(code, regScratch) return code.Len() }
func (mach X86) OpTrapIfStackExhausted(code gen.Coder) (stackCheckAddr int32) { var checked links.L Lea.opFromStack(code, types.I64, regScratch, -0x80000000) // reserve 32-bit displacement stackCheckAddr = code.Len() Cmp.opFromReg(code, types.I64, regScratch, regStackLimit) Jge.rel8.opStub(code) checked.AddSite(code.Len()) code.OpTrapCall(traps.CallStackExhausted) checked.Addr = code.Len() mach.updateBranches8(code, &checked) return }