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