reflect: Fix MakeFunc for 386 when returning a struct.

When a 386 function returns a struct, it needs to return using
an rtd instruction that pops the hidden struct parameter off
the stack.  That wasn't happening.

From-SVN: r205551
This commit is contained in:
Ian Lance Taylor 2013-11-30 17:14:50 +00:00
parent 67aca9dfae
commit 9c6230e90e
2 changed files with 14 additions and 1 deletions

View file

@ -26,8 +26,11 @@ reflect.makeFuncStub:
esp uint32 // 0x0
eax uint32 // 0x4
st0 uint64 // 0x8
rs int32 // 0x10
}
*/
The rs field is set by the function to a non-zero value if
the function takes a struct hidden pointer that must be
popped off the stack. */
pushl %ebp
.LCFI0:
@ -73,12 +76,19 @@ reflect.makeFuncStub:
movsd -16(%ebp), %xmm0
#endif
movl -8(%ebp), %edx
addl $36, %esp
popl %ebx
.LCFI3:
popl %ebp
.LCFI4:
testl %edx,%edx
jne 1f
ret
1:
ret $4
.LFE1:
#ifdef __ELF__
.size reflect.makeFuncStub, . - reflect.makeFuncStub

View file

@ -16,6 +16,7 @@ type i386Regs struct {
esp uint32
eax uint32 // Value to return in %eax.
st0 uint64 // Value to return in %st(0).
sr int32 // Set to non-zero if hidden struct pointer.
}
// MakeFuncStubGo implements the 386 calling convention for MakeFunc.
@ -56,10 +57,12 @@ func MakeFuncStubGo(regs *i386Regs, c *makeFuncImpl) {
in := make([]Value, 0, len(ftyp.in))
ap := uintptr(regs.esp)
regs.sr = 0
var retPtr unsafe.Pointer
if retStruct {
retPtr = *(*unsafe.Pointer)(unsafe.Pointer(ap))
ap += ptrSize
regs.sr = 1
}
for _, rt := range ftyp.in {