1 A complex number is one of libffi's predefined types. It cannot be described as 2 a struct of two reals instead: libffi passes such a description differently than 3 the predefined type, so which of the two a descriptor is decides whether a call 4 passes the right values. 5 6 A libffi backend provides the predefined complex types only when it defines 7 FFI_TARGET_HAS_COMPLEX_TYPE, which powerpc does not, so where they are 8 unavailable a declaration naming one is rejected rather than answered with a 9 description that would pass bogus values. 10 11 A system library offers no entry point of a caller's choosing that takes a 12 complex number, so each testcase ships the source of one, compiles it with cc, 13 and abstains when no C compiler or predefined libffi complex type is available. 14 15 Take a complex number by value. 16 17 -- Testcase -- 18 {% 19 import * as ffi from 'ffi'; 20 21 if (ffi.C.dlsym('ffi_type_complex_double') == null) 22 exit(77); 23 24 let src = TESTFILES_PATH + '/uctestlib.c'; 25 let so = TESTFILES_PATH + '/uctestlib.so'; 26 27 if (system([ 'cc', '-shared', '-fPIC', '-o', so, src ]) != 0) 28 exit(77); 29 30 let lib = ffi.dlopen(so, false, ` 31 double uctest_compl_real(double complex z); 32 double uctest_compl_imag(double complex z); 33 `); 34 35 print("real: ", lib.uctest_compl_real([3.0, 4.0]), "\n"); 36 print("imag: ", lib.uctest_compl_imag([3.0, 4.0]), "\n"); 37 %} 38 -- End -- 39 40 -- File uctestlib.c -- 41 double 42 uctest_compl_real(double _Complex z) 43 { 44 return __real__ z; 45 } 46 47 double 48 uctest_compl_imag(double _Complex z) 49 { 50 return __imag__ z; 51 } 52 -- End -- 53 54 -- Expect stdout -- 55 real: 3 56 imag: 4 57 -- End -- 58 59 Take two complex numbers by value. 60 61 -- Testcase -- 62 {% 63 import * as ffi from 'ffi'; 64 65 if (ffi.C.dlsym('ffi_type_complex_double') == null) 66 exit(77); 67 68 let src = TESTFILES_PATH + '/uctestlib.c'; 69 let so = TESTFILES_PATH + '/uctestlib.so'; 70 71 if (system([ 'cc', '-shared', '-fPIC', '-o', so, src ]) != 0) 72 exit(77); 73 74 let lib = ffi.dlopen(so, false, ` 75 double uctest_compl_add_real(double complex a, double complex b); 76 `); 77 78 print("sum: ", lib.uctest_compl_add_real([1.5, 0.0], [2.25, 0.0]), "\n"); 79 %} 80 -- End -- 81 82 -- File uctestlib.c -- 83 double 84 uctest_compl_add_real(double _Complex a, double _Complex b) 85 { 86 return __real__ a + __real__ b; 87 } 88 -- End -- 89 90 -- Expect stdout -- 91 sum: 3.75 92 -- End -- 93 94 Scale a complex number by a double following it. 95 96 -- Testcase -- 97 {% 98 import * as ffi from 'ffi'; 99 100 if (ffi.C.dlsym('ffi_type_complex_double') == null) 101 exit(77); 102 103 let src = TESTFILES_PATH + '/uctestlib.c'; 104 let so = TESTFILES_PATH + '/uctestlib.so'; 105 106 if (system([ 'cc', '-shared', '-fPIC', '-o', so, src ]) != 0) 107 exit(77); 108 109 let lib = ffi.dlopen(so, false, ` 110 double complex uctest_compl_scale(double complex z, double s); 111 `); 112 113 // A double following a complex number is only found where the ABI puts it 114 // when the complex argument is described by its predefined type. 115 print("scaled: ", lib.uctest_compl_scale([1.5, -2.5], 2.0), "\n"); 116 %} 117 -- End -- 118 119 -- File uctestlib.c -- 120 double _Complex 121 uctest_compl_scale(double _Complex z, double s) 122 { 123 double _Complex r; 124 125 __real__ r = __real__ z * s; 126 __imag__ r = __imag__ z * s; 127 128 return r; 129 } 130 -- End -- 131 132 -- Expect stdout -- 133 scaled: [ 3.0, -5.0 ] 134 -- End --
This page was automatically generated by LXR 0.3.1. • OpenWrt