test-calling-function-ptr.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include "libgccjit.h"
  4. #include "harness.h"
  5. void
  6. create_code (gcc_jit_context *ctxt, void *user_data)
  7. {
  8. /* Let's try to inject the equivalent of:
  9. void
  10. test_calling_function_ptr (void (*fn_ptr) (int, int, int) fn_ptr,
  11. int a)
  12. {
  13. fn_ptr (a * 3, a * 4, a * 5);
  14. }
  15. */
  16. int i;
  17. gcc_jit_type *void_type =
  18. gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
  19. gcc_jit_type *int_type =
  20. gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
  21. /* Build the function ptr type. */
  22. gcc_jit_type *param_types[3];
  23. param_types[0] = int_type;
  24. param_types[1] = int_type;
  25. param_types[2] = int_type;
  26. gcc_jit_type *fn_ptr_type =
  27. gcc_jit_context_new_function_ptr_type (ctxt, NULL,
  28. void_type,
  29. 3, param_types, 0);
  30. /* Ensure that function ptr types have sane debug strings. */
  31. CHECK_STRING_VALUE (
  32. gcc_jit_object_get_debug_string (gcc_jit_type_as_object (fn_ptr_type)),
  33. "void (*) (int, int, int)");
  34. /* Build the test_fn. */
  35. gcc_jit_param *param_fn_ptr =
  36. gcc_jit_context_new_param (ctxt, NULL, fn_ptr_type, "fn_ptr");
  37. gcc_jit_param *param_a =
  38. gcc_jit_context_new_param (ctxt, NULL, int_type, "a");
  39. gcc_jit_param *params[2];
  40. params[0] = param_fn_ptr;
  41. params[1] = param_a;
  42. gcc_jit_function *test_fn =
  43. gcc_jit_context_new_function (ctxt, NULL,
  44. GCC_JIT_FUNCTION_EXPORTED,
  45. void_type,
  46. "test_calling_function_ptr",
  47. 2, params,
  48. 0);
  49. /* "a * 3, a * 4, a * 5" */
  50. gcc_jit_rvalue *args[3];
  51. for (i = 0; i < 3; i++)
  52. args[i] =
  53. gcc_jit_context_new_binary_op (
  54. ctxt, NULL,
  55. GCC_JIT_BINARY_OP_MULT,
  56. int_type,
  57. gcc_jit_param_as_rvalue (param_a),
  58. gcc_jit_context_new_rvalue_from_int (
  59. ctxt,
  60. int_type,
  61. (i + 3) ));
  62. gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
  63. gcc_jit_block_add_eval (
  64. block, NULL,
  65. gcc_jit_context_new_call_through_ptr (
  66. ctxt,
  67. NULL,
  68. gcc_jit_param_as_rvalue (param_fn_ptr),
  69. 3, args));
  70. gcc_jit_block_end_with_void_return (block, NULL);
  71. }
  72. static int called_through_ptr_with[3];
  73. static void
  74. function_called_through_fn_ptr (int i, int j, int k)
  75. {
  76. called_through_ptr_with[0] = i;
  77. called_through_ptr_with[1] = j;
  78. called_through_ptr_with[2] = k;
  79. }
  80. void
  81. verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
  82. {
  83. typedef void (*fn_type) (void (*fn_ptr) (int, int, int),
  84. int);
  85. CHECK_NON_NULL (result);
  86. fn_type test_caller =
  87. (fn_type)gcc_jit_result_get_code (result, "test_calling_function_ptr");
  88. CHECK_NON_NULL (test_caller);
  89. called_through_ptr_with[0] = 0;
  90. called_through_ptr_with[1] = 0;
  91. called_through_ptr_with[2] = 0;
  92. /* Call the JIT-generated function. */
  93. test_caller (function_called_through_fn_ptr, 5);
  94. /* Verify that it correctly called "function_called_through_fn_ptr". */
  95. CHECK_VALUE (called_through_ptr_with[0], 15);
  96. CHECK_VALUE (called_through_ptr_with[1], 20);
  97. CHECK_VALUE (called_through_ptr_with[2], 25);
  98. }