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:
parent
67aca9dfae
commit
9c6230e90e
2 changed files with 14 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Reference in a new issue