runtime: Handle FFI promoting result types.
From-SVN: r184123
This commit is contained in:
parent
edb7412e0e
commit
83a5c149a6
1 changed files with 99 additions and 1 deletions
|
@ -5,6 +5,7 @@
|
|||
license that can be found in the LICENSE file. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "ffi.h"
|
||||
|
@ -326,6 +327,28 @@ go_results_size (const struct __go_func_type *func)
|
|||
|
||||
types = (const struct __go_type_descriptor **) func->__out.__values;
|
||||
|
||||
/* A single integer return value is always promoted to a full
|
||||
word. */
|
||||
if (count == 1)
|
||||
{
|
||||
switch (types[0]->__code & GO_CODE_MASK)
|
||||
{
|
||||
case GO_BOOL:
|
||||
case GO_INT8:
|
||||
case GO_INT16:
|
||||
case GO_INT32:
|
||||
case GO_UINT8:
|
||||
case GO_UINT16:
|
||||
case GO_UINT32:
|
||||
case GO_INT:
|
||||
case GO_UINT:
|
||||
return sizeof (ffi_arg);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
off = 0;
|
||||
maxalign = 0;
|
||||
for (i = 0; i < count; ++i)
|
||||
|
@ -362,6 +385,81 @@ go_set_results (const struct __go_func_type *func, unsigned char *call_result,
|
|||
|
||||
types = (const struct __go_type_descriptor **) func->__out.__values;
|
||||
|
||||
/* A single integer return value is always promoted to a full
|
||||
word. */
|
||||
if (count == 1)
|
||||
{
|
||||
switch (types[0]->__code & GO_CODE_MASK)
|
||||
{
|
||||
case GO_BOOL:
|
||||
case GO_INT8:
|
||||
case GO_INT16:
|
||||
case GO_INT32:
|
||||
case GO_UINT8:
|
||||
case GO_UINT16:
|
||||
case GO_UINT32:
|
||||
case GO_INT:
|
||||
case GO_UINT:
|
||||
{
|
||||
union
|
||||
{
|
||||
unsigned char buf[sizeof (ffi_arg)];
|
||||
ffi_arg v;
|
||||
} u;
|
||||
ffi_arg v;
|
||||
|
||||
__builtin_memcpy (&u.buf, call_result, sizeof (ffi_arg));
|
||||
v = u.v;
|
||||
|
||||
switch (types[0]->__size)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
uint8_t b;
|
||||
|
||||
b = (uint8_t) v;
|
||||
__builtin_memcpy (results[0], &b, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
uint16_t s;
|
||||
|
||||
s = (uint16_t) v;
|
||||
__builtin_memcpy (results[0], &s, 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
{
|
||||
uint32_t w;
|
||||
|
||||
w = (uint32_t) v;
|
||||
__builtin_memcpy (results[0], &w, 4);
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
{
|
||||
uint64_t d;
|
||||
|
||||
d = (uint64_t) v;
|
||||
__builtin_memcpy (results[0], &d, 8);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
off = 0;
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
|
@ -388,7 +486,7 @@ reflect_call (const struct __go_func_type *func_type, const void *func_addr,
|
|||
ffi_cif cif;
|
||||
unsigned char *call_result;
|
||||
|
||||
__go_assert (func_type->__common.__code == GO_FUNC);
|
||||
__go_assert ((func_type->__common.__code & GO_CODE_MASK) == GO_FUNC);
|
||||
go_func_to_cif (func_type, is_interface, is_method, &cif);
|
||||
|
||||
call_result = (unsigned char *) malloc (go_results_size (func_type));
|
||||
|
|
Loading…
Add table
Reference in a new issue