aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/syscall_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/syscall_windows.go')
-rw-r--r--src/runtime/syscall_windows.go23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go
index 6b9195bcd5..4763a440e7 100644
--- a/src/runtime/syscall_windows.go
+++ b/src/runtime/syscall_windows.go
@@ -64,6 +64,7 @@ type abiDesc struct {
srcStackSize uintptr // stdcall/fastcall stack space tracking
dstStackSize uintptr // Go stack space used
+ dstSpill uintptr // Extra stack space for argument spill slots
dstRegisters int // Go ABI int argument registers used
// retOffset is the offset of the uintptr-sized result in the Go
@@ -110,7 +111,14 @@ func (p *abiDesc) assignArg(t *_type) {
// arguments. The same is true on arm.
oldParts := p.parts
- if !p.tryRegAssignArg(t, 0) {
+ if p.tryRegAssignArg(t, 0) {
+ // Account for spill space.
+ //
+ // TODO(mknyszek): Remove this when we no longer have
+ // caller reserved spill space.
+ p.dstSpill = alignUp(p.dstSpill, uintptr(t.align))
+ p.dstSpill += t.size
+ } else {
// Register assignment failed.
// Undo the work and stack assign.
p.parts = oldParts
@@ -277,7 +285,11 @@ func compileCallback(fn eface, cdecl bool) (code uintptr) {
abiMap.dstStackSize += sys.PtrSize
}
- if abiMap.dstStackSize > callbackMaxFrame {
+ // TODO(mknyszek): Remove dstSpill from this calculation when we no longer have
+ // caller reserved spill space.
+ frameSize := alignUp(abiMap.dstStackSize, sys.PtrSize)
+ frameSize += abiMap.dstSpill
+ if frameSize > callbackMaxFrame {
panic("compileCallback: function argument frame too large")
}
@@ -356,9 +368,14 @@ func callbackWrap(a *callbackArgs) {
}
}
+ // TODO(mknyszek): Remove this when we no longer have
+ // caller reserved spill space.
+ frameSize := alignUp(c.abiMap.dstStackSize, sys.PtrSize)
+ frameSize += c.abiMap.dstSpill
+
// Even though this is copying back results, we can pass a nil
// type because those results must not require write barriers.
- reflectcall(nil, unsafe.Pointer(c.fn), noescape(goArgs), uint32(c.abiMap.dstStackSize), uint32(c.abiMap.retOffset), uint32(c.abiMap.dstStackSize), &regs)
+ reflectcall(nil, unsafe.Pointer(c.fn), noescape(goArgs), uint32(c.abiMap.dstStackSize), uint32(c.abiMap.retOffset), uint32(frameSize), &regs)
// Extract the result.
//