31 #if !defined(__x86_64__) || defined(_WIN64) || defined(__CYGWIN__) 49 register unsigned int i;
50 register void **p_argv;
52 register ffi_type **p_arg;
54 const int cabi = ecif->
cif->abi;
56 unsigned int stack_args_count = 0;
57 void *p_stack_data[3];
65 if ((ecif->
cif->flags == FFI_TYPE_STRUCT
68 && ((ecif->
cif->rtype->size & (1 | 2 | 4 | 8)) == 0)
77 p_stack_data[stack_args_count] = argp;
82 *(
void **) argp = ecif->
rvalue;
83 argp +=
sizeof(
void*);
86 p_arg = ecif->
cif->arg_types;
90 const int nargs = ecif->
cif->nargs - 1;
98 for (i = ecif->
cif->nargs;
100 i--, p_arg += dir, p_argv += dir)
105 if ((
sizeof(
void*) - 1) & (
size_t) argp)
106 argp = (
char *)
ALIGN(argp,
sizeof(
void*));
112 || ((*p_arg)->type == FFI_TYPE_STRUCT
113 && (z & (1 | 2 | 4 | 8)) == 0)
120 *(
void **)argp = *p_argv;
122 else if ((*p_arg)->type == FFI_TYPE_FLOAT)
131 switch ((*p_arg)->type)
141 case FFI_TYPE_SINT16:
145 case FFI_TYPE_UINT16:
149 case FFI_TYPE_SINT32:
153 case FFI_TYPE_UINT32:
157 case FFI_TYPE_STRUCT:
178 && ((*p_arg)->type != FFI_TYPE_FLOAT && (*p_arg)->type != FFI_TYPE_STRUCT)
181 if (dir < 0 && stack_args_count > 2)
185 p_stack_data[0] = p_stack_data[1];
186 p_stack_data[1] = p_stack_data[2];
187 stack_args_count = 2;
190 p_stack_data[stack_args_count] = argp;
196 argp += (z +
sizeof(
void*) - 1) & ~(
sizeof(
void*) - 1);
205 if (stack_args_count > 0)
208 if (dir < 0 && stack_args_count > 1)
212 *(
ffi_arg*) p_stack_data[0] = *(
ffi_arg*) p_stack_data[stack_args_count - 1];
213 *(
ffi_arg*) p_stack_data[stack_args_count - 1] = tmp;
216 for (i = 0; i < stack_args_count; i++)
218 if (p_stack_data[i] != argp2)
229 return stack_args_count;
241 switch (cif->rtype->type)
245 case FFI_TYPE_UINT16:
247 case FFI_TYPE_SINT16:
249 case FFI_TYPE_UINT32:
250 case FFI_TYPE_SINT32:
252 case FFI_TYPE_SINT64:
254 case FFI_TYPE_DOUBLE:
256 #if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE 260 cif->flags = (unsigned) cif->rtype->type;
263 case FFI_TYPE_UINT64:
265 case FFI_TYPE_POINTER:
267 cif->flags = FFI_TYPE_SINT64;
270 case FFI_TYPE_STRUCT:
272 if (cif->rtype->size == 1)
276 else if (cif->rtype->size == 2)
280 else if (cif->rtype->size == 4)
285 cif->flags = FFI_TYPE_INT;
288 else if (cif->rtype->size == 8)
290 cif->flags = FFI_TYPE_SINT64;
296 if (cif->abi == FFI_MS_CDECL)
300 cif->flags = FFI_TYPE_STRUCT;
308 cif->flags = FFI_TYPE_SINT64;
311 cif->flags = FFI_TYPE_SINT32;
313 cif->flags = FFI_TYPE_INT;
318 for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
320 if (((*ptr)->alignment - 1) & cif->bytes)
321 cif->bytes =
ALIGN(cif->bytes, (*ptr)->alignment);
334 cif->bytes = (cif->bytes + 15) & ~0xF;
343 unsigned,
unsigned,
unsigned *,
void (*fn)(
void));
347 unsigned,
unsigned,
unsigned,
unsigned *,
void (*fn)(
void));
349 unsigned,
unsigned,
unsigned *,
void (*fn)(
void));
352 void ffi_call(ffi_cif *cif,
void (*fn)(
void),
void *rvalue,
void **avalue)
364 && cif->flags == FFI_TYPE_STRUCT
365 && ((cif->rtype->size & (1 | 2 | 4 | 8)) == 0))
371 && (cif->flags == FFI_TYPE_STRUCT
386 cif->flags, ecif.
rvalue, fn);
419 void** args, ffi_cif* cif);
424 unsigned int FFI_HIDDEN ffi_closure_WIN32_inner (ffi_closure *,
void **,
void *)
426 void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
429 void FFI_HIDDEN ffi_closure_raw_THISCALL (ffi_raw_closure *)
433 void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *);
434 void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *);
435 void FFI_HIDDEN ffi_closure_FASTCALL (ffi_closure *);
436 void FFI_HIDDEN ffi_closure_REGISTER (ffi_closure *);
438 void FFI_HIDDEN ffi_closure_win64 (ffi_closure *);
445 ffi_closure_win64_inner (ffi_closure *closure,
void *args) {
452 arg_area = (
void**)
alloca (cif->nargs * sizeof (
void*));
462 (closure->fun) (cif, resp, arg_area, closure->user_data);
469 return cif->rtype->size >
sizeof(
void *) ? resp : *(
void **)resp;
481 arg_area = (
void**)
alloca (cif->nargs * sizeof (
void*));
491 (closure->fun) (cif, *respp, arg_area, closure->user_data);
497 ffi_closure_WIN32_inner (ffi_closure *closure,
void **respp,
void *args)
505 arg_area = (
void**)
alloca (cif->nargs * sizeof (
void*));
515 (closure->fun) (cif, *respp, arg_area, closure->user_data);
525 register unsigned int i;
526 register void **p_argv;
528 register ffi_type **p_arg;
530 const int cabi = cif->abi;
532 const unsigned int max_stack_count = (cabi ==
FFI_THISCALL) ? 1
536 unsigned int passed_regs = 0;
537 void *p_stack_data[3] = { stack - 1 };
547 if ((cif->flags == FFI_TYPE_STRUCT
550 && ((cif->rtype->size & (1 | 2 | 4 | 8)) == 0)
555 if (passed_regs < max_stack_count)
557 *rvalue = *(
void**) (stack + (passed_regs*FFI_SIZEOF_ARG));
563 *rvalue = *(
void **) argp;
564 argp +=
sizeof(
void *);
570 for (i = 0, p_arg = cif->arg_types;
571 i < cif->nargs && passed_regs < max_stack_count;
575 if ((*p_arg)->type == FFI_TYPE_FLOAT
576 || (*p_arg)->type == FFI_TYPE_STRUCT)
580 if(sz == 0 || sz > FFI_SIZEOF_ARG)
583 p_stack_data[passed_regs] = avalue + i;
589 p_arg = cif->arg_types;
593 const int nargs = cif->nargs - 1;
603 i--, p_arg += dir, p_argv += dir)
608 if ((
sizeof(
void*) - 1) & (
size_t) argp)
609 argp = (
char *)
ALIGN(argp,
sizeof(
void*));
614 if (z > FFI_SIZEOF_ARG
615 || ((*p_arg)->type == FFI_TYPE_STRUCT
616 && (z & (1 | 2 | 4 | 8)) == 0)
623 *p_argv = *(
void **)argp;
628 && z <= FFI_SIZEOF_ARG
629 && (p_argv == p_stack_data[0]
630 || p_argv == p_stack_data[1]
631 || p_argv == p_stack_data[2]))
640 *p_argv = (
void*) argp;
644 argp += (z +
sizeof(
void*) - 1) & ~(
sizeof(
void*) - 1);
650 return (
int)((size_t)argp - (
size_t)stack);
653 #define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \ 654 { unsigned char *__tramp = (unsigned char*)(TRAMP); \ 655 void* __fun = (void*)(FUN); \ 656 void* __ctx = (void*)(CTX); \ 657 *(unsigned char*) &__tramp[0] = 0x41; \ 658 *(unsigned char*) &__tramp[1] = 0xbb; \ 659 *(unsigned int*) &__tramp[2] = MASK; \ 660 *(unsigned char*) &__tramp[6] = 0x48; \ 661 *(unsigned char*) &__tramp[7] = 0xb8; \ 662 *(void**) &__tramp[8] = __ctx; \ 663 *(unsigned char *) &__tramp[16] = 0x49; \ 664 *(unsigned char *) &__tramp[17] = 0xba; \ 665 *(void**) &__tramp[18] = __fun; \ 666 *(unsigned char *) &__tramp[26] = 0x41; \ 667 *(unsigned char *) &__tramp[27] = 0xff; \ 668 *(unsigned char *) &__tramp[28] = 0xe2; \ 673 #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ 674 { unsigned char *__tramp = (unsigned char*)(TRAMP); \ 675 unsigned int __fun = (unsigned int)(FUN); \ 676 unsigned int __ctx = (unsigned int)(CTX); \ 677 unsigned int __dis = __fun - (__ctx + 10); \ 678 *(unsigned char*) &__tramp[0] = 0xb8; \ 679 *(unsigned int*) &__tramp[1] = __ctx; \ 680 *(unsigned char*) &__tramp[5] = 0xe9; \ 681 *(unsigned int*) &__tramp[6] = __dis; \ 684 #define FFI_INIT_TRAMPOLINE_RAW_THISCALL(TRAMP,FUN,CTX,SIZE) \ 685 { unsigned char *__tramp = (unsigned char*)(TRAMP); \ 686 unsigned int __fun = (unsigned int)(FUN); \ 687 unsigned int __ctx = (unsigned int)(CTX); \ 688 unsigned int __dis = __fun - (__ctx + 49); \ 689 unsigned short __size = (unsigned short)(SIZE); \ 690 *(unsigned int *) &__tramp[0] = 0x8324048b; \ 691 *(unsigned int *) &__tramp[4] = 0x4c890cec; \ 692 *(unsigned int *) &__tramp[8] = 0x04890424; \ 693 *(unsigned char*) &__tramp[12] = 0x24; \ 694 *(unsigned char*) &__tramp[13] = 0xb8; \ 695 *(unsigned int *) &__tramp[14] = __size; \ 696 *(unsigned int *) &__tramp[18] = 0x08244c8d; \ 697 *(unsigned int *) &__tramp[22] = 0x4802e8c1; \ 698 *(unsigned short*) &__tramp[26] = 0x0b74; \ 699 *(unsigned int *) &__tramp[28] = 0x8908518b; \ 700 *(unsigned int *) &__tramp[32] = 0x04c18311; \ 701 *(unsigned char*) &__tramp[36] = 0x48; \ 702 *(unsigned short*) &__tramp[37] = 0xf575; \ 703 *(unsigned char*) &__tramp[39] = 0xb8; \ 704 *(unsigned int*) &__tramp[40] = __ctx; \ 705 *(unsigned char *) &__tramp[44] = 0xe8; \ 706 *(unsigned int*) &__tramp[45] = __dis; \ 707 *(unsigned char*) &__tramp[49] = 0xc2; \ 708 *(unsigned short*) &__tramp[50] = (__size + 8); \ 711 #define FFI_INIT_TRAMPOLINE_WIN32(TRAMP,FUN,CTX) \ 712 { unsigned char *__tramp = (unsigned char*)(TRAMP); \ 713 unsigned int __fun = (unsigned int)(FUN); \ 714 unsigned int __ctx = (unsigned int)(CTX); \ 715 unsigned int __dis = __fun - (__ctx + 10); \ 716 *(unsigned char*) &__tramp[0] = 0x68; \ 717 *(unsigned int*) &__tramp[1] = __ctx; \ 718 *(unsigned char*) &__tramp[5] = 0xe9; \ 719 *(unsigned int*) &__tramp[6] = __dis; \ 727 void (*fun)(ffi_cif*,
void*,
void**,
void*),
732 #define ISFLOAT(IDX) (cif->arg_types[IDX]->type == FFI_TYPE_FLOAT || cif->arg_types[IDX]->type == FFI_TYPE_DOUBLE) 733 #define FLAG(IDX) (cif->nargs>(IDX)&&ISFLOAT(IDX)?(1<<(IDX)):0) 734 if (cif->abi == FFI_WIN64)
736 int mask = FLAG(0)|FLAG(1)|FLAG(2)|FLAG(3);
752 &ffi_closure_REGISTER,
758 &ffi_closure_FASTCALL,
764 &ffi_closure_THISCALL,
770 &ffi_closure_STDCALL,
774 else if (cif->abi == FFI_MS_CDECL)
788 closure->user_data = user_data;
801 void (*fun)(ffi_cif*,
void*,ffi_raw*,
void*),
819 for (i = cif->nargs-1; i >= 0; i--)
821 FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
839 closure->user_data = user_data;
848 const ffi_cif *cif = ecif->
cif;
849 unsigned int i, passed_regs = 0;
852 const unsigned int abi = cif->abi;
858 if (cif->flags == FFI_TYPE_STRUCT)
861 for (i = 0; i < cif->nargs && passed_regs <= max_regs; i++)
864 if (cif->arg_types[i]->type == FFI_TYPE_FLOAT
865 || cif->arg_types[i]->type == FFI_TYPE_STRUCT)
868 sz = cif->arg_types[i]->size;
886 ffi_raw_call(ffi_cif *cif,
void (*fn)(
void),
void *rvalue, ffi_raw *fake_avalue)
889 void **avalue = (
void **)fake_avalue;
898 && (cif->flags == FFI_TYPE_STRUCT
ffi_status ffi_prep_raw_closure_loc(ffi_raw_closure *closure, ffi_cif *cif, void(*fun)(ffi_cif *, void *, ffi_raw *, void *), void *user_data, void *codeloc)
#define FFI_INIT_TRAMPOLINE_WIN32(TRAMP, FUN, CTX)
void FFI_HIDDEN ffi_closure_SYSV_inner(ffi_closure *closure, struct call_context *context, void *stack)
#define FFI_INIT_TRAMPOLINE(TRAMP, FUN, CTX)
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
void *PTR64 __attribute__((mode(DI)))
#define FFI_INIT_TRAMPOLINE_RAW_THISCALL(TRAMP, FUN, CTX, SIZE)
void ffi_call_SYSV(unsigned(*)(struct call_context *context, unsigned char *, extended_cif *), struct call_context *context, extended_cif *, size_t, void(*fn)(void))
RUBY_EXTERN void * memmove(void *, const void *, size_t)
void ffi_raw_call(ffi_cif *cif, void(*fn)(void), void *rvalue, ffi_raw *fake_avalue)
static unsigned int ffi_prep_args_raw(char *stack, extended_cif *ecif)
#define FFI_TYPE_SMALL_STRUCT_1B
#define FFI_TYPE_LONGDOUBLE
ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void(*fun)(ffi_cif *, void *, void **, void *), void *user_data, void *codeloc)
#define FFI_TYPE_MS_STRUCT
void ffi_call(ffi_cif *cif, void(*fn)(void), void *rvalue, void **avalue)
#define FFI_INIT_TRAMPOLINE_WIN64(TRAMP, FUN, CTX, MASK)
#define FFI_TYPE_SMALL_STRUCT_2B
const UINT64 ffi_template_tramp_tile [] FFI_HIDDEN
#define FFI_TYPE_SMALL_STRUCT_4B
static unsigned int ffi_prep_incoming_args(char *stack, void **ret, void **args, ffi_cif *cif)
private members
void ffi_call_win32(unsigned int(*)(char *, extended_cif *), extended_cif *, unsigned, unsigned, unsigned, unsigned *, void(*fn)(void))
void ffi_prep_args(char *stack, extended_cif *ecif)
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
void ffi_closure_SYSV(ffi_closure *)