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