1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stddef.h>
4 #include <stdbool.h>
5 
6 #include "libgccjit.h"
7 
8 #include "harness.h"
9 
10 struct zoo
11 {
12   void *m_void_ptr;
13 
14   bool m_bool;
15 
16   char m_char;
17   signed char m_signed_char;
18   unsigned char m_unsigned_char;
19 
20   short m_short;
21   unsigned short m_unsigned_short;
22 
23   int m_int;
24   unsigned int m_unsigned_int;
25 
26   long m_long;
27   unsigned long m_unsigned_long;
28 
29   long long m_long_long;
30   unsigned long long m_unsigned_long_long;
31 
32   int m_sized_int_type;
33 
34   float m_float;
35   double m_double;
36   long double m_long_double;
37 
38   const char *m_const_char_ptr;
39 
40   size_t m_size_t;
41 
42   FILE *m_FILE_ptr;
43 };
44 
45 int test_int = 42;
46 int *test_ptr = &test_int;
47 
48 const char *test_string = "test_string";
49 
50 void
create_code(gcc_jit_context * ctxt,void * user_data)51 create_code (gcc_jit_context *ctxt, void *user_data)
52 {
53   /* Let's try to inject the equivalent of:
54 
55      void
56      test_caller (struct zoo *z)
57      {
58 	for each fields "m_field":
59 	  z->m_field = ...some data;
60      }
61   */
62   gcc_jit_type *void_type =
63     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
64 
65 #define CREATE_FIELD(TYPE, NAME) \
66   gcc_jit_context_new_field ( \
67 	ctxt, NULL, \
68 	gcc_jit_context_get_type (ctxt, TYPE), \
69 	NAME)
70 
71   gcc_jit_field *field_m_void_ptr =
72     CREATE_FIELD (GCC_JIT_TYPE_VOID_PTR, "m_void_ptr");
73 
74   gcc_jit_field *field_m_bool =
75     CREATE_FIELD (GCC_JIT_TYPE_BOOL, "m_bool");
76 
77   gcc_jit_field *field_m_char =
78     CREATE_FIELD (GCC_JIT_TYPE_CHAR, "m_char");
79   gcc_jit_field *field_m_signed_char =
80     CREATE_FIELD (GCC_JIT_TYPE_SIGNED_CHAR, "m_signed_char");
81   gcc_jit_field *field_m_unsigned_char =
82     CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_CHAR, "m_unsigned_char");
83 
84   gcc_jit_field *field_m_short =
85     CREATE_FIELD (GCC_JIT_TYPE_SHORT, "m_short");
86   gcc_jit_field *field_m_unsigned_short =
87     CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_SHORT, "m_unsigned_short");
88 
89   gcc_jit_field *field_m_int =
90     CREATE_FIELD (GCC_JIT_TYPE_INT, "m_int");
91   gcc_jit_field *field_m_unsigned_int =
92     CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_INT, "m_unsigned_int");
93 
94   gcc_jit_field *field_m_long =
95     CREATE_FIELD (GCC_JIT_TYPE_LONG, "m_long");
96   gcc_jit_field *field_m_unsigned_long =
97     CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_LONG, "m_unsigned_long");
98 
99   gcc_jit_field *field_m_long_long =
100     CREATE_FIELD (GCC_JIT_TYPE_LONG_LONG, "m_long_long");
101   gcc_jit_field *field_m_unsigned_long_long =
102     CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_LONG_LONG, "m_unsigned_long_long");
103 
104   /* Signed int type with sizeof (int): */
105   gcc_jit_type *sized_int_type =
106     gcc_jit_context_get_int_type (ctxt, sizeof (int), 1);
107   gcc_jit_field *field_m_sized_int_type =
108     gcc_jit_context_new_field (
109       ctxt, NULL, sized_int_type, "m_sized_int_type");
110 
111   gcc_jit_field *field_m_float =
112     CREATE_FIELD (GCC_JIT_TYPE_FLOAT, "m_float");
113   gcc_jit_field *field_m_double =
114     CREATE_FIELD (GCC_JIT_TYPE_DOUBLE, "m_double");
115   gcc_jit_field *field_m_long_double =
116     CREATE_FIELD (GCC_JIT_TYPE_LONG_DOUBLE, "m_long_double");
117 
118   gcc_jit_field *field_m_const_char_ptr =
119     CREATE_FIELD (GCC_JIT_TYPE_CONST_CHAR_PTR, "m_const_char_ptr");
120 
121   gcc_jit_field *field_m_size_t =
122     CREATE_FIELD (GCC_JIT_TYPE_SIZE_T, "m_size_t");
123 
124   gcc_jit_field *field_m_FILE_ptr =
125     CREATE_FIELD (GCC_JIT_TYPE_FILE_PTR, "m_FILE_ptr");
126 
127 #undef CREATE_FIELD
128 
129   gcc_jit_field *zoo_fields[] = {
130     field_m_void_ptr,
131 
132     field_m_bool,
133 
134     field_m_char,
135     field_m_signed_char,
136     field_m_unsigned_char,
137 
138     field_m_short,
139     field_m_unsigned_short,
140 
141     field_m_int,
142     field_m_unsigned_int,
143 
144     field_m_long,
145     field_m_unsigned_long,
146 
147     field_m_long_long,
148     field_m_unsigned_long_long,
149 
150     field_m_sized_int_type,
151 
152     field_m_float,
153     field_m_double,
154     field_m_long_double,
155 
156     field_m_const_char_ptr,
157 
158     field_m_size_t,
159 
160     field_m_FILE_ptr
161   };
162 
163   gcc_jit_type *zoo_type =
164     gcc_jit_struct_as_type (
165       gcc_jit_context_new_struct_type (
166         ctxt,
167 	NULL,
168 	"zoo",
169 	sizeof (zoo_fields) / sizeof (zoo_fields[0]),
170 	zoo_fields));
171 
172   gcc_jit_type *zoo_ptr_type =
173     gcc_jit_type_get_pointer (zoo_type);
174 
175   /* Build the test_fn.	 */
176   gcc_jit_param *param_z =
177     gcc_jit_context_new_param (ctxt, NULL, zoo_ptr_type, "z");
178   gcc_jit_function *test_fn =
179     gcc_jit_context_new_function (ctxt, NULL,
180 				  GCC_JIT_FUNCTION_EXPORTED,
181 				  void_type,
182 				  "test_types",
183 				  1, &param_z,
184 				  0);
185   gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
186 
187   /* Write to the various fields of param "z".	*/
188 #define ASSIGN(FIELD, EXPR) \
189   gcc_jit_block_add_assignment (		\
190     block, NULL,				\
191     gcc_jit_rvalue_dereference_field (		\
192       gcc_jit_param_as_rvalue (param_z),	\
193       NULL,					\
194       (FIELD)),				\
195     (EXPR));
196 
197   ASSIGN(
198     field_m_void_ptr,
199     gcc_jit_context_new_rvalue_from_ptr (
200       ctxt,
201       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID_PTR),
202       test_ptr))
203 
204   ASSIGN(field_m_bool,
205     gcc_jit_context_new_rvalue_from_int (
206       ctxt,
207       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL), 1))
208 
209   ASSIGN(field_m_char,
210     gcc_jit_context_new_rvalue_from_int (
211       ctxt,
212       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR),
213       'V'))
214   ASSIGN(field_m_signed_char,
215     gcc_jit_context_new_rvalue_from_int (
216       ctxt,
217       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_SIGNED_CHAR),
218       -37))
219   ASSIGN(field_m_unsigned_char,
220     gcc_jit_context_new_rvalue_from_int (
221       ctxt,
222       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR),
223       200))
224 
225   ASSIGN(field_m_short,
226     gcc_jit_context_new_rvalue_from_int (
227       ctxt,
228       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_SHORT),
229       -900))
230   ASSIGN(field_m_unsigned_short,
231     gcc_jit_context_new_rvalue_from_int (
232       ctxt,
233       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_SHORT),
234       0x3000))
235 
236   ASSIGN(field_m_int,
237     gcc_jit_context_new_rvalue_from_int (
238       ctxt,
239       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT),
240       -0x2000))
241   ASSIGN(field_m_unsigned_int,
242     gcc_jit_context_new_rvalue_from_int (
243       ctxt,
244       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_INT),
245       1234567))
246 
247   ASSIGN(field_m_long,
248     gcc_jit_context_new_rvalue_from_int (
249       ctxt,
250       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG),
251       -5))
252   ASSIGN(field_m_unsigned_long,
253     gcc_jit_context_new_rvalue_from_int (
254       ctxt,
255       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_LONG),
256       12345678))
257 
258   ASSIGN(field_m_long_long,
259     gcc_jit_context_new_rvalue_from_int (
260       ctxt,
261       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG_LONG),
262       -42))
263   ASSIGN(field_m_unsigned_long_long,
264     gcc_jit_context_new_rvalue_from_int (
265       ctxt,
266       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_LONG_LONG),
267       123456789))
268 
269   ASSIGN(field_m_sized_int_type,
270     gcc_jit_context_new_rvalue_from_int (
271       ctxt,
272       sized_int_type, 500))
273 
274   ASSIGN(field_m_float,
275     gcc_jit_context_new_rvalue_from_double (
276       ctxt,
277       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT),
278       3.141))
279   ASSIGN(field_m_double,
280     gcc_jit_context_new_rvalue_from_double (
281       ctxt,
282       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE),
283       3.141))
284   ASSIGN(field_m_long_double,
285     gcc_jit_context_new_rvalue_from_double (
286       ctxt,
287       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG_DOUBLE),
288       3.141))
289 
290   ASSIGN(field_m_const_char_ptr,
291     gcc_jit_context_new_rvalue_from_ptr (
292       ctxt,
293       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR),
294       (char *)test_string))
295 
296   ASSIGN(field_m_size_t,
297     gcc_jit_context_new_rvalue_from_int (
298       ctxt,
299       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_SIZE_T),
300       sizeof (struct zoo)))
301 
302   ASSIGN(field_m_FILE_ptr,
303     gcc_jit_context_new_rvalue_from_ptr (
304       ctxt,
305       gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FILE_PTR),
306       stderr))
307 
308 #undef ASSIGN
309 
310   gcc_jit_block_end_with_void_return (block, NULL);
311 }
312 
313 void
verify_code(gcc_jit_context * ctxt,gcc_jit_result * result)314 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
315 {
316   typedef void (*fn_type) (struct zoo *);
317   CHECK_NON_NULL (result);
318 
319   fn_type test_types =
320     (fn_type)gcc_jit_result_get_code (result, "test_types");
321   CHECK_NON_NULL (test_types);
322 
323   struct zoo z;
324   memset (&z, 0xf0, sizeof (z));
325 
326   /* Call the JIT-generated function.  */
327   test_types (&z);
328 
329   /* Verify that it correctly wrote to the various fields.  */
330   CHECK_VALUE (z.m_void_ptr, test_ptr);
331 
332   CHECK_VALUE (z.m_bool, true);
333 
334   CHECK_VALUE (z.m_char, 'V');
335   CHECK_VALUE (z.m_signed_char, -37);
336   CHECK_VALUE (z.m_unsigned_char, 200);
337 
338   CHECK_VALUE (z.m_short, -900);
339   CHECK_VALUE (z.m_unsigned_short, 0x3000);
340 
341   CHECK_VALUE (z.m_int, -0x2000);
342   CHECK_VALUE (z.m_unsigned_int, 1234567);
343 
344   CHECK_VALUE (z.m_long, -5);
345   CHECK_VALUE (z.m_unsigned_long, 12345678);
346 
347   CHECK_VALUE (z.m_long_long, -42);
348   CHECK_VALUE (z.m_unsigned_long_long, 123456789);
349 
350   CHECK_VALUE (z.m_sized_int_type, 500);
351 
352   CHECK_VALUE (z.m_float, 3.141f);
353   CHECK_VALUE (z.m_double, 3.141);
354   CHECK_VALUE (z.m_long_double, 3.141);
355 
356   CHECK_VALUE (z.m_const_char_ptr, test_string);
357 
358   CHECK_VALUE (z.m_size_t, sizeof (struct zoo));
359 
360   CHECK_VALUE (z.m_FILE_ptr, stderr);
361 }
362