• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/ucode/tests/custom/17_lib_ffi/32_struct_values

  1 A structure taken by value is described to libffi by a type descriptor which has
  2 to match the memory layout the ABI uses: a NULL terminated vector of its
  3 members, and a plain byte alignment rather than the base 2 logarithm the CType
  4 stores. Without the vector, initialize_aggregate() cannot derive size and
  5 alignment and ffi_prep_cif() dies while dereferencing the absent members.
  6 
  7 A system library offers no entry point taking a caller defined structure, so
  8 each testcase ships the source of one, compiles it with cc, and abstains when
  9 no C compiler is available.
 10 
 11 Compare two structures taken by value.
 12 
 13 -- Testcase --
 14 {%
 15     import * as ffi from 'ffi';
 16 
 17     let src = TESTFILES_PATH + '/uctestlib.c';
 18     let so = TESTFILES_PATH + '/uctestlib.so';
 19 
 20     if (system([ 'cc', '-shared', '-fPIC', '-o', so, src ]) != 0)
 21         exit(77);
 22 
 23     let lib = ffi.dlopen(so, false, `
 24         struct point { int x; int y; };
 25         int uctest_cmp_val(struct point a, struct point b);
 26     `);
 27 
 28     // Two structures in one signature are only placed at the offsets the ABI
 29     // uses when the descriptor carries an alignment of eight bytes rather than
 30     // the logarithm of it.
 31     print("equal: ", lib.uctest_cmp_val({ x: 1, y: 2 }, { x: 1, y: 2 }), "\n");
 32     print("less:  ", lib.uctest_cmp_val({ x: 1, y: 2 }, { x: 3, y: 4 }), "\n");
 33     print("more:  ", lib.uctest_cmp_val({ x: 3, y: 4 }, { x: 1, y: 2 }), "\n");
 34 %}
 35 -- End --
 36 
 37 -- File uctestlib.c --
 38 struct point {
 39         int x;
 40         int y;
 41 };
 42 
 43 int
 44 uctest_cmp_val(struct point a, struct point b)
 45 {
 46         if (a.x != b.x)
 47                 return a.x < b.x ? -1 : 1;
 48 
 49         return a.y == b.y ? 0 : (a.y < b.y ? -1 : 1);
 50 }
 51 -- End --
 52 
 53 -- Expect stdout --
 54 equal: 0
 55 less:  -1
 56 more:  1
 57 -- End --
 58 
 59 
 60 Add up the members of a nested structure taken by value.
 61 
 62 -- Testcase --
 63 {%
 64     import * as ffi from 'ffi';
 65 
 66     let src = TESTFILES_PATH + '/uctestlib.c';
 67     let so = TESTFILES_PATH + '/uctestlib.so';
 68 
 69     if (system([ 'cc', '-shared', '-fPIC', '-o', so, src ]) != 0)
 70         exit(77);
 71 
 72     let lib = ffi.dlopen(so, false, `
 73         struct point { int x; int y; };
 74         struct nested { struct point p; long sum; };
 75         long uctest_nested_val(struct nested n);
 76     `);
 77 
 78     // A nested structure is a member like any other, so the vector has to be
 79     // built all the way down.
 80     print("nested: ", lib.uctest_nested_val({ p: { x: 1, y: 2 }, sum: 30 }), "\n");
 81 %}
 82 -- End --
 83 
 84 -- File uctestlib.c --
 85 struct point {
 86         int x;
 87         int y;
 88 };
 89 
 90 struct nested {
 91         struct point p;
 92         long sum;
 93 };
 94 
 95 long
 96 uctest_nested_val(struct nested n)
 97 {
 98         return n.p.x + n.p.y + n.sum;
 99 }
100 -- End --
101 
102 -- Expect stdout --
103 nested: 33
104 -- End --
105 
106 
107 Read the members of a wide structure taken by value.
108 
109 -- Testcase --
110 {%
111     import * as ffi from 'ffi';
112 
113     let src = TESTFILES_PATH + '/uctestlib.c';
114     let so = TESTFILES_PATH + '/uctestlib.so';
115 
116     if (system([ 'cc', '-shared', '-fPIC', '-o', so, src ]) != 0)
117         exit(77);
118 
119     let lib = ffi.dlopen(so, false, `
120         struct wide { long a; long b; long c; };
121         long uctest_wide_val(struct wide w);
122     `);
123 
124     // A structure too large for the general purpose registers is passed on the
125     // stack, where the ABI only finds it if the descriptor's size and
126     // alignment describe its memory layout.
127     print("wide: ", lib.uctest_wide_val({ a: 1, b: 2, c: 3 }), "\n");
128 %}
129 -- End --
130 
131 -- File uctestlib.c --
132 struct wide {
133         long a;
134         long b;
135         long c;
136 };
137 
138 long
139 uctest_wide_val(struct wide w)
140 {
141         return w.a * 10000 + w.b * 100 + w.c;
142 }
143 -- End --
144 
145 -- Expect stdout --
146 wide: 10203
147 -- End --

This page was automatically generated by LXR 0.3.1.  •  OpenWrt