void create_code (gcc_jit_context *ctxt, void *user_data) { /* Let's try to inject the equivalent of: void test_bogus_access (struct foo f) { f.x = f.p; } i.e. using the wrong struct for the RHS. */ gcc_jit_type *void_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); /* Map "struct foo". */ gcc_jit_field *x = gcc_jit_context_new_field (ctxt, NULL, int_type, "x"); gcc_jit_field *y = gcc_jit_context_new_field (ctxt, NULL, int_type, "y"); gcc_jit_field *foo_fields[] = {x, y}; gcc_jit_struct *struct_foo = gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 2, foo_fields); /* Map "struct bar". */ gcc_jit_field *p = gcc_jit_context_new_field (ctxt, NULL, int_type, "p"); gcc_jit_field *q = gcc_jit_context_new_field (ctxt, NULL, int_type, "q"); /* We don't actually need a gcc_jit_type for "struct bar" for the test. */ gcc_jit_field *bar_fields[] = {p, q}; (void)gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 2, bar_fields); /* Build the test function. */ gcc_jit_param *param_f = gcc_jit_context_new_param (ctxt, NULL, gcc_jit_struct_as_type (struct_foo), "f"); gcc_jit_function *test_fn = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, void_type, "test_bogus_access", 1, ¶m_f, 0); /* OK: f.x = ... */ gcc_jit_lvalue *lvalue = gcc_jit_lvalue_access_field ( gcc_jit_param_as_lvalue (param_f), NULL, x); /* Erroneous: ... = f.p; */ gcc_jit_rvalue *rvalue = gcc_jit_rvalue_access_field ( gcc_jit_param_as_rvalue (param_f), NULL, p); gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); gcc_jit_block_add_assignment ( block, NULL, lvalue, rvalue); gcc_jit_block_end_with_void_return (block, NULL); }
void create_code (gcc_jit_context *ctxt, void *user_data) { /* Let's try to inject the equivalent of: float test_union (int i) { union int_or_float u; u.as_int = i; return u.as_float; } */ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); gcc_jit_field *as_int = gcc_jit_context_new_field (ctxt, NULL, int_type, "as_int"); gcc_jit_field *as_float = gcc_jit_context_new_field (ctxt, NULL, float_type, "as_float"); gcc_jit_field *fields[] = {as_int, as_float}; gcc_jit_type *union_type = gcc_jit_context_new_union_type (ctxt, NULL, "int_or_float", 2, fields); /* Build the test function. */ gcc_jit_param *param_i = gcc_jit_context_new_param (ctxt, NULL, int_type, "i"); gcc_jit_function *test_fn = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, float_type, "test_union", 1, ¶m_i, 0); gcc_jit_lvalue *u = gcc_jit_function_new_local (test_fn, NULL, union_type, "u"); gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); /* u.as_int = i; */ gcc_jit_block_add_assignment ( block, NULL, /* "u.as_int = ..." */ gcc_jit_lvalue_access_field (u, NULL, as_int), gcc_jit_param_as_rvalue (param_i)); /* return u.as_float; */ gcc_jit_block_end_with_return ( block, NULL, gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (u), NULL, as_float)); }
static void make_test_quadratic (struct top_level *top_level, struct middle_level *middle_level, struct bottom_level *bottom_level) { gcc_jit_param *a = gcc_jit_context_new_param (bottom_level->ctxt, NULL, top_level->numeric_type, "a"); gcc_jit_param *b = gcc_jit_context_new_param (bottom_level->ctxt, NULL, top_level->numeric_type, "b"); gcc_jit_param *c = gcc_jit_context_new_param (bottom_level->ctxt, NULL, top_level->numeric_type, "c"); gcc_jit_param *r1 = gcc_jit_context_new_param (bottom_level->ctxt, NULL, top_level->numeric_type_ptr, "r1"); gcc_jit_param *r2 = gcc_jit_context_new_param (bottom_level->ctxt, NULL, top_level->numeric_type_ptr, "r2"); gcc_jit_param *params[] = {a, b, c, r1, r2}; gcc_jit_function *test_quadratic = gcc_jit_context_new_function (bottom_level->ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, top_level->int_type, "test_quadratic", 5, params, 0); /* struct quadratic q; */ gcc_jit_lvalue *q = gcc_jit_function_new_local ( test_quadratic, NULL, top_level->struct_quadratic, "q"); gcc_jit_block *initial = gcc_jit_function_new_block (test_quadratic, "initial"); gcc_jit_block *on_positive_discriminant = gcc_jit_function_new_block (test_quadratic, "positive_discriminant"); gcc_jit_block *on_nonpositive_discriminant = gcc_jit_function_new_block (test_quadratic, "nonpositive_discriminant"); gcc_jit_block *on_zero_discriminant = gcc_jit_function_new_block (test_quadratic, "zero_discriminant"); gcc_jit_block *on_negative_discriminant = gcc_jit_function_new_block (test_quadratic, "negative_discriminant"); /* Initial block. */ /* q.a = a; */ gcc_jit_block_add_assignment ( initial, NULL, gcc_jit_lvalue_access_field (q, NULL, top_level->a), gcc_jit_param_as_rvalue (a)); /* q.b = b; */ gcc_jit_block_add_assignment ( initial, NULL, gcc_jit_lvalue_access_field (q, NULL, top_level->b), gcc_jit_param_as_rvalue (b)); /* q.c = c; */ gcc_jit_block_add_assignment ( initial, NULL, gcc_jit_lvalue_access_field (q, NULL, top_level->c), gcc_jit_param_as_rvalue (c)); /* calc_discriminant (&q); */ gcc_jit_rvalue *address_of_q = gcc_jit_lvalue_get_address (q, NULL); gcc_jit_block_add_eval ( initial, NULL, gcc_jit_context_new_call ( bottom_level->ctxt, NULL, middle_level->calc_discriminant, 1, &address_of_q)); gcc_jit_block_add_comment ( initial, NULL, "if (q.discriminant > 0)"); gcc_jit_block_end_with_conditional ( initial, NULL, gcc_jit_context_new_comparison ( bottom_level->ctxt, NULL, GCC_JIT_COMPARISON_GT, gcc_jit_rvalue_access_field ( gcc_jit_lvalue_as_rvalue (q), NULL, top_level->discriminant), top_level->zero), on_positive_discriminant, on_nonpositive_discriminant); /* Block: "on_positive_discriminant" */ /* double s = sqrt (q.discriminant); */ gcc_jit_lvalue *s = gcc_jit_function_new_local ( test_quadratic, NULL, top_level->numeric_type, "s"); gcc_jit_rvalue *discriminant_of_q = gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (q), NULL, top_level->discriminant); gcc_jit_block_add_assignment ( on_positive_discriminant, NULL, s, gcc_jit_context_new_call ( bottom_level->ctxt, NULL, top_level->sqrt, 1, &discriminant_of_q)); gcc_jit_rvalue *minus_b = gcc_jit_context_new_unary_op ( bottom_level->ctxt, NULL, GCC_JIT_UNARY_OP_MINUS, top_level->numeric_type, gcc_jit_param_as_rvalue (b)); gcc_jit_rvalue *two_a = gcc_jit_context_new_binary_op ( bottom_level->ctxt, NULL, GCC_JIT_BINARY_OP_MULT, top_level->numeric_type, gcc_jit_context_new_rvalue_from_int ( bottom_level->ctxt, top_level->numeric_type, 2), gcc_jit_param_as_rvalue (a)); gcc_jit_block_add_comment ( on_positive_discriminant, NULL, "*r1 = (-b + s) / (2 * a);"); gcc_jit_block_add_assignment ( on_positive_discriminant, NULL, /* "*r1 = ..." */ gcc_jit_rvalue_dereference ( gcc_jit_param_as_rvalue (r1), NULL), /* (-b + s) / (2 * a) */ gcc_jit_context_new_binary_op ( bottom_level->ctxt, NULL, GCC_JIT_BINARY_OP_DIVIDE, top_level->numeric_type, gcc_jit_context_new_binary_op ( bottom_level->ctxt, NULL, GCC_JIT_BINARY_OP_PLUS, top_level->numeric_type, minus_b, gcc_jit_lvalue_as_rvalue (s)), two_a)); gcc_jit_block_add_comment ( on_positive_discriminant, NULL, "*r2 = (-b - s) / (2 * a)"); gcc_jit_block_add_assignment ( on_positive_discriminant, NULL, /* "*r2 = ..." */ gcc_jit_rvalue_dereference ( gcc_jit_param_as_rvalue (r2), NULL), /* (-b - s) / (2 * a) */ gcc_jit_context_new_binary_op ( bottom_level->ctxt, NULL, GCC_JIT_BINARY_OP_DIVIDE, top_level->numeric_type, gcc_jit_context_new_binary_op ( bottom_level->ctxt, NULL, GCC_JIT_BINARY_OP_MINUS, top_level->numeric_type, minus_b, gcc_jit_lvalue_as_rvalue (s)), two_a)); /* "return 2;" */ gcc_jit_block_end_with_return ( on_positive_discriminant, NULL, gcc_jit_context_new_rvalue_from_int ( bottom_level->ctxt, top_level->int_type, 2)); /* Block: "on_nonpositive_discriminant" */ gcc_jit_block_add_comment ( on_nonpositive_discriminant, NULL, "else if (q.discriminant == 0)"); gcc_jit_block_end_with_conditional ( on_nonpositive_discriminant, NULL, gcc_jit_context_new_comparison ( bottom_level->ctxt, NULL, GCC_JIT_COMPARISON_EQ, gcc_jit_rvalue_access_field ( gcc_jit_lvalue_as_rvalue (q), NULL, top_level->discriminant), top_level->zero), on_zero_discriminant, on_negative_discriminant); /* Block: "on_zero_discriminant" */ gcc_jit_block_add_comment ( on_zero_discriminant, NULL, "*r1 = -b / (2 * a);"); gcc_jit_block_add_assignment ( on_zero_discriminant, NULL, /* "*r1 = ..." */ gcc_jit_rvalue_dereference ( gcc_jit_param_as_rvalue (r1), NULL), /* -b / (2 * a) */ gcc_jit_context_new_binary_op ( bottom_level->ctxt, NULL, GCC_JIT_BINARY_OP_DIVIDE, top_level->numeric_type, minus_b, two_a)); /* "return 1;" */ gcc_jit_block_end_with_return ( on_zero_discriminant, NULL, gcc_jit_context_one (bottom_level->ctxt, top_level->int_type)); /* Block: "on_negative_discriminant" */ gcc_jit_block_end_with_return ( /* else return 0; */ on_negative_discriminant, NULL, gcc_jit_context_zero (bottom_level->ctxt, top_level->int_type)); }