#include #include #include #include #include "libgccjit.h" #include "harness.h" struct zoo { void *m_void_ptr; bool m_bool; char m_char; signed char m_signed_char; unsigned char m_unsigned_char; short m_short; unsigned short m_unsigned_short; int m_int; unsigned int m_unsigned_int; long m_long; unsigned long m_unsigned_long; long long m_long_long; unsigned long long m_unsigned_long_long; int m_sized_int_type; float m_float; double m_double; long double m_long_double; const char *m_const_char_ptr; size_t m_size_t; FILE *m_FILE_ptr; }; int test_int = 42; int *test_ptr = &test_int; const char *test_string = "test_string"; void create_code (gcc_jit_context *ctxt, void *user_data) { /* Let's try to inject the equivalent of: void test_caller (struct zoo *z) { for each fields "m_field": z->m_field = ...some data; } */ gcc_jit_type *void_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); #define CREATE_FIELD(TYPE, NAME) \ gcc_jit_context_new_field ( \ ctxt, NULL, \ gcc_jit_context_get_type (ctxt, TYPE), \ NAME) gcc_jit_field *field_m_void_ptr = CREATE_FIELD (GCC_JIT_TYPE_VOID_PTR, "m_void_ptr"); gcc_jit_field *field_m_bool = CREATE_FIELD (GCC_JIT_TYPE_BOOL, "m_bool"); gcc_jit_field *field_m_char = CREATE_FIELD (GCC_JIT_TYPE_CHAR, "m_char"); gcc_jit_field *field_m_signed_char = CREATE_FIELD (GCC_JIT_TYPE_SIGNED_CHAR, "m_signed_char"); gcc_jit_field *field_m_unsigned_char = CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_CHAR, "m_unsigned_char"); gcc_jit_field *field_m_short = CREATE_FIELD (GCC_JIT_TYPE_SHORT, "m_short"); gcc_jit_field *field_m_unsigned_short = CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_SHORT, "m_unsigned_short"); gcc_jit_field *field_m_int = CREATE_FIELD (GCC_JIT_TYPE_INT, "m_int"); gcc_jit_field *field_m_unsigned_int = CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_INT, "m_unsigned_int"); gcc_jit_field *field_m_long = CREATE_FIELD (GCC_JIT_TYPE_LONG, "m_long"); gcc_jit_field *field_m_unsigned_long = CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_LONG, "m_unsigned_long"); gcc_jit_field *field_m_long_long = CREATE_FIELD (GCC_JIT_TYPE_LONG_LONG, "m_long_long"); gcc_jit_field *field_m_unsigned_long_long = CREATE_FIELD (GCC_JIT_TYPE_UNSIGNED_LONG_LONG, "m_unsigned_long_long"); /* Signed int type with sizeof (int): */ gcc_jit_type *sized_int_type = gcc_jit_context_get_int_type (ctxt, sizeof (int), 1); gcc_jit_field *field_m_sized_int_type = gcc_jit_context_new_field ( ctxt, NULL, sized_int_type, "m_sized_int_type"); gcc_jit_field *field_m_float = CREATE_FIELD (GCC_JIT_TYPE_FLOAT, "m_float"); gcc_jit_field *field_m_double = CREATE_FIELD (GCC_JIT_TYPE_DOUBLE, "m_double"); gcc_jit_field *field_m_long_double = CREATE_FIELD (GCC_JIT_TYPE_LONG_DOUBLE, "m_long_double"); gcc_jit_field *field_m_const_char_ptr = CREATE_FIELD (GCC_JIT_TYPE_CONST_CHAR_PTR, "m_const_char_ptr"); gcc_jit_field *field_m_size_t = CREATE_FIELD (GCC_JIT_TYPE_SIZE_T, "m_size_t"); gcc_jit_field *field_m_FILE_ptr = CREATE_FIELD (GCC_JIT_TYPE_FILE_PTR, "m_FILE_ptr"); #undef CREATE_FIELD gcc_jit_field *zoo_fields[] = { field_m_void_ptr, field_m_bool, field_m_char, field_m_signed_char, field_m_unsigned_char, field_m_short, field_m_unsigned_short, field_m_int, field_m_unsigned_int, field_m_long, field_m_unsigned_long, field_m_long_long, field_m_unsigned_long_long, field_m_sized_int_type, field_m_float, field_m_double, field_m_long_double, field_m_const_char_ptr, field_m_size_t, field_m_FILE_ptr }; gcc_jit_type *zoo_type = gcc_jit_struct_as_type ( gcc_jit_context_new_struct_type ( ctxt, NULL, "zoo", sizeof (zoo_fields) / sizeof (zoo_fields[0]), zoo_fields)); gcc_jit_type *zoo_ptr_type = gcc_jit_type_get_pointer (zoo_type); /* Build the test_fn. */ gcc_jit_param *param_z = gcc_jit_context_new_param (ctxt, NULL, zoo_ptr_type, "z"); gcc_jit_function *test_fn = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, void_type, "test_types", 1, ¶m_z, 0); gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); /* Write to the various fields of param "z". */ #define ASSIGN(FIELD, EXPR) \ gcc_jit_block_add_assignment ( \ block, NULL, \ gcc_jit_rvalue_dereference_field ( \ gcc_jit_param_as_rvalue (param_z), \ NULL, \ (FIELD)), \ (EXPR)); ASSIGN( field_m_void_ptr, gcc_jit_context_new_rvalue_from_ptr ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID_PTR), test_ptr)) ASSIGN(field_m_bool, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL), 1)) ASSIGN(field_m_char, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR), 'V')) ASSIGN(field_m_signed_char, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_SIGNED_CHAR), -37)) ASSIGN(field_m_unsigned_char, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR), 200)) ASSIGN(field_m_short, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_SHORT), -900)) ASSIGN(field_m_unsigned_short, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_SHORT), 0x3000)) ASSIGN(field_m_int, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT), -0x2000)) ASSIGN(field_m_unsigned_int, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_INT), 1234567)) ASSIGN(field_m_long, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG), -5)) ASSIGN(field_m_unsigned_long, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_LONG), 12345678)) ASSIGN(field_m_long_long, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG_LONG), -42)) ASSIGN(field_m_unsigned_long_long, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_LONG_LONG), 123456789)) ASSIGN(field_m_sized_int_type, gcc_jit_context_new_rvalue_from_int ( ctxt, sized_int_type, 500)) ASSIGN(field_m_float, gcc_jit_context_new_rvalue_from_double ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT), 3.141)) ASSIGN(field_m_double, gcc_jit_context_new_rvalue_from_double ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE), 3.141)) ASSIGN(field_m_long_double, gcc_jit_context_new_rvalue_from_double ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_LONG_DOUBLE), 3.141)) ASSIGN(field_m_const_char_ptr, gcc_jit_context_new_rvalue_from_ptr ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR), (char *)test_string)) ASSIGN(field_m_size_t, gcc_jit_context_new_rvalue_from_int ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_SIZE_T), sizeof (struct zoo))) ASSIGN(field_m_FILE_ptr, gcc_jit_context_new_rvalue_from_ptr ( ctxt, gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FILE_PTR), stderr)) #undef ASSIGN gcc_jit_block_end_with_void_return (block, NULL); } void verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) { typedef void (*fn_type) (struct zoo *); CHECK_NON_NULL (result); fn_type test_types = (fn_type)gcc_jit_result_get_code (result, "test_types"); CHECK_NON_NULL (test_types); struct zoo z; memset (&z, 0xf0, sizeof (z)); /* Call the JIT-generated function. */ test_types (&z); /* Verify that it correctly wrote to the various fields. */ CHECK_VALUE (z.m_void_ptr, test_ptr); CHECK_VALUE (z.m_bool, true); CHECK_VALUE (z.m_char, 'V'); CHECK_VALUE (z.m_signed_char, -37); CHECK_VALUE (z.m_unsigned_char, 200); CHECK_VALUE (z.m_short, -900); CHECK_VALUE (z.m_unsigned_short, 0x3000); CHECK_VALUE (z.m_int, -0x2000); CHECK_VALUE (z.m_unsigned_int, 1234567); CHECK_VALUE (z.m_long, -5); CHECK_VALUE (z.m_unsigned_long, 12345678); CHECK_VALUE (z.m_long_long, -42); CHECK_VALUE (z.m_unsigned_long_long, 123456789); CHECK_VALUE (z.m_sized_int_type, 500); CHECK_VALUE (z.m_float, 3.141f); CHECK_VALUE (z.m_double, 3.141); CHECK_VALUE (z.m_long_double, 3.141); CHECK_VALUE (z.m_const_char_ptr, test_string); CHECK_VALUE (z.m_size_t, sizeof (struct zoo)); CHECK_VALUE (z.m_FILE_ptr, stderr); }