ffi 1.16.3 → 1.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +59 -0
- data/Gemfile +11 -2
- data/README.md +1 -1
- data/Rakefile +19 -7
- data/ext/ffi_c/AbstractMemory.c +39 -38
- data/ext/ffi_c/ArrayType.c +2 -2
- data/ext/ffi_c/Buffer.c +4 -4
- data/ext/ffi_c/Call.c +12 -6
- data/ext/ffi_c/Call.h +3 -2
- data/ext/ffi_c/DynamicLibrary.c +2 -2
- data/ext/ffi_c/Function.c +52 -34
- data/ext/ffi_c/FunctionInfo.c +1 -1
- data/ext/ffi_c/LastError.c +4 -4
- data/ext/ffi_c/MemoryPointer.c +2 -2
- data/ext/ffi_c/Pointer.c +14 -11
- data/ext/ffi_c/Struct.c +11 -4
- data/ext/ffi_c/StructLayout.c +13 -13
- data/ext/ffi_c/Type.c +17 -16
- data/ext/ffi_c/Types.c +7 -1
- data/ext/ffi_c/Types.h +0 -1
- data/ext/ffi_c/Variadic.c +6 -3
- data/ext/ffi_c/libffi/.allow-ai-service +0 -0
- data/ext/ffi_c/libffi/.github/workflows/build.yml +34 -15
- data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +50 -61
- data/ext/ffi_c/libffi/LICENSE +1 -1
- data/ext/ffi_c/libffi/Makefile.am +4 -3
- data/ext/ffi_c/libffi/Makefile.in +5 -25
- data/ext/ffi_c/libffi/README.md +28 -6
- data/ext/ffi_c/libffi/acinclude.m4 +6 -0
- data/ext/ffi_c/libffi/config.guess +80 -22
- data/ext/ffi_c/libffi/config.sub +161 -80
- data/ext/ffi_c/libffi/configure +46 -30
- data/ext/ffi_c/libffi/configure.ac +10 -9
- data/ext/ffi_c/libffi/configure.host +1 -6
- data/ext/ffi_c/libffi/doc/Makefile.in +1 -0
- data/ext/ffi_c/libffi/doc/libffi.texi +4 -4
- data/ext/ffi_c/libffi/doc/version.texi +4 -4
- data/ext/ffi_c/libffi/fficonfig.h.in +3 -3
- data/ext/ffi_c/libffi/include/Makefile.in +1 -0
- data/ext/ffi_c/libffi/include/ffi.h.in +2 -11
- data/ext/ffi_c/libffi/include/ffi_cfi.h +2 -0
- data/ext/ffi_c/libffi/include/ffi_common.h +21 -2
- data/ext/ffi_c/libffi/libffi.map.in +5 -0
- data/ext/ffi_c/libffi/libtool-version +1 -1
- data/ext/ffi_c/libffi/ltmain.sh +8 -20
- data/ext/ffi_c/libffi/man/Makefile.in +1 -0
- data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/ffi.h +1 -1
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +33 -17
- data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +2 -2
- data/ext/ffi_c/libffi/src/aarch64/internal.h +63 -17
- data/ext/ffi_c/libffi/src/aarch64/sysv.S +213 -57
- data/ext/ffi_c/libffi/src/arc/arcompact.S +2 -2
- data/ext/ffi_c/libffi/src/arc/ffi.c +6 -2
- data/ext/ffi_c/libffi/src/closures.c +6 -6
- data/ext/ffi_c/libffi/src/debug.c +2 -2
- data/ext/ffi_c/libffi/src/dlmalloc.c +2 -1
- data/ext/ffi_c/libffi/src/loongarch64/ffi.c +3 -0
- data/ext/ffi_c/libffi/src/mips/ffi.c +12 -4
- data/ext/ffi_c/libffi/src/mips/ffitarget.h +2 -4
- data/ext/ffi_c/libffi/src/mips/n32.S +69 -14
- data/ext/ffi_c/libffi/src/mips/o32.S +4 -0
- data/ext/ffi_c/libffi/src/or1k/ffi.c +2 -2
- data/ext/ffi_c/libffi/src/powerpc/ffi.c +13 -0
- data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +36 -24
- data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +26 -19
- data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +26 -16
- data/ext/ffi_c/libffi/src/powerpc/internal.h +10 -0
- data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +47 -0
- data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +24 -0
- data/ext/ffi_c/libffi/src/prep_cif.c +1 -4
- data/ext/ffi_c/libffi/src/s390/ffi.c +28 -1
- data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
- data/ext/ffi_c/libffi/src/s390/sysv.S +38 -0
- data/ext/ffi_c/libffi/src/sparc/ffi.c +16 -0
- data/ext/ffi_c/libffi/src/sparc/ffi64.c +7 -1
- data/ext/ffi_c/libffi/src/tramp.c +1 -1
- data/ext/ffi_c/libffi/src/types.c +4 -6
- data/ext/ffi_c/libffi/src/wasm32/ffi.c +23 -262
- data/ext/ffi_c/libffi/src/x86/ffi.c +4 -1
- data/ext/ffi_c/libffi/src/x86/ffi64.c +4 -1
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +1 -1
- data/ext/ffi_c/libffi/testsuite/Makefile.am +80 -127
- data/ext/ffi_c/libffi/testsuite/Makefile.in +81 -127
- data/ext/ffi_c/libffi/testsuite/emscripten/build-tests.sh +4 -24
- data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +8 -25
- data/ext/ffi_c/libffi/testsuite/emscripten/conftest.py +6 -0
- data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +3 -28
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback.c +99 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback2.c +108 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback3.c +114 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/callback4.c +119 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/overread.c +54 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/struct_int_float.c +88 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +1 -0
- data/ext/ffi_c/libffi/testsuite/libffi.call/x32.c +31 -0
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_sshortchar.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_ushortchar.c +1 -1
- data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +1 -1
- data/ext/ffi_c/libffi.darwin.mk +2 -2
- data/lib/ffi/autopointer.rb +1 -9
- data/lib/ffi/dynamic_library.rb +34 -5
- data/lib/ffi/enum.rb +0 -1
- data/lib/ffi/ffi.rb +59 -0
- data/lib/ffi/function.rb +1 -1
- data/lib/ffi/io.rb +2 -2
- data/lib/ffi/library.rb +23 -23
- data/lib/ffi/platform/aarch64-linux/types.conf +74 -3
- data/lib/ffi/pointer.rb +6 -6
- data/lib/ffi/struct.rb +4 -4
- data/lib/ffi/struct_layout.rb +2 -2
- data/lib/ffi/struct_layout_builder.rb +8 -8
- data/lib/ffi/types.rb +51 -49
- data/lib/ffi/version.rb +1 -1
- data/sig/ffi/abstract_memory.rbs +165 -0
- data/sig/ffi/auto_pointer.rbs +26 -0
- data/sig/ffi/buffer.rbs +18 -0
- data/sig/ffi/data_converter.rbs +10 -0
- data/sig/ffi/dynamic_library.rbs +9 -0
- data/sig/ffi/enum.rbs +38 -0
- data/sig/ffi/function.rbs +39 -0
- data/sig/ffi/library.rbs +42 -0
- data/sig/ffi/native_type.rbs +86 -0
- data/sig/ffi/pointer.rbs +42 -0
- data/sig/ffi/struct.rbs +76 -0
- data/sig/ffi/struct_by_reference.rbs +11 -0
- data/sig/ffi/struct_by_value.rbs +7 -0
- data/sig/ffi/struct_layout.rbs +9 -0
- data/sig/ffi/struct_layout_builder.rbs +5 -0
- data/sig/ffi/type.rbs +39 -0
- data/sig/ffi.rbs +26 -0
- data.tar.gz.sig +0 -0
- metadata +41 -22
- metadata.gz.sig +0 -0
- data/ext/ffi_c/libffi/.circleci/config.yml +0 -156
- data/ext/ffi_c/libffi/src/nios2/ffi.c +0 -304
- data/ext/ffi_c/libffi/src/nios2/ffitarget.h +0 -52
- data/ext/ffi_c/libffi/src/nios2/sysv.S +0 -136
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
|
|
3
|
+
if ! [ -x "$(command -v emcc)" ]; then
|
|
4
|
+
echo "Error: emcc could not be found." >&2
|
|
4
5
|
exit 1
|
|
5
|
-
|
|
6
|
+
fi
|
|
6
7
|
|
|
7
8
|
set -e
|
|
8
9
|
|
|
@@ -13,38 +14,20 @@ TARGET=$SOURCE_DIR/target
|
|
|
13
14
|
mkdir -p "$TARGET"
|
|
14
15
|
|
|
15
16
|
# Define default arguments
|
|
16
|
-
|
|
17
|
-
# JS BigInt to Wasm i64 integration, disabled by default
|
|
18
|
-
# This needs to test false if there exists an environment variable called
|
|
19
|
-
# WASM_BIGINT whose contents are empty. Don't use +x.
|
|
20
|
-
if [ -n "${WASM_BIGINT}" ]; then
|
|
21
|
-
WASM_BIGINT=true
|
|
22
|
-
else
|
|
23
|
-
WASM_BIGINT=false
|
|
24
|
-
fi
|
|
17
|
+
DEBUG=false
|
|
25
18
|
|
|
26
19
|
# Parse arguments
|
|
27
20
|
while [ $# -gt 0 ]; do
|
|
28
21
|
case $1 in
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
*)
|
|
32
|
-
echo "ERROR: Unknown parameter: $1" >&2
|
|
33
|
-
exit 1
|
|
34
|
-
;;
|
|
22
|
+
--debug) DEBUG=true ;;
|
|
23
|
+
*) echo "ERROR: Unknown parameter: $1" >&2; exit 1 ;;
|
|
35
24
|
esac
|
|
36
25
|
shift
|
|
37
26
|
done
|
|
38
27
|
|
|
39
28
|
# Common compiler flags
|
|
40
29
|
export CFLAGS="-O3 -fPIC"
|
|
41
|
-
if [ "$
|
|
42
|
-
# We need to detect WASM_BIGINT support at compile time
|
|
43
|
-
export CFLAGS+=" -DWASM_BIGINT"
|
|
44
|
-
fi
|
|
45
|
-
if [ "$DEBUG" = "true" ]; then
|
|
46
|
-
export CFLAGS+=" -DDEBUG_F"
|
|
47
|
-
fi
|
|
30
|
+
if [ "$DEBUG" = "true" ]; then export CFLAGS+=" -DDEBUG_F"; fi
|
|
48
31
|
export CXXFLAGS="$CFLAGS"
|
|
49
32
|
|
|
50
33
|
# Build paths
|
|
@@ -3,6 +3,8 @@ from pytest import fixture
|
|
|
3
3
|
from pytest_pyodide.server import spawn_web_server
|
|
4
4
|
from pytest_pyodide import runner
|
|
5
5
|
|
|
6
|
+
import logging
|
|
7
|
+
|
|
6
8
|
TEST_PATH = Path(__file__).parents[1].resolve()
|
|
7
9
|
|
|
8
10
|
|
|
@@ -47,6 +49,10 @@ RUNNER_DICT = {x.browser: x for x in [FirefoxRunner, ChromeRunner]}
|
|
|
47
49
|
def selenium_class_scope(request, web_server_main):
|
|
48
50
|
server_hostname, server_port, server_log = web_server_main
|
|
49
51
|
assert request.param in RUNNER_DICT
|
|
52
|
+
|
|
53
|
+
logger = logging.getLogger('selenium')
|
|
54
|
+
logger.setLevel(logging.DEBUG)
|
|
55
|
+
|
|
50
56
|
cls = RUNNER_DICT[request.param]
|
|
51
57
|
selenium = cls(
|
|
52
58
|
test_dir=request.cls.TEST_BUILD_DIR,
|
|
@@ -1,39 +1,14 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
emcc_exists="$(command -v emcc)"
|
|
7
|
-
if [ ! "${emcc_exists}" ]; then
|
|
8
|
-
echo "Emscripten not on path"
|
|
3
|
+
if ! [ -x "$(command -v emcc)" ]; then
|
|
4
|
+
echo "Error: emcc could not be found." >&2
|
|
9
5
|
exit 1
|
|
10
6
|
fi
|
|
11
7
|
|
|
12
|
-
# Parse arguments
|
|
13
|
-
while [ $# -gt 0 ]; do
|
|
14
|
-
case $1 in
|
|
15
|
-
--wasm-bigint) WASM_BIGINT=true ;;
|
|
16
|
-
*)
|
|
17
|
-
echo "ERROR: Unknown parameter: $1" >&2
|
|
18
|
-
exit 1
|
|
19
|
-
;;
|
|
20
|
-
esac
|
|
21
|
-
shift
|
|
22
|
-
done
|
|
23
|
-
|
|
24
8
|
# Common compiler flags
|
|
25
9
|
export CFLAGS="-fPIC $EXTRA_CFLAGS"
|
|
26
|
-
if [ "$WASM_BIGINT" = "true" ]; then
|
|
27
|
-
# We need to detect WASM_BIGINT support at compile time
|
|
28
|
-
export CFLAGS+=" -DWASM_BIGINT"
|
|
29
|
-
fi
|
|
30
10
|
export CXXFLAGS="$CFLAGS -sNO_DISABLE_EXCEPTION_CATCHING $EXTRA_CXXFLAGS"
|
|
31
|
-
export LDFLAGS="-sEXPORTED_FUNCTIONS=_main,_malloc,_free -sALLOW_TABLE_GROWTH -sASSERTIONS -sNO_DISABLE_EXCEPTION_CATCHING"
|
|
32
|
-
if [ "$WASM_BIGINT" = "true" ]; then
|
|
33
|
-
export LDFLAGS+=" -sWASM_BIGINT"
|
|
34
|
-
else
|
|
35
|
-
export LDFLAGS+=" -sEXPORTED_RUNTIME_METHODS='getTempRet0,setTempRet0'"
|
|
36
|
-
fi
|
|
11
|
+
export LDFLAGS="-sEXPORTED_FUNCTIONS=_main,_malloc,_free -sALLOW_TABLE_GROWTH -sASSERTIONS -sNO_DISABLE_EXCEPTION_CATCHING -sWASM_BIGINT"
|
|
37
12
|
|
|
38
13
|
# Specific variables for cross-compilation
|
|
39
14
|
export CHOST="wasm32-unknown-linux" # wasm32-unknown-emscripten
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/* Area: ffi_call
|
|
2
|
+
Purpose: Check structures with array and callback.
|
|
3
|
+
Limitations: none.
|
|
4
|
+
PR: none.
|
|
5
|
+
Originator: David Tenty <daltenty@ibm.com> */
|
|
6
|
+
|
|
7
|
+
/* { dg-do run } */
|
|
8
|
+
#include "ffitest.h"
|
|
9
|
+
|
|
10
|
+
static int i=5;
|
|
11
|
+
|
|
12
|
+
static void callback(void) { i++; }
|
|
13
|
+
|
|
14
|
+
typedef struct
|
|
15
|
+
{
|
|
16
|
+
unsigned char c1;
|
|
17
|
+
double s[2];
|
|
18
|
+
unsigned char c2;
|
|
19
|
+
} test_structure_12;
|
|
20
|
+
|
|
21
|
+
static test_structure_12 ABI_ATTR struct12 (test_structure_12 ts, void (*func)(void))
|
|
22
|
+
{
|
|
23
|
+
ts.c1 += 1;
|
|
24
|
+
ts.c2 += 1;
|
|
25
|
+
ts.s[0] += 1;
|
|
26
|
+
ts.s[1] += 1;
|
|
27
|
+
|
|
28
|
+
func();
|
|
29
|
+
return ts;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
int main (void)
|
|
33
|
+
{
|
|
34
|
+
ffi_cif cif;
|
|
35
|
+
ffi_type *args[MAX_ARGS];
|
|
36
|
+
void *values[MAX_ARGS];
|
|
37
|
+
ffi_type ts12_type,ts12a_type;
|
|
38
|
+
ffi_type *ts12_type_elements[4];
|
|
39
|
+
ffi_type *ts12a_type_elements[3];
|
|
40
|
+
|
|
41
|
+
test_structure_12 ts12_arg;
|
|
42
|
+
void (*ptr)(void)=&callback;
|
|
43
|
+
|
|
44
|
+
test_structure_12 *ts12_result =
|
|
45
|
+
(test_structure_12 *) malloc (sizeof(test_structure_12));
|
|
46
|
+
|
|
47
|
+
ts12a_type.size = 0;
|
|
48
|
+
ts12a_type.alignment = 0;
|
|
49
|
+
ts12a_type.type = FFI_TYPE_STRUCT;
|
|
50
|
+
ts12a_type.elements = ts12a_type_elements;
|
|
51
|
+
ts12a_type_elements[0] = &ffi_type_double;
|
|
52
|
+
ts12a_type_elements[1] = &ffi_type_double;
|
|
53
|
+
ts12a_type_elements[2] = NULL;
|
|
54
|
+
|
|
55
|
+
ts12_type.size = 0;
|
|
56
|
+
ts12_type.alignment = 0;
|
|
57
|
+
ts12_type.type = FFI_TYPE_STRUCT;
|
|
58
|
+
ts12_type.elements = ts12_type_elements;
|
|
59
|
+
ts12_type_elements[0] = &ffi_type_uchar;
|
|
60
|
+
ts12_type_elements[1] = &ts12a_type;
|
|
61
|
+
ts12_type_elements[2] = &ffi_type_uchar;
|
|
62
|
+
ts12_type_elements[3] = NULL;
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
args[0] = &ts12_type;
|
|
66
|
+
args[1] = &ffi_type_pointer;
|
|
67
|
+
values[0] = &ts12_arg;
|
|
68
|
+
values[1] = &ptr;
|
|
69
|
+
|
|
70
|
+
CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts12_type, args) == FFI_OK);
|
|
71
|
+
|
|
72
|
+
ts12_arg.c1 = 5;
|
|
73
|
+
ts12_arg.c2 = 6;
|
|
74
|
+
ts12_arg.s[0] = 7.77;
|
|
75
|
+
ts12_arg.s[1] = 8.88;
|
|
76
|
+
|
|
77
|
+
printf ("%u\n", ts12_arg.c1);
|
|
78
|
+
printf ("%u\n", ts12_arg.c2);
|
|
79
|
+
printf ("%g\n", ts12_arg.s[0]);
|
|
80
|
+
printf ("%g\n", ts12_arg.s[1]);
|
|
81
|
+
printf ("%d\n", i);
|
|
82
|
+
|
|
83
|
+
ffi_call(&cif, FFI_FN(struct12), ts12_result, values);
|
|
84
|
+
|
|
85
|
+
printf ("%u\n", ts12_result->c1);
|
|
86
|
+
printf ("%u\n", ts12_result->c2);
|
|
87
|
+
printf ("%g\n", ts12_result->s[0]);
|
|
88
|
+
printf ("%g\n", ts12_result->s[1]);
|
|
89
|
+
printf ("%d\n", i);
|
|
90
|
+
CHECK(ts12_result->c1 == 5 + 1);
|
|
91
|
+
CHECK(ts12_result->c2 == 6 + 1);
|
|
92
|
+
CHECK(ts12_result->s[0] == 7.77 + 1);
|
|
93
|
+
CHECK(ts12_result->s[1] == 8.88 + 1);
|
|
94
|
+
CHECK(i == 5 + 1);
|
|
95
|
+
CHECK(ts12_type.size == sizeof(test_structure_12));
|
|
96
|
+
|
|
97
|
+
free (ts12_result);
|
|
98
|
+
exit(0);
|
|
99
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/* Area: ffi_call
|
|
2
|
+
Purpose: Check structures with nested array and callback.
|
|
3
|
+
Limitations: none.
|
|
4
|
+
PR: none.
|
|
5
|
+
Originator: David Tenty <daltenty@ibm.com> */
|
|
6
|
+
|
|
7
|
+
/* { dg-do run } */
|
|
8
|
+
#include "ffitest.h"
|
|
9
|
+
|
|
10
|
+
static int i=5;
|
|
11
|
+
|
|
12
|
+
static void callback(void) { i++; }
|
|
13
|
+
|
|
14
|
+
typedef struct
|
|
15
|
+
{
|
|
16
|
+
struct { double d; } s1;
|
|
17
|
+
double s[2];
|
|
18
|
+
unsigned char c2;
|
|
19
|
+
} test_structure_12;
|
|
20
|
+
|
|
21
|
+
static test_structure_12 ABI_ATTR struct12 (test_structure_12 ts, void (*func)(void))
|
|
22
|
+
{
|
|
23
|
+
ts.s1.d += 1;
|
|
24
|
+
ts.c2 += 1;
|
|
25
|
+
ts.s[0] += 1;
|
|
26
|
+
ts.s[1] += 1;
|
|
27
|
+
|
|
28
|
+
func();
|
|
29
|
+
return ts;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
int main (void)
|
|
33
|
+
{
|
|
34
|
+
ffi_cif cif;
|
|
35
|
+
ffi_type *args[MAX_ARGS];
|
|
36
|
+
void *values[MAX_ARGS];
|
|
37
|
+
ffi_type ts12_type,ts12a_type, ts12b_type;
|
|
38
|
+
ffi_type *ts12_type_elements[4];
|
|
39
|
+
ffi_type *ts12a_type_elements[2];
|
|
40
|
+
ffi_type *ts12b_type_elements[3];
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
test_structure_12 ts12_arg;
|
|
44
|
+
void (*ptr)(void)=&callback;
|
|
45
|
+
|
|
46
|
+
test_structure_12 *ts12_result =
|
|
47
|
+
(test_structure_12 *) malloc (sizeof(test_structure_12));
|
|
48
|
+
|
|
49
|
+
ts12a_type.size = 0;
|
|
50
|
+
ts12a_type.alignment = 0;
|
|
51
|
+
ts12a_type.type = FFI_TYPE_STRUCT;
|
|
52
|
+
ts12a_type.elements = ts12a_type_elements;
|
|
53
|
+
ts12a_type_elements[0] = &ffi_type_double;
|
|
54
|
+
ts12a_type_elements[1] = NULL;
|
|
55
|
+
|
|
56
|
+
ts12b_type.size = 0;
|
|
57
|
+
ts12b_type.alignment = 0;
|
|
58
|
+
ts12b_type.type = FFI_TYPE_STRUCT;
|
|
59
|
+
ts12b_type.elements = ts12b_type_elements;
|
|
60
|
+
ts12b_type_elements[0] = &ffi_type_double;
|
|
61
|
+
ts12b_type_elements[1] = &ffi_type_double;
|
|
62
|
+
ts12b_type_elements[2] = NULL;
|
|
63
|
+
|
|
64
|
+
ts12_type.size = 0;
|
|
65
|
+
ts12_type.alignment = 0;
|
|
66
|
+
ts12_type.type = FFI_TYPE_STRUCT;
|
|
67
|
+
ts12_type.elements = ts12_type_elements;
|
|
68
|
+
ts12_type_elements[0] = &ts12a_type;
|
|
69
|
+
ts12_type_elements[1] = &ts12b_type;
|
|
70
|
+
ts12_type_elements[2] = &ffi_type_uchar;
|
|
71
|
+
ts12_type_elements[3] = NULL;
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
args[0] = &ts12_type;
|
|
75
|
+
args[1] = &ffi_type_pointer;
|
|
76
|
+
values[0] = &ts12_arg;
|
|
77
|
+
values[1] = &ptr;
|
|
78
|
+
|
|
79
|
+
CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts12_type, args) == FFI_OK);
|
|
80
|
+
|
|
81
|
+
ts12_arg.s1.d = 5.55;
|
|
82
|
+
ts12_arg.c2 = 6;
|
|
83
|
+
ts12_arg.s[0] = 7.77;
|
|
84
|
+
ts12_arg.s[1] = 8.88;
|
|
85
|
+
|
|
86
|
+
printf ("%g\n", ts12_arg.s1.d);
|
|
87
|
+
printf ("%u\n", ts12_arg.c2);
|
|
88
|
+
printf ("%g\n", ts12_arg.s[0]);
|
|
89
|
+
printf ("%g\n", ts12_arg.s[1]);
|
|
90
|
+
printf ("%d\n", i);
|
|
91
|
+
|
|
92
|
+
ffi_call(&cif, FFI_FN(struct12), ts12_result, values);
|
|
93
|
+
|
|
94
|
+
printf ("%g\n", ts12_result->s1.d);
|
|
95
|
+
printf ("%u\n", ts12_result->c2);
|
|
96
|
+
printf ("%g\n", ts12_result->s[0]);
|
|
97
|
+
printf ("%g\n", ts12_result->s[1]);
|
|
98
|
+
printf ("%d\n", i);
|
|
99
|
+
CHECK(ts12_result->s1.d == 5.55 + 1);
|
|
100
|
+
CHECK(ts12_result->c2 == 6 + 1);
|
|
101
|
+
CHECK(ts12_result->s[0] == 7.77 + 1);
|
|
102
|
+
CHECK(ts12_result->s[1] == 8.88 + 1);
|
|
103
|
+
CHECK(i == 5 + 1);
|
|
104
|
+
CHECK(ts12_type.size == sizeof(test_structure_12));
|
|
105
|
+
|
|
106
|
+
free (ts12_result);
|
|
107
|
+
exit(0);
|
|
108
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/* Area: ffi_call
|
|
2
|
+
Purpose: Check structures with array and callback.
|
|
3
|
+
Limitations: none.
|
|
4
|
+
PR: none.
|
|
5
|
+
Originator: David Tenty <daltenty@ibm.com> */
|
|
6
|
+
|
|
7
|
+
/* { dg-do run } */
|
|
8
|
+
#include "ffitest.h"
|
|
9
|
+
|
|
10
|
+
static int i=5;
|
|
11
|
+
|
|
12
|
+
static void callback(void) { i++; }
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
typedef struct
|
|
16
|
+
{
|
|
17
|
+
struct { unsigned char c; double d; } s1;
|
|
18
|
+
double s[2];
|
|
19
|
+
unsigned char c2;
|
|
20
|
+
} test_structure_12;
|
|
21
|
+
|
|
22
|
+
static test_structure_12 ABI_ATTR struct12 (test_structure_12 ts, void (*func)(void))
|
|
23
|
+
{
|
|
24
|
+
ts.s1.c += 1;
|
|
25
|
+
ts.s1.d += 1;
|
|
26
|
+
ts.c2 += 1;
|
|
27
|
+
ts.s[0] += 1;
|
|
28
|
+
ts.s[1] += 1;
|
|
29
|
+
|
|
30
|
+
func();
|
|
31
|
+
return ts;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
int main (void)
|
|
35
|
+
{
|
|
36
|
+
ffi_cif cif;
|
|
37
|
+
ffi_type *args[MAX_ARGS];
|
|
38
|
+
void *values[MAX_ARGS];
|
|
39
|
+
ffi_type ts12_type,ts12b_type, ts12a_type;
|
|
40
|
+
ffi_type *ts12_type_elements[4];
|
|
41
|
+
ffi_type *ts12b_type_elements[3];
|
|
42
|
+
ffi_type *ts12a_type_elements[3];
|
|
43
|
+
|
|
44
|
+
test_structure_12 ts12_arg;
|
|
45
|
+
void (*ptr)(void)=&callback;
|
|
46
|
+
|
|
47
|
+
test_structure_12 *ts12_result =
|
|
48
|
+
(test_structure_12 *) malloc (sizeof(test_structure_12));
|
|
49
|
+
|
|
50
|
+
ts12a_type.size = 0;
|
|
51
|
+
ts12a_type.alignment = 0;
|
|
52
|
+
ts12a_type.type = FFI_TYPE_STRUCT;
|
|
53
|
+
ts12a_type.elements = ts12a_type_elements;
|
|
54
|
+
ts12a_type_elements[0] = &ffi_type_uchar;
|
|
55
|
+
ts12a_type_elements[1] = &ffi_type_double;
|
|
56
|
+
ts12a_type_elements[2] = NULL;
|
|
57
|
+
|
|
58
|
+
ts12b_type.size = 0;
|
|
59
|
+
ts12b_type.alignment = 0;
|
|
60
|
+
ts12b_type.type = FFI_TYPE_STRUCT;
|
|
61
|
+
ts12b_type.elements = ts12b_type_elements;
|
|
62
|
+
ts12b_type_elements[0] = &ffi_type_double;
|
|
63
|
+
ts12b_type_elements[1] = &ffi_type_double;
|
|
64
|
+
ts12b_type_elements[2] = NULL;
|
|
65
|
+
|
|
66
|
+
ts12_type.size = 0;
|
|
67
|
+
ts12_type.alignment = 0;
|
|
68
|
+
ts12_type.type = FFI_TYPE_STRUCT;
|
|
69
|
+
ts12_type.elements = ts12_type_elements;
|
|
70
|
+
ts12_type_elements[0] = &ts12a_type;
|
|
71
|
+
ts12_type_elements[1] = &ts12b_type;
|
|
72
|
+
ts12_type_elements[2] = &ffi_type_uchar;
|
|
73
|
+
ts12_type_elements[3] = NULL;
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
args[0] = &ts12_type;
|
|
77
|
+
args[1] = &ffi_type_pointer;
|
|
78
|
+
values[0] = &ts12_arg;
|
|
79
|
+
values[1] = &ptr;
|
|
80
|
+
|
|
81
|
+
CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts12_type, args) == FFI_OK);
|
|
82
|
+
|
|
83
|
+
ts12_arg.s1.c = 5;
|
|
84
|
+
ts12_arg.s1.d = 5.55;
|
|
85
|
+
ts12_arg.c2 = 6;
|
|
86
|
+
ts12_arg.s[0] = 7.77;
|
|
87
|
+
ts12_arg.s[1] = 8.88;
|
|
88
|
+
|
|
89
|
+
printf ("%d\n", ts12_arg.s1.c);
|
|
90
|
+
printf ("%g\n", ts12_arg.s1.d);
|
|
91
|
+
printf ("%u\n", ts12_arg.c2);
|
|
92
|
+
printf ("%g\n", ts12_arg.s[0]);
|
|
93
|
+
printf ("%g\n", ts12_arg.s[1]);
|
|
94
|
+
printf ("%d\n", i);
|
|
95
|
+
|
|
96
|
+
ffi_call(&cif, FFI_FN(struct12), ts12_result, values);
|
|
97
|
+
|
|
98
|
+
printf ("%d\n", ts12_result->s1.c);
|
|
99
|
+
printf ("%g\n", ts12_result->s1.d);
|
|
100
|
+
printf ("%u\n", ts12_result->c2);
|
|
101
|
+
printf ("%g\n", ts12_result->s[0]);
|
|
102
|
+
printf ("%g\n", ts12_result->s[1]);
|
|
103
|
+
printf ("%d\n", i);
|
|
104
|
+
CHECK(ts12_result->s1.c == 5 + 1);
|
|
105
|
+
CHECK(ts12_result->s1.d == 5.55 + 1);
|
|
106
|
+
CHECK(ts12_result->c2 == 6 + 1);
|
|
107
|
+
CHECK(ts12_result->s[0] == 7.77 + 1);
|
|
108
|
+
CHECK(ts12_result->s[1] == 8.88 + 1);
|
|
109
|
+
CHECK(i == 5 + 1);
|
|
110
|
+
CHECK(ts12_type.size == sizeof(test_structure_12));
|
|
111
|
+
|
|
112
|
+
free (ts12_result);
|
|
113
|
+
exit(0);
|
|
114
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/* Area: ffi_call
|
|
2
|
+
Purpose: Check structures with array and callback.
|
|
3
|
+
Limitations: none.
|
|
4
|
+
PR: none.
|
|
5
|
+
Originator: David Tenty <daltenty@ibm.com> */
|
|
6
|
+
|
|
7
|
+
/* { dg-do run } */
|
|
8
|
+
#include "ffitest.h"
|
|
9
|
+
|
|
10
|
+
static int i=5;
|
|
11
|
+
|
|
12
|
+
static void callback(void) { i++; }
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
typedef struct
|
|
16
|
+
{
|
|
17
|
+
unsigned char c1;
|
|
18
|
+
struct { double d; unsigned char c; } s[2];
|
|
19
|
+
unsigned char c2;
|
|
20
|
+
} test_structure_12;
|
|
21
|
+
|
|
22
|
+
static test_structure_12 ABI_ATTR struct12 (test_structure_12 ts, void (*func)(void))
|
|
23
|
+
{
|
|
24
|
+
ts.c1 += 1;
|
|
25
|
+
ts.s[0].d += 1;
|
|
26
|
+
ts.s[0].c += 1;
|
|
27
|
+
ts.s[1].d += 1;
|
|
28
|
+
ts.s[1].c += 1;
|
|
29
|
+
ts.c2 += 1;
|
|
30
|
+
|
|
31
|
+
func();
|
|
32
|
+
return ts;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
int main (void)
|
|
36
|
+
{
|
|
37
|
+
ffi_cif cif;
|
|
38
|
+
ffi_type *args[MAX_ARGS];
|
|
39
|
+
void *values[MAX_ARGS];
|
|
40
|
+
ffi_type ts12_type,ts12b_type, ts12a_type;
|
|
41
|
+
ffi_type *ts12_type_elements[4];
|
|
42
|
+
ffi_type *ts12b_type_elements[3];
|
|
43
|
+
ffi_type *ts12a_type_elements[3];
|
|
44
|
+
|
|
45
|
+
test_structure_12 ts12_arg;
|
|
46
|
+
void (*ptr)(void)=&callback;
|
|
47
|
+
|
|
48
|
+
test_structure_12 *ts12_result =
|
|
49
|
+
(test_structure_12 *) malloc (sizeof(test_structure_12));
|
|
50
|
+
|
|
51
|
+
ts12a_type.size = 0;
|
|
52
|
+
ts12a_type.alignment = 0;
|
|
53
|
+
ts12a_type.type = FFI_TYPE_STRUCT;
|
|
54
|
+
ts12a_type.elements = ts12a_type_elements;
|
|
55
|
+
ts12a_type_elements[0] = &ffi_type_double;
|
|
56
|
+
ts12a_type_elements[1] = &ffi_type_uchar;
|
|
57
|
+
ts12a_type_elements[2] = NULL;
|
|
58
|
+
|
|
59
|
+
ts12b_type.size = 0;
|
|
60
|
+
ts12b_type.alignment = 0;
|
|
61
|
+
ts12b_type.type = FFI_TYPE_STRUCT;
|
|
62
|
+
ts12b_type.elements = ts12b_type_elements;
|
|
63
|
+
ts12b_type_elements[0] = &ts12a_type;
|
|
64
|
+
ts12b_type_elements[1] = &ts12a_type;
|
|
65
|
+
ts12b_type_elements[2] = NULL;
|
|
66
|
+
|
|
67
|
+
ts12_type.size = 0;
|
|
68
|
+
ts12_type.alignment = 0;
|
|
69
|
+
ts12_type.type = FFI_TYPE_STRUCT;
|
|
70
|
+
ts12_type.elements = ts12_type_elements;
|
|
71
|
+
ts12_type_elements[0] = &ffi_type_uchar;
|
|
72
|
+
ts12_type_elements[1] = &ts12b_type;
|
|
73
|
+
ts12_type_elements[2] = &ffi_type_uchar;
|
|
74
|
+
ts12_type_elements[3] = NULL;
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
args[0] = &ts12_type;
|
|
78
|
+
args[1] = &ffi_type_pointer;
|
|
79
|
+
values[0] = &ts12_arg;
|
|
80
|
+
values[1] = &ptr;
|
|
81
|
+
|
|
82
|
+
CHECK(ffi_prep_cif(&cif, ABI_NUM, 2, &ts12_type, args) == FFI_OK);
|
|
83
|
+
|
|
84
|
+
ts12_arg.c1 = 5;
|
|
85
|
+
ts12_arg.s[0].d = 5.55;
|
|
86
|
+
ts12_arg.s[0].c = 6;
|
|
87
|
+
ts12_arg.s[1].d = 7.77;
|
|
88
|
+
ts12_arg.s[1].c = 8;
|
|
89
|
+
ts12_arg.c2 = 9;
|
|
90
|
+
|
|
91
|
+
printf ("%u\n", ts12_arg.c1);
|
|
92
|
+
printf ("%g\n", ts12_arg.s[0].d);
|
|
93
|
+
printf ("%u\n", ts12_arg.s[0].c);
|
|
94
|
+
printf ("%g\n", ts12_arg.s[1].d);
|
|
95
|
+
printf ("%u\n", ts12_arg.s[1].c);
|
|
96
|
+
printf ("%u\n", ts12_arg.c2);
|
|
97
|
+
printf ("%d\n", i);
|
|
98
|
+
|
|
99
|
+
ffi_call(&cif, FFI_FN(struct12), ts12_result, values);
|
|
100
|
+
|
|
101
|
+
printf ("%u\n", ts12_result->c1);
|
|
102
|
+
printf ("%g\n", ts12_result->s[0].d);
|
|
103
|
+
printf ("%u\n", ts12_result->s[0].c);
|
|
104
|
+
printf ("%g\n", ts12_result->s[1].d);
|
|
105
|
+
printf ("%u\n", ts12_result->s[1].c);
|
|
106
|
+
printf ("%u\n", ts12_result->c2);
|
|
107
|
+
printf ("%d\n", i);
|
|
108
|
+
CHECK(ts12_result->c1 == 5 + 1);
|
|
109
|
+
CHECK(ts12_result->s[0].d == 5.55 + 1);
|
|
110
|
+
CHECK(ts12_result->s[0].c == 6 + 1);
|
|
111
|
+
CHECK(ts12_result->s[1].d == 7.77 + 1);
|
|
112
|
+
CHECK(ts12_result->s[1].c == 8 + 1);
|
|
113
|
+
CHECK(ts12_result->c2 == 9 + 1);
|
|
114
|
+
CHECK(i == 5 + 1);
|
|
115
|
+
CHECK(ts12_type.size == sizeof(test_structure_12));
|
|
116
|
+
|
|
117
|
+
free (ts12_result);
|
|
118
|
+
exit(0);
|
|
119
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/* Area: ffi_call
|
|
2
|
+
Purpose: Tests if ffi_call reads data beyond end.
|
|
3
|
+
Limitations: needs mmap.
|
|
4
|
+
PR: 887
|
|
5
|
+
Originator: Mikulas Patocka <mikulas@twibright.com> */
|
|
6
|
+
|
|
7
|
+
/* { dg-do run } */
|
|
8
|
+
|
|
9
|
+
#include "ffitest.h"
|
|
10
|
+
|
|
11
|
+
#ifdef __linux__
|
|
12
|
+
#include <sys/mman.h>
|
|
13
|
+
#include <unistd.h>
|
|
14
|
+
|
|
15
|
+
static int ABI_ATTR fn(unsigned char a, unsigned short b, unsigned int c, unsigned long d)
|
|
16
|
+
{
|
|
17
|
+
return (int)(a + b + c + d);
|
|
18
|
+
}
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
int main(void)
|
|
22
|
+
{
|
|
23
|
+
#ifdef __linux__
|
|
24
|
+
ffi_cif cif;
|
|
25
|
+
ffi_type *args[MAX_ARGS];
|
|
26
|
+
void *values[MAX_ARGS];
|
|
27
|
+
ffi_arg rint;
|
|
28
|
+
char *m;
|
|
29
|
+
int ps;
|
|
30
|
+
args[0] = &ffi_type_uchar;
|
|
31
|
+
args[1] = &ffi_type_ushort;
|
|
32
|
+
args[2] = &ffi_type_uint;
|
|
33
|
+
args[3] = &ffi_type_ulong;
|
|
34
|
+
CHECK(ffi_prep_cif(&cif, ABI_NUM, 4, &ffi_type_sint, args) == FFI_OK);
|
|
35
|
+
ps = getpagesize();
|
|
36
|
+
m = mmap(NULL, ps * 3, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
|
37
|
+
CHECK(m != MAP_FAILED);
|
|
38
|
+
CHECK(mprotect(m, ps, PROT_NONE) == 0);
|
|
39
|
+
CHECK(mprotect(m + ps * 2, ps, PROT_NONE) == 0);
|
|
40
|
+
values[0] = m + ps * 2 - sizeof(unsigned char);
|
|
41
|
+
values[1] = m + ps * 2 - sizeof(unsigned short);
|
|
42
|
+
values[2] = m + ps * 2 - sizeof(unsigned int);
|
|
43
|
+
values[3] = m + ps * 2 - sizeof(unsigned long);
|
|
44
|
+
ffi_call(&cif, FFI_FN(fn), &rint, values);
|
|
45
|
+
CHECK((int)rint == 0);
|
|
46
|
+
values[0] = m + ps;
|
|
47
|
+
values[1] = m + ps;
|
|
48
|
+
values[2] = m + ps;
|
|
49
|
+
values[3] = m + ps;
|
|
50
|
+
ffi_call(&cif, FFI_FN(fn), &rint, values);
|
|
51
|
+
CHECK((int)rint == 0);
|
|
52
|
+
#endif
|
|
53
|
+
exit(0);
|
|
54
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/* Area: ffi_call
|
|
2
|
+
Purpose: Demonstrate structures with integers corrupting earlier floats
|
|
3
|
+
Limitations: none.
|
|
4
|
+
PR: #848
|
|
5
|
+
Originator: kellda */
|
|
6
|
+
|
|
7
|
+
/* { dg-do run } */
|
|
8
|
+
#include "ffitest.h"
|
|
9
|
+
|
|
10
|
+
typedef struct
|
|
11
|
+
{
|
|
12
|
+
unsigned long i;
|
|
13
|
+
float f;
|
|
14
|
+
} test_structure_int_float;
|
|
15
|
+
|
|
16
|
+
static float ABI_ATTR struct_int_float(test_structure_int_float ts1,
|
|
17
|
+
test_structure_int_float ts2 __UNUSED__,
|
|
18
|
+
test_structure_int_float ts3 __UNUSED__,
|
|
19
|
+
test_structure_int_float ts4 __UNUSED__,
|
|
20
|
+
test_structure_int_float ts5 __UNUSED__,
|
|
21
|
+
test_structure_int_float ts6 __UNUSED__)
|
|
22
|
+
{
|
|
23
|
+
return ts1.f;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
int main (void)
|
|
27
|
+
{
|
|
28
|
+
ffi_cif cif;
|
|
29
|
+
ffi_type *args[MAX_ARGS];
|
|
30
|
+
void *values[MAX_ARGS];
|
|
31
|
+
ffi_type ts_type;
|
|
32
|
+
ffi_type *ts_type_elements[3];
|
|
33
|
+
float rfloat;
|
|
34
|
+
|
|
35
|
+
test_structure_int_float ts_arg[6];
|
|
36
|
+
|
|
37
|
+
ts_type.size = 0;
|
|
38
|
+
ts_type.alignment = 0;
|
|
39
|
+
ts_type.type = FFI_TYPE_STRUCT;
|
|
40
|
+
ts_type.elements = ts_type_elements;
|
|
41
|
+
ts_type_elements[0] = &ffi_type_ulong;
|
|
42
|
+
ts_type_elements[1] = &ffi_type_float;
|
|
43
|
+
ts_type_elements[2] = NULL;
|
|
44
|
+
|
|
45
|
+
args[0] = &ts_type;
|
|
46
|
+
values[0] = &ts_arg[0];
|
|
47
|
+
args[1] = &ts_type;
|
|
48
|
+
values[1] = &ts_arg[1];
|
|
49
|
+
args[2] = &ts_type;
|
|
50
|
+
values[2] = &ts_arg[2];
|
|
51
|
+
args[3] = &ts_type;
|
|
52
|
+
values[3] = &ts_arg[3];
|
|
53
|
+
args[4] = &ts_type;
|
|
54
|
+
values[4] = &ts_arg[4];
|
|
55
|
+
args[5] = &ts_type;
|
|
56
|
+
values[5] = &ts_arg[5];
|
|
57
|
+
|
|
58
|
+
/* Initialize the cif */
|
|
59
|
+
CHECK(ffi_prep_cif(&cif, ABI_NUM, 6, &ffi_type_float, args) == FFI_OK);
|
|
60
|
+
|
|
61
|
+
ts_arg[0].i = 1;
|
|
62
|
+
ts_arg[0].f = 11.11f;
|
|
63
|
+
ts_arg[1].i = 2;
|
|
64
|
+
ts_arg[1].f = 22.22f;
|
|
65
|
+
ts_arg[2].i = 3;
|
|
66
|
+
ts_arg[2].f = 33.33f;
|
|
67
|
+
ts_arg[3].i = 4;
|
|
68
|
+
ts_arg[3].f = 44.44f;
|
|
69
|
+
ts_arg[4].i = 5;
|
|
70
|
+
ts_arg[4].f = 55.55f;
|
|
71
|
+
ts_arg[5].i = 6;
|
|
72
|
+
ts_arg[5].f = 66.66f;
|
|
73
|
+
|
|
74
|
+
printf ("%g\n", ts_arg[0].f);
|
|
75
|
+
printf ("%g\n", ts_arg[1].f);
|
|
76
|
+
printf ("%g\n", ts_arg[2].f);
|
|
77
|
+
printf ("%g\n", ts_arg[3].f);
|
|
78
|
+
printf ("%g\n", ts_arg[4].f);
|
|
79
|
+
printf ("%g\n", ts_arg[5].f);
|
|
80
|
+
|
|
81
|
+
ffi_call(&cif, FFI_FN(struct_int_float), &rfloat, values);
|
|
82
|
+
|
|
83
|
+
printf ("%g\n", rfloat);
|
|
84
|
+
|
|
85
|
+
CHECK(fabs(rfloat - 11.11) < 3 * FLT_EPSILON);
|
|
86
|
+
|
|
87
|
+
exit(0);
|
|
88
|
+
}
|