1 #include <stdlib.h>
2 #include <stdio.h>
3 
4 #include "libgccjit.h"
5 
6 #include "harness.h"
7 
8 struct bar
9 {
10   int x;
11   int y;
12 };
13 
14 void
create_code(gcc_jit_context * ctxt,void * user_data)15 create_code (gcc_jit_context *ctxt, void *user_data)
16 {
17   /* Let's try to inject the equivalent of:
18 
19      int
20      test_reading (const struct bar *f)
21      {
22        return f->x * f->y;
23      }
24 
25      int
26      test_writing ()
27      {
28        struct bar tmp;
29        tmp.x = 5;
30        tmp.y = 7;
31        return test_reading (&tmp);
32      }
33   */
34   gcc_jit_type *int_type =
35     gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
36   gcc_jit_field *x =
37     gcc_jit_context_new_field (ctxt,
38                                NULL,
39                                int_type,
40                                "x");
41   gcc_jit_field *y =
42     gcc_jit_context_new_field (ctxt,
43                                NULL,
44                                int_type,
45                                "y");
46   gcc_jit_field *fields[] = {x, y};
47   gcc_jit_type *struct_type =
48     gcc_jit_struct_as_type (
49       gcc_jit_context_new_struct_type (ctxt, NULL, "bar", 2, fields));
50   gcc_jit_type *const_struct_type = gcc_jit_type_get_const (struct_type);
51   gcc_jit_type *ptr_type = gcc_jit_type_get_pointer (const_struct_type);
52 
53   /* Build "test_reading".  */
54   gcc_jit_param *param_f =
55     gcc_jit_context_new_param (ctxt, NULL, ptr_type, "f");
56   gcc_jit_function *fn_test_reading =
57     gcc_jit_context_new_function (ctxt, NULL,
58                                   GCC_JIT_FUNCTION_EXPORTED,
59                                   int_type,
60                                   "test_reading",
61                                   1, &param_f,
62                                   0);
63 
64   /* return f->x * f->y; */
65   gcc_jit_block *reading_block = gcc_jit_function_new_block (fn_test_reading, NULL);
66   gcc_jit_block_end_with_return (
67     reading_block,
68     NULL,
69     gcc_jit_context_new_binary_op (
70       ctxt, NULL,
71       GCC_JIT_BINARY_OP_MULT,
72       int_type,
73       gcc_jit_lvalue_as_rvalue (
74 	gcc_jit_rvalue_dereference_field (
75 	  gcc_jit_param_as_rvalue (param_f),
76 	  NULL,
77 	  x)),
78       gcc_jit_lvalue_as_rvalue (
79 	gcc_jit_rvalue_dereference_field (
80 	gcc_jit_param_as_rvalue (param_f),
81 	NULL,
82 	y))));
83 
84   /* Build "test_writing".  */
85   gcc_jit_function *fn_test_writing =
86     gcc_jit_context_new_function (ctxt, NULL,
87                                   GCC_JIT_FUNCTION_EXPORTED,
88                                   int_type,
89                                   "test_writing",
90                                   0, NULL,
91                                   0);
92 
93   /* struct bar tmp; */
94   gcc_jit_lvalue *local_tmp =
95     gcc_jit_function_new_local (fn_test_writing, NULL,
96 				struct_type,
97 				"tmp");
98   /* tmp.x = 5; */
99   gcc_jit_block *writing_block = gcc_jit_function_new_block (fn_test_writing, NULL);
100   gcc_jit_block_add_assignment (
101     writing_block, NULL,
102     gcc_jit_lvalue_access_field (local_tmp, NULL, x),
103     gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 5));
104 
105   /* tmp.y = 7; */
106   gcc_jit_block_add_assignment (
107     writing_block, NULL,
108     gcc_jit_lvalue_access_field (local_tmp, NULL, y),
109     gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 7));
110 
111   /* return test_reading (&tmp); */
112   gcc_jit_rvalue *arg = gcc_jit_lvalue_get_address (local_tmp, NULL);
113   gcc_jit_block_end_with_return (
114     writing_block,
115     NULL,
116     gcc_jit_context_new_call (
117       ctxt, NULL,
118       fn_test_reading,
119       1, &arg));
120 }
121 
122 void
verify_code(gcc_jit_context * ctxt,gcc_jit_result * result)123 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
124 {
125   typedef int (*fn_type) (void);
126   CHECK_NON_NULL (result);
127 
128   fn_type test_writing =
129     (fn_type)gcc_jit_result_get_code (result, "test_writing");
130   CHECK_NON_NULL (test_writing);
131 
132   /* Verify that the code correctly returns the product of the fields.  */
133   CHECK_VALUE (test_writing (), 35);
134 }
135 
136