mirror of git://gcc.gnu.org/git/gcc.git
runtime: Handle FFI promoting result types.
From-SVN: r184123
This commit is contained in:
parent
edb7412e0e
commit
83a5c149a6
|
|
@ -5,6 +5,7 @@
|
||||||
license that can be found in the LICENSE file. */
|
license that can be found in the LICENSE file. */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "ffi.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;
|
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;
|
off = 0;
|
||||||
maxalign = 0;
|
maxalign = 0;
|
||||||
for (i = 0; i < count; ++i)
|
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;
|
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;
|
off = 0;
|
||||||
for (i = 0; i < count; ++i)
|
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;
|
ffi_cif cif;
|
||||||
unsigned char *call_result;
|
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);
|
go_func_to_cif (func_type, is_interface, is_method, &cif);
|
||||||
|
|
||||||
call_result = (unsigned char *) malloc (go_results_size (func_type));
|
call_result = (unsigned char *) malloc (go_results_size (func_type));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue