1/* Area: ffi_closure, unwind info 2 Purpose: Check if the unwind information is passed correctly. 3 Limitations: none. 4 PR: none. 5 Originator: Jeff Sturm <jsturm@one-point.com> */ 6 7/* { dg-do run } */ 8 9#include "ffitestcxx.h" 10 11#if defined HAVE_STDINT_H 12#include <stdint.h> 13#endif 14 15#if defined HAVE_INTTYPES_H 16#include <inttypes.h> 17#endif 18 19void 20closure_test_fn(ffi_cif* cif __UNUSED__, void* resp __UNUSED__, 21 void** args __UNUSED__, void* userdata __UNUSED__) 22{ 23 throw 9; 24} 25 26typedef void (*closure_test_type)(); 27 28void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, 29 void** args, void* userdata __UNUSED__) 30 { 31 *(ffi_arg*)resp = 32 (int)*(float *)args[0] +(int)(*(float *)args[1]) + 33 (int)(*(float *)args[2]) + (int)*(float *)args[3] + 34 (int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) + 35 (int)*(float *)args[6] + (int)(*(int *)args[7]) + 36 (int)(*(double*)args[8]) + (int)*(int *)args[9] + 37 (int)(*(int *)args[10]) + (int)(*(float *)args[11]) + 38 (int)*(int *)args[12] + (int)(*(int *)args[13]) + 39 (int)(*(int *)args[14]) + *(int *)args[15] + (int)(intptr_t)userdata; 40 41 printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n", 42 (int)*(float *)args[0], (int)(*(float *)args[1]), 43 (int)(*(float *)args[2]), (int)*(float *)args[3], 44 (int)(*(signed short *)args[4]), (int)(*(float *)args[5]), 45 (int)*(float *)args[6], (int)(*(int *)args[7]), 46 (int)(*(double *)args[8]), (int)*(int *)args[9], 47 (int)(*(int *)args[10]), (int)(*(float *)args[11]), 48 (int)*(int *)args[12], (int)(*(int *)args[13]), 49 (int)(*(int *)args[14]), *(int *)args[15], 50 (int)(intptr_t)userdata, (int)*(ffi_arg*)resp); 51 52 throw (int)*(ffi_arg*)resp; 53} 54 55typedef int (*closure_test_type1)(float, float, float, float, signed short, 56 float, float, int, double, int, int, float, 57 int, int, int, int); 58 59int main (void) 60{ 61 ffi_cif cif; 62 void *code; 63 ffi_closure *pcl = (ffi_closure *)ffi_closure_alloc(sizeof(ffi_closure), &code); 64 ffi_type * cl_arg_types[17]; 65 66 { 67 cl_arg_types[1] = NULL; 68 69 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, 70 &ffi_type_void, cl_arg_types) == FFI_OK); 71 CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn, NULL, code) == FFI_OK); 72 73 try 74 { 75 (*((closure_test_type)(code)))(); 76 } catch (int exception_code) 77 { 78 CHECK(exception_code == 9); 79 } 80 81 printf("part one OK\n"); 82 /* { dg-output "part one OK" } */ 83 } 84 85 { 86 87 cl_arg_types[0] = &ffi_type_float; 88 cl_arg_types[1] = &ffi_type_float; 89 cl_arg_types[2] = &ffi_type_float; 90 cl_arg_types[3] = &ffi_type_float; 91 cl_arg_types[4] = &ffi_type_sshort; 92 cl_arg_types[5] = &ffi_type_float; 93 cl_arg_types[6] = &ffi_type_float; 94 cl_arg_types[7] = &ffi_type_uint; 95 cl_arg_types[8] = &ffi_type_double; 96 cl_arg_types[9] = &ffi_type_uint; 97 cl_arg_types[10] = &ffi_type_uint; 98 cl_arg_types[11] = &ffi_type_float; 99 cl_arg_types[12] = &ffi_type_uint; 100 cl_arg_types[13] = &ffi_type_uint; 101 cl_arg_types[14] = &ffi_type_uint; 102 cl_arg_types[15] = &ffi_type_uint; 103 cl_arg_types[16] = NULL; 104 105 /* Initialize the cif */ 106 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16, 107 &ffi_type_sint, cl_arg_types) == FFI_OK); 108 109 CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn1, 110 (void *) 3 /* userdata */, code) == FFI_OK); 111 try 112 { 113 (*((closure_test_type1)code)) 114 (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13, 115 19, 21, 1); 116 /* { dg-output "\n1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */ 117 } catch (int exception_code) 118 { 119 CHECK(exception_code == 255); 120 } 121 printf("part two OK\n"); 122 /* { dg-output "\npart two OK" } */ 123 } 124 exit(0); 125} 126