ffi 1.9.21 → 1.9.22
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ffi might be problematic. Click here for more details.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +22 -0
- data/.gitmodules +3 -0
- data/.travis.yml +52 -0
- data/.yardopts +5 -0
- data/Gemfile +15 -0
- data/{spec/ffi/LICENSE.SPECS → LICENSE.SPECS} +1 -1
- data/README.md +1 -1
- data/Rakefile +28 -3
- data/appveyor.yml +22 -0
- data/ext/ffi_c/Call.c +1 -22
- data/ext/ffi_c/Call.h +0 -9
- data/ext/ffi_c/Closure.c +54 -0
- data/ext/ffi_c/{ClosurePool.h → Closure.h} +13 -23
- data/ext/ffi_c/Function.c +16 -25
- data/ext/ffi_c/Function.h +1 -2
- data/ext/ffi_c/FunctionInfo.c +0 -4
- data/ext/ffi_c/MethodHandle.c +33 -268
- data/ext/ffi_c/extconf.rb +3 -3
- data/ext/ffi_c/ffi.c +2 -2
- data/ext/ffi_c/libffi.bsd.mk +3 -3
- data/ext/ffi_c/libffi.darwin.mk +1 -1
- data/ext/ffi_c/libffi.gnu.mk +1 -1
- data/ext/ffi_c/libffi.mk +2 -2
- data/ext/ffi_c/libffi.vc.mk +1 -1
- data/ext/ffi_c/libffi.vc64.mk +1 -1
- data/ext/ffi_c/libffi/.appveyor.yml +48 -0
- data/ext/ffi_c/libffi/.gitignore +36 -0
- data/ext/ffi_c/libffi/.travis.yml +30 -0
- data/ext/ffi_c/libffi/.travis/install.sh +14 -0
- data/ext/ffi_c/libffi/Makefile.am +5 -3
- data/ext/ffi_c/libffi/acinclude.m4 +6 -0
- data/ext/ffi_c/libffi/autogen.sh +1 -1
- data/ext/ffi_c/libffi/config.guess +1466 -0
- data/ext/ffi_c/libffi/config.sub +1836 -0
- data/ext/ffi_c/libffi/configure.ac +2 -2
- data/ext/ffi_c/libffi/configure.host +15 -3
- data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +11 -15
- data/ext/ffi_c/libffi/include/ffi.h.in +6 -1
- data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +465 -59
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +33 -10
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +2 -2
- data/ext/ffi_c/libffi/src/arm/ffi.c +12 -1
- data/ext/ffi_c/libffi/src/arm/sysv.S +1 -1
- data/ext/ffi_c/libffi/src/closures.c +143 -97
- data/ext/ffi_c/libffi/src/ia64/unix.S +2 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +8 -0
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
- data/ext/ffi_c/libffi/src/mips/n32.S +2 -0
- data/ext/ffi_c/libffi/src/powerpc/aix.S +239 -1
- data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +250 -3
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +86 -5
- data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +3 -0
- data/ext/ffi_c/libffi/src/x86/ffi.c +3 -1
- data/ext/ffi_c/libffi/src/x86/ffi64.c +26 -5
- data/ext/ffi_c/libffi/src/x86/sysv.S +2 -2
- data/ext/ffi_c/libffi/src/x86/unix64.S +1 -1
- data/ext/ffi_c/libffi/src/x86/win64.S +1 -1
- data/ext/ffi_c/libffi/testsuite/Makefile.am +2 -1
- data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +2 -1
- data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3float.c +95 -0
- data/ffi.gemspec +14 -1
- data/lib/ffi/library.rb +1 -1
- data/lib/ffi/version.rb +1 -1
- data/samples/getlogin.rb +8 -0
- data/samples/getpid.rb +8 -0
- data/samples/gettimeofday.rb +18 -0
- data/samples/hello.rb +7 -0
- data/samples/inotify.rb +60 -0
- data/samples/pty.rb +76 -0
- data/samples/qsort.rb +21 -0
- data/samples/sample_helper.rb +6 -0
- metadata +59 -81
- metadata.gz.sig +0 -0
- data/ext/ffi_c/ClosurePool.c +0 -283
- data/gen/Rakefile +0 -30
- data/libtest/Benchmark.c +0 -52
- data/libtest/BoolTest.c +0 -34
- data/libtest/BufferTest.c +0 -31
- data/libtest/ClosureTest.c +0 -205
- data/libtest/EnumTest.c +0 -51
- data/libtest/FunctionTest.c +0 -70
- data/libtest/GNUmakefile +0 -149
- data/libtest/GlobalVariable.c +0 -62
- data/libtest/LastErrorTest.c +0 -21
- data/libtest/NumberTest.c +0 -132
- data/libtest/PointerTest.c +0 -63
- data/libtest/ReferenceTest.c +0 -23
- data/libtest/StringTest.c +0 -34
- data/libtest/StructTest.c +0 -243
- data/libtest/UnionTest.c +0 -43
- data/libtest/VariadicTest.c +0 -99
- data/spec/ffi/async_callback_spec.rb +0 -35
- data/spec/ffi/bitmask_spec.rb +0 -575
- data/spec/ffi/bool_spec.rb +0 -32
- data/spec/ffi/buffer_spec.rb +0 -279
- data/spec/ffi/callback_spec.rb +0 -773
- data/spec/ffi/custom_param_type.rb +0 -37
- data/spec/ffi/custom_type_spec.rb +0 -74
- data/spec/ffi/dup_spec.rb +0 -52
- data/spec/ffi/enum_spec.rb +0 -423
- data/spec/ffi/errno_spec.rb +0 -20
- data/spec/ffi/ffi_spec.rb +0 -28
- data/spec/ffi/fixtures/Benchmark.c +0 -52
- data/spec/ffi/fixtures/BitmaskTest.c +0 -51
- data/spec/ffi/fixtures/BoolTest.c +0 -34
- data/spec/ffi/fixtures/BufferTest.c +0 -31
- data/spec/ffi/fixtures/ClosureTest.c +0 -205
- data/spec/ffi/fixtures/EnumTest.c +0 -51
- data/spec/ffi/fixtures/FunctionTest.c +0 -142
- data/spec/ffi/fixtures/GNUmakefile +0 -149
- data/spec/ffi/fixtures/GlobalVariable.c +0 -62
- data/spec/ffi/fixtures/LastErrorTest.c +0 -21
- data/spec/ffi/fixtures/NumberTest.c +0 -132
- data/spec/ffi/fixtures/PipeHelper.h +0 -21
- data/spec/ffi/fixtures/PipeHelperPosix.c +0 -41
- data/spec/ffi/fixtures/PipeHelperWindows.c +0 -72
- data/spec/ffi/fixtures/PointerTest.c +0 -63
- data/spec/ffi/fixtures/ReferenceTest.c +0 -23
- data/spec/ffi/fixtures/StringTest.c +0 -34
- data/spec/ffi/fixtures/StructTest.c +0 -243
- data/spec/ffi/fixtures/UnionTest.c +0 -43
- data/spec/ffi/fixtures/VariadicTest.c +0 -99
- data/spec/ffi/fixtures/classes.rb +0 -438
- data/spec/ffi/function_spec.rb +0 -97
- data/spec/ffi/io_spec.rb +0 -16
- data/spec/ffi/library_spec.rb +0 -286
- data/spec/ffi/long_double.rb +0 -30
- data/spec/ffi/managed_struct_spec.rb +0 -68
- data/spec/ffi/memorypointer_spec.rb +0 -78
- data/spec/ffi/number_spec.rb +0 -247
- data/spec/ffi/platform_spec.rb +0 -114
- data/spec/ffi/pointer_spec.rb +0 -285
- data/spec/ffi/rbx/attach_function_spec.rb +0 -34
- data/spec/ffi/rbx/memory_pointer_spec.rb +0 -198
- data/spec/ffi/rbx/spec_helper.rb +0 -6
- data/spec/ffi/rbx/struct_spec.rb +0 -18
- data/spec/ffi/spec_helper.rb +0 -93
- data/spec/ffi/string_spec.rb +0 -118
- data/spec/ffi/strptr_spec.rb +0 -50
- data/spec/ffi/struct_by_ref_spec.rb +0 -43
- data/spec/ffi/struct_callback_spec.rb +0 -69
- data/spec/ffi/struct_initialize_spec.rb +0 -35
- data/spec/ffi/struct_packed_spec.rb +0 -50
- data/spec/ffi/struct_spec.rb +0 -882
- data/spec/ffi/typedef_spec.rb +0 -91
- data/spec/ffi/union_spec.rb +0 -67
- data/spec/ffi/variadic_spec.rb +0 -132
- data/spec/spec.opts +0 -4
@@ -33,6 +33,7 @@
|
|
33
33
|
#include <stdlib.h>
|
34
34
|
|
35
35
|
extern void ffi_closure_ASM (void);
|
36
|
+
extern void ffi_go_closure_ASM (void);
|
36
37
|
|
37
38
|
enum {
|
38
39
|
/* The assembly depends on these exact flags.
|
@@ -908,6 +909,9 @@ ffi_prep_cif_machdep (ffi_cif *cif)
|
|
908
909
|
extern void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *,
|
909
910
|
void (*fn)(void), void (*fn2)(void));
|
910
911
|
|
912
|
+
extern void ffi_call_go_AIX(extended_cif *, long, unsigned, unsigned *,
|
913
|
+
void (*fn)(void), void (*fn2)(void), void *closure);
|
914
|
+
|
911
915
|
extern void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *,
|
912
916
|
void (*fn)(void), void (*fn2)(void), ffi_type*);
|
913
917
|
|
@@ -946,6 +950,38 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
|
946
950
|
}
|
947
951
|
}
|
948
952
|
|
953
|
+
void
|
954
|
+
ffi_call_go (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue,
|
955
|
+
void *closure)
|
956
|
+
{
|
957
|
+
extended_cif ecif;
|
958
|
+
|
959
|
+
ecif.cif = cif;
|
960
|
+
ecif.avalue = avalue;
|
961
|
+
|
962
|
+
/* If the return value is a struct and we don't have a return
|
963
|
+
value address then we need to make one. */
|
964
|
+
|
965
|
+
if ((rvalue == NULL) &&
|
966
|
+
(cif->rtype->type == FFI_TYPE_STRUCT))
|
967
|
+
{
|
968
|
+
ecif.rvalue = alloca (cif->rtype->size);
|
969
|
+
}
|
970
|
+
else
|
971
|
+
ecif.rvalue = rvalue;
|
972
|
+
|
973
|
+
switch (cif->abi)
|
974
|
+
{
|
975
|
+
case FFI_AIX:
|
976
|
+
ffi_call_go_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
|
977
|
+
FFI_FN(ffi_prep_args), closure);
|
978
|
+
break;
|
979
|
+
default:
|
980
|
+
FFI_ASSERT(0);
|
981
|
+
break;
|
982
|
+
}
|
983
|
+
}
|
984
|
+
|
949
985
|
static void flush_icache(char *);
|
950
986
|
static void flush_range(char *, int);
|
951
987
|
|
@@ -1074,6 +1110,30 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
|
1074
1110
|
return FFI_OK;
|
1075
1111
|
}
|
1076
1112
|
|
1113
|
+
ffi_status
|
1114
|
+
ffi_prep_go_closure (ffi_go_closure* closure,
|
1115
|
+
ffi_cif* cif,
|
1116
|
+
void (*fun)(ffi_cif*, void*, void**, void*))
|
1117
|
+
{
|
1118
|
+
switch (cif->abi)
|
1119
|
+
{
|
1120
|
+
case FFI_AIX:
|
1121
|
+
|
1122
|
+
FFI_ASSERT (cif->abi == FFI_AIX);
|
1123
|
+
|
1124
|
+
closure->tramp = (void *)ffi_go_closure_ASM;
|
1125
|
+
closure->cif = cif;
|
1126
|
+
closure->fun = fun;
|
1127
|
+
return FFI_OK;
|
1128
|
+
|
1129
|
+
// For now, ffi_prep_go_closure is only implemented for AIX, not for Darwin
|
1130
|
+
default:
|
1131
|
+
return FFI_BAD_ABI;
|
1132
|
+
break;
|
1133
|
+
}
|
1134
|
+
return FFI_OK;
|
1135
|
+
}
|
1136
|
+
|
1077
1137
|
static void
|
1078
1138
|
flush_icache(char *addr)
|
1079
1139
|
{
|
@@ -1108,6 +1168,10 @@ ffi_type *
|
|
1108
1168
|
ffi_closure_helper_DARWIN (ffi_closure *, void *,
|
1109
1169
|
unsigned long *, ffi_dblfl *);
|
1110
1170
|
|
1171
|
+
ffi_type *
|
1172
|
+
ffi_go_closure_helper_DARWIN (ffi_go_closure*, void *,
|
1173
|
+
unsigned long *, ffi_dblfl *);
|
1174
|
+
|
1111
1175
|
/* Basically the trampoline invokes ffi_closure_ASM, and on
|
1112
1176
|
entry, r11 holds the address of the closure.
|
1113
1177
|
After storing the registers that could possibly contain
|
@@ -1115,8 +1179,10 @@ ffi_closure_helper_DARWIN (ffi_closure *, void *,
|
|
1115
1179
|
up space for a return value, ffi_closure_ASM invokes the
|
1116
1180
|
following helper function to do most of the work. */
|
1117
1181
|
|
1118
|
-
ffi_type *
|
1119
|
-
|
1182
|
+
static ffi_type *
|
1183
|
+
ffi_closure_helper_common (ffi_cif* cif,
|
1184
|
+
void (*fun)(ffi_cif*, void*, void**, void*),
|
1185
|
+
void *user_data, void *rvalue,
|
1120
1186
|
unsigned long *pgr, ffi_dblfl *pfr)
|
1121
1187
|
{
|
1122
1188
|
/* rvalue is the pointer to space for return value in closure assembly
|
@@ -1134,14 +1200,12 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
|
|
1134
1200
|
void ** avalue;
|
1135
1201
|
ffi_type ** arg_types;
|
1136
1202
|
long i, avn;
|
1137
|
-
ffi_cif * cif;
|
1138
1203
|
ffi_dblfl * end_pfr = pfr + NUM_FPR_ARG_REGISTERS;
|
1139
1204
|
unsigned size_al;
|
1140
1205
|
#if defined(POWERPC_DARWIN64)
|
1141
1206
|
unsigned fpsused = 0;
|
1142
1207
|
#endif
|
1143
1208
|
|
1144
|
-
cif = closure->cif;
|
1145
1209
|
avalue = alloca (cif->nargs * sizeof(void *));
|
1146
1210
|
|
1147
1211
|
if (cif->rtype->type == FFI_TYPE_STRUCT)
|
@@ -1352,8 +1416,25 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
|
|
1352
1416
|
i++;
|
1353
1417
|
}
|
1354
1418
|
|
1355
|
-
(
|
1419
|
+
(fun) (cif, rvalue, avalue, user_data);
|
1356
1420
|
|
1357
1421
|
/* Tell ffi_closure_ASM to perform return type promotions. */
|
1358
1422
|
return cif->rtype;
|
1359
1423
|
}
|
1424
|
+
|
1425
|
+
ffi_type *
|
1426
|
+
ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
|
1427
|
+
unsigned long *pgr, ffi_dblfl *pfr)
|
1428
|
+
{
|
1429
|
+
return ffi_closure_helper_common (closure->cif, closure->fun,
|
1430
|
+
closure->user_data, rvalue, pgr, pfr);
|
1431
|
+
}
|
1432
|
+
|
1433
|
+
ffi_type *
|
1434
|
+
ffi_go_closure_helper_DARWIN (ffi_go_closure *closure, void *rvalue,
|
1435
|
+
unsigned long *pgr, ffi_dblfl *pfr)
|
1436
|
+
{
|
1437
|
+
return ffi_closure_helper_common (closure->cif, closure->fun,
|
1438
|
+
closure, rvalue, pgr, pfr);
|
1439
|
+
}
|
1440
|
+
|
@@ -142,6 +142,9 @@ typedef enum ffi_abi {
|
|
142
142
|
# define FFI_TARGET_SPECIFIC_VARIADIC 1
|
143
143
|
# define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
|
144
144
|
#endif
|
145
|
+
#if defined (POWERPC_AIX)
|
146
|
+
# define FFI_GO_CLOSURES 1
|
147
|
+
#endif
|
145
148
|
|
146
149
|
/* ppc_closure.S and linux64_closure.S expect this. */
|
147
150
|
#define FFI_PPC_TYPE_LAST FFI_TYPE_POINTER
|
@@ -32,6 +32,7 @@
|
|
32
32
|
#ifndef __x86_64__
|
33
33
|
#include <ffi.h>
|
34
34
|
#include <ffi_common.h>
|
35
|
+
#include <stdint.h>
|
35
36
|
#include <stdlib.h>
|
36
37
|
#include "internal.h"
|
37
38
|
|
@@ -674,7 +675,8 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)
|
|
674
675
|
}
|
675
676
|
|
676
677
|
bytes = cif->bytes;
|
677
|
-
argp = stack =
|
678
|
+
argp = stack =
|
679
|
+
(void *)((uintptr_t)alloca(bytes + sizeof(*frame) + rsize + 15) & ~16);
|
678
680
|
frame = (struct call_frame *)(stack + bytes);
|
679
681
|
if (rsize)
|
680
682
|
rvalue = frame + 1;
|
@@ -389,19 +389,24 @@ examine_argument (ffi_type *type, enum x86_64_reg_class classes[MAX_CLASSES],
|
|
389
389
|
|
390
390
|
/* Perform machine dependent cif processing. */
|
391
391
|
|
392
|
+
#ifndef __ILP32__
|
392
393
|
extern ffi_status
|
393
394
|
ffi_prep_cif_machdep_efi64(ffi_cif *cif);
|
395
|
+
#endif
|
394
396
|
|
395
397
|
ffi_status
|
396
398
|
ffi_prep_cif_machdep (ffi_cif *cif)
|
397
399
|
{
|
398
|
-
int gprcount, ssecount, i, avn, ngpr, nsse
|
400
|
+
int gprcount, ssecount, i, avn, ngpr, nsse;
|
401
|
+
unsigned flags;
|
399
402
|
enum x86_64_reg_class classes[MAX_CLASSES];
|
400
403
|
size_t bytes, n, rtype_size;
|
401
404
|
ffi_type *rtype;
|
402
405
|
|
406
|
+
#ifndef __ILP32__
|
403
407
|
if (cif->abi == FFI_EFI64)
|
404
408
|
return ffi_prep_cif_machdep_efi64(cif);
|
409
|
+
#endif
|
405
410
|
if (cif->abi != FFI_UNIX64)
|
406
411
|
return FFI_BAD_ABI;
|
407
412
|
|
@@ -494,7 +499,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
|
|
494
499
|
case FFI_TYPE_SINT32:
|
495
500
|
case FFI_TYPE_UINT64:
|
496
501
|
case FFI_TYPE_SINT64:
|
497
|
-
flags = UNIX64_RET_ST_RAX_RDX | (rtype_size << UNIX64_SIZE_SHIFT);
|
502
|
+
flags = UNIX64_RET_ST_RAX_RDX | ((unsigned) rtype_size << UNIX64_SIZE_SHIFT);
|
498
503
|
break;
|
499
504
|
case FFI_TYPE_FLOAT:
|
500
505
|
flags = UNIX64_RET_XMM64;
|
@@ -542,7 +547,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
|
|
542
547
|
flags |= UNIX64_FLAG_XMM_ARGS;
|
543
548
|
|
544
549
|
cif->flags = flags;
|
545
|
-
cif->bytes = FFI_ALIGN (bytes, 8);
|
550
|
+
cif->bytes = (unsigned) FFI_ALIGN (bytes, 8);
|
546
551
|
|
547
552
|
return FFI_OK;
|
548
553
|
}
|
@@ -646,10 +651,10 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
|
646
651
|
break;
|
647
652
|
case X86_64_SSE_CLASS:
|
648
653
|
case X86_64_SSEDF_CLASS:
|
649
|
-
reg_args->sse[ssecount++].i64
|
654
|
+
memcpy (®_args->sse[ssecount++].i64, a, sizeof(UINT64));
|
650
655
|
break;
|
651
656
|
case X86_64_SSESF_CLASS:
|
652
|
-
reg_args->sse[ssecount++].i32
|
657
|
+
memcpy (®_args->sse[ssecount++].i32, a, sizeof(UINT32));
|
653
658
|
break;
|
654
659
|
default:
|
655
660
|
abort();
|
@@ -663,27 +668,35 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
|
663
668
|
flags, rvalue, fn);
|
664
669
|
}
|
665
670
|
|
671
|
+
#ifndef __ILP32__
|
666
672
|
extern void
|
667
673
|
ffi_call_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue);
|
674
|
+
#endif
|
668
675
|
|
669
676
|
void
|
670
677
|
ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
671
678
|
{
|
679
|
+
#ifndef __ILP32__
|
672
680
|
if (cif->abi == FFI_EFI64)
|
673
681
|
return ffi_call_efi64(cif, fn, rvalue, avalue);
|
682
|
+
#endif
|
674
683
|
ffi_call_int (cif, fn, rvalue, avalue, NULL);
|
675
684
|
}
|
676
685
|
|
686
|
+
#ifndef __ILP32__
|
677
687
|
extern void
|
678
688
|
ffi_call_go_efi64(ffi_cif *cif, void (*fn)(void), void *rvalue,
|
679
689
|
void **avalue, void *closure);
|
690
|
+
#endif
|
680
691
|
|
681
692
|
void
|
682
693
|
ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
683
694
|
void **avalue, void *closure)
|
684
695
|
{
|
696
|
+
#ifndef __ILP32__
|
685
697
|
if (cif->abi == FFI_EFI64)
|
686
698
|
ffi_call_go_efi64(cif, fn, rvalue, avalue, closure);
|
699
|
+
#endif
|
687
700
|
ffi_call_int (cif, fn, rvalue, avalue, closure);
|
688
701
|
}
|
689
702
|
|
@@ -691,12 +704,14 @@ ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
|
691
704
|
extern void ffi_closure_unix64(void) FFI_HIDDEN;
|
692
705
|
extern void ffi_closure_unix64_sse(void) FFI_HIDDEN;
|
693
706
|
|
707
|
+
#ifndef __ILP32__
|
694
708
|
extern ffi_status
|
695
709
|
ffi_prep_closure_loc_efi64(ffi_closure* closure,
|
696
710
|
ffi_cif* cif,
|
697
711
|
void (*fun)(ffi_cif*, void*, void**, void*),
|
698
712
|
void *user_data,
|
699
713
|
void *codeloc);
|
714
|
+
#endif
|
700
715
|
|
701
716
|
ffi_status
|
702
717
|
ffi_prep_closure_loc (ffi_closure* closure,
|
@@ -716,8 +731,10 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
|
716
731
|
void (*dest)(void);
|
717
732
|
char *tramp = closure->tramp;
|
718
733
|
|
734
|
+
#ifndef __ILP32__
|
719
735
|
if (cif->abi == FFI_EFI64)
|
720
736
|
return ffi_prep_closure_loc_efi64(closure, cif, fun, user_data, codeloc);
|
737
|
+
#endif
|
721
738
|
if (cif->abi != FFI_UNIX64)
|
722
739
|
return FFI_BAD_ABI;
|
723
740
|
|
@@ -832,16 +849,20 @@ ffi_closure_unix64_inner(ffi_cif *cif,
|
|
832
849
|
extern void ffi_go_closure_unix64(void) FFI_HIDDEN;
|
833
850
|
extern void ffi_go_closure_unix64_sse(void) FFI_HIDDEN;
|
834
851
|
|
852
|
+
#ifndef __ILP32__
|
835
853
|
extern ffi_status
|
836
854
|
ffi_prep_go_closure_efi64(ffi_go_closure* closure, ffi_cif* cif,
|
837
855
|
void (*fun)(ffi_cif*, void*, void**, void*));
|
856
|
+
#endif
|
838
857
|
|
839
858
|
ffi_status
|
840
859
|
ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
|
841
860
|
void (*fun)(ffi_cif*, void*, void**, void*))
|
842
861
|
{
|
862
|
+
#ifndef __ILP32__
|
843
863
|
if (cif->abi == FFI_EFI64)
|
844
864
|
return ffi_prep_go_closure_efi64(closure, cif, fun);
|
865
|
+
#endif
|
845
866
|
if (cif->abi != FFI_UNIX64)
|
846
867
|
return FFI_BAD_ABI;
|
847
868
|
|
@@ -274,7 +274,7 @@ L(C1(pc,N)): \
|
|
274
274
|
# define FFI_CLOSURE_CALL_INNER(UWN) \
|
275
275
|
movl %ebx, 40(%esp); /* save ebx */ \
|
276
276
|
L(C1(UW,UWN)): \
|
277
|
-
|
277
|
+
/* cfi_rel_offset(%ebx, 40); */ \
|
278
278
|
call C(__x86.get_pc_thunk.bx); /* load got register */ \
|
279
279
|
addl $C(_GLOBAL_OFFSET_TABLE_), %ebx; \
|
280
280
|
call ffi_closure_inner@PLT
|
@@ -284,7 +284,7 @@ L(C1(UW,UWN)): \
|
|
284
284
|
leal L(C1(load_table,N))@GOTOFF(%ebx, %eax, 8), %edx; \
|
285
285
|
movl 40(%esp), %ebx; /* restore ebx */ \
|
286
286
|
L(C1(UW,UWN)): \
|
287
|
-
|
287
|
+
/* cfi_restore(%ebx); */ \
|
288
288
|
movl closure_CF(%esp), %eax; /* optimiztic load */ \
|
289
289
|
jmp *%edx
|
290
290
|
# endif /* DARWIN || HIDDEN */
|
@@ -274,7 +274,7 @@ L(do_closure):
|
|
274
274
|
leaq ffi_closure_OFS_RVALUE(%rsp), %rcx /* Load rvalue */
|
275
275
|
movq %rsp, %r8 /* Load reg_args */
|
276
276
|
leaq ffi_closure_FS+8(%rsp), %r9 /* Load argp */
|
277
|
-
call C(ffi_closure_unix64_inner)
|
277
|
+
call PLT(C(ffi_closure_unix64_inner))
|
278
278
|
|
279
279
|
/* Deallocate stack frame early; return value is now in redzone. */
|
280
280
|
addq $ffi_closure_FS, %rsp
|
@@ -214,7 +214,7 @@ C(ffi_closure_win64):
|
|
214
214
|
movsd %xmm3, ffi_clo_OFF_X+24(%rsp)
|
215
215
|
|
216
216
|
leaq ffi_clo_OFF_R(%rsp), %r9
|
217
|
-
call C(ffi_closure_win64_inner)
|
217
|
+
call PLT(C(ffi_closure_win64_inner))
|
218
218
|
|
219
219
|
/* Load the result into both possible result registers. */
|
220
220
|
movq ffi_clo_OFF_R(%rsp), %rax
|
@@ -324,7 +324,8 @@ proc run-many-tests { testcases extra_flags } {
|
|
324
324
|
"-DABI_NUM=FFI_THISCALL -DABI_ATTR=__THISCALL__"
|
325
325
|
"-DABI_NUM=FFI_FASTCALL -DABI_ATTR=__FASTCALL__"
|
326
326
|
}
|
327
|
-
} elseif [istarget "x86_64-*-*"]
|
327
|
+
} elseif { [istarget "x86_64-*-*"] \
|
328
|
+
&& [libffi_feature_test "#ifndef __ILP32__"] } {
|
328
329
|
set targetabis {
|
329
330
|
""
|
330
331
|
"-DABI_NUM=FFI_WIN64 -DABI_ATTR=__MSABI__"
|
@@ -0,0 +1,95 @@
|
|
1
|
+
/* Area: ffi_call, closure_call
|
2
|
+
Purpose: Check structure passing with different structure size.
|
3
|
+
Depending on the ABI. Check overlapping.
|
4
|
+
Limitations:>none.
|
5
|
+
PR: none.
|
6
|
+
Originator: <compnerd@compnerd.org> 20171026 */
|
7
|
+
|
8
|
+
/* { dg-do run } */
|
9
|
+
|
10
|
+
#include "ffitest.h"
|
11
|
+
|
12
|
+
typedef struct cls_struct_3float {
|
13
|
+
float f;
|
14
|
+
float g;
|
15
|
+
float h;
|
16
|
+
} cls_struct_3float;
|
17
|
+
|
18
|
+
cls_struct_3float cls_struct_3float_fn(struct cls_struct_3float a1,
|
19
|
+
struct cls_struct_3float a2)
|
20
|
+
{
|
21
|
+
struct cls_struct_3float result;
|
22
|
+
|
23
|
+
result.f = a1.f + a2.f;
|
24
|
+
result.g = a1.g + a2.g;
|
25
|
+
result.h = a1.h + a2.h;
|
26
|
+
|
27
|
+
printf("%g %g %g %g %g %g: %g %g %g\n", a1.f, a1.g, a1.h,
|
28
|
+
a2.f, a2.g, a2.h, result.f, result.g, result.h);
|
29
|
+
|
30
|
+
return result;
|
31
|
+
}
|
32
|
+
|
33
|
+
static void
|
34
|
+
cls_struct_3float_gn(ffi_cif *cif __UNUSED__, void* resp, void **args,
|
35
|
+
void* userdata __UNUSED__)
|
36
|
+
{
|
37
|
+
struct cls_struct_3float a1, a2;
|
38
|
+
|
39
|
+
a1 = *(struct cls_struct_3float*)(args[0]);
|
40
|
+
a2 = *(struct cls_struct_3float*)(args[1]);
|
41
|
+
|
42
|
+
*(cls_struct_3float*)resp = cls_struct_3float_fn(a1, a2);
|
43
|
+
}
|
44
|
+
|
45
|
+
int main (void)
|
46
|
+
{
|
47
|
+
ffi_cif cif;
|
48
|
+
void *code;
|
49
|
+
ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
|
50
|
+
void *args_dbl[3];
|
51
|
+
ffi_type* cls_struct_fields[4];
|
52
|
+
ffi_type cls_struct_type;
|
53
|
+
ffi_type* dbl_arg_types[3];
|
54
|
+
|
55
|
+
struct cls_struct_3float g_dbl = { 1.0f, 2.0f, 3.0f };
|
56
|
+
struct cls_struct_3float f_dbl = { 1.0f, 2.0f, 3.0f };
|
57
|
+
struct cls_struct_3float res_dbl;
|
58
|
+
|
59
|
+
cls_struct_fields[0] = &ffi_type_float;
|
60
|
+
cls_struct_fields[1] = &ffi_type_float;
|
61
|
+
cls_struct_fields[2] = &ffi_type_float;
|
62
|
+
cls_struct_fields[3] = NULL;
|
63
|
+
|
64
|
+
cls_struct_type.size = 0;
|
65
|
+
cls_struct_type.alignment = 0;
|
66
|
+
cls_struct_type.type = FFI_TYPE_STRUCT;
|
67
|
+
cls_struct_type.elements = cls_struct_fields;
|
68
|
+
|
69
|
+
dbl_arg_types[0] = &cls_struct_type;
|
70
|
+
dbl_arg_types[1] = &cls_struct_type;
|
71
|
+
dbl_arg_types[2] = NULL;
|
72
|
+
|
73
|
+
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
|
74
|
+
dbl_arg_types) == FFI_OK);
|
75
|
+
|
76
|
+
args_dbl[0] = &g_dbl;
|
77
|
+
args_dbl[1] = &f_dbl;
|
78
|
+
args_dbl[2] = NULL;
|
79
|
+
|
80
|
+
ffi_call(&cif, FFI_FN(cls_struct_3float_fn), &res_dbl, args_dbl);
|
81
|
+
/* { dg-output "1 2 3 1 2 3: 2 4 6" } */
|
82
|
+
printf("res: %g %g %g\n", res_dbl.f, res_dbl.g, res_dbl.h);
|
83
|
+
/* { dg-output "\nres: 2 4 6" } */
|
84
|
+
|
85
|
+
CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_3float_gn, NULL, code) ==
|
86
|
+
FFI_OK);
|
87
|
+
|
88
|
+
res_dbl = ((cls_struct_3float(*)(cls_struct_3float,
|
89
|
+
cls_struct_3float))(code))(g_dbl, f_dbl);
|
90
|
+
/* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */
|
91
|
+
printf("res: %g %g %g\n", res_dbl.f, res_dbl.g, res_dbl.h);
|
92
|
+
/* { dg-output "\nres: 2 4 6" } */
|
93
|
+
|
94
|
+
exit(0);
|
95
|
+
}
|