Exemple #1
0
int main (void)
{
	ffi_cif cif;
#ifndef USING_MMAP
	static ffi_closure cl;
#endif
	ffi_closure *pcl;
	void* args[1];
	ffi_type* arg_types[1];

#ifdef USING_MMAP
	pcl = allocate_mmap (sizeof(ffi_closure));
#else
	pcl = &cl;
#endif

	arg_types[0] = NULL;
	args[0] = NULL;

	CHECK(ffi_prep_cif(&cif, 255, 0, &ffi_type_void,
		arg_types) == FFI_BAD_ABI);

	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_void,
		arg_types) == FFI_OK);

	cif.abi= 255;

	CHECK(ffi_prep_closure(pcl, &cif, dummy_fn, NULL) == FFI_BAD_ABI);

	exit(0);
}
Exemple #2
0
int main (void)
{
  ffi_cif cif;
#ifndef USING_MMAP
  static ffi_closure cl;
#endif
  ffi_closure *pcl;
  ffi_type * cl_arg_types[2];
  unsigned short res;

#ifdef USING_MMAP
  pcl = allocate_mmap (sizeof(ffi_closure));
#else
  pcl = &cl;
#endif

  cl_arg_types[0] = &ffi_type_ushort;
  cl_arg_types[1] = NULL;

  /* Initialize the cif */
  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
		     &ffi_type_ushort, cl_arg_types) == FFI_OK);

  CHECK(ffi_prep_closure(pcl, &cif, cls_ret_ushort_fn, NULL)  == FFI_OK);

  res = (*((cls_ret_ushort)pcl))(65535);
  /* { dg-output "65535: 65535" } */
  printf("res: %d\n",res);
  /* { dg-output "\nres: 65535" } */

  exit(0);
}
Exemple #3
0
static bool
closure_prep(ffi_cif* cif, void* code, Closure* closure, char* errbuf, size_t errbufsize)
{
    ffi_status status;

    status = ffi_prep_closure(code, cif, closure_invoke, closure);
    switch (status) {
        case FFI_OK:
            return true;

        case FFI_BAD_ABI:
            snprintf(errbuf, errbufsize, "Invalid ABI specified");
            //throwException(env, IllegalArgument, "Invalid ABI specified");
            return false;

        case FFI_BAD_TYPEDEF:
            snprintf(errbuf, errbufsize, "Invalid argument type specified");
            //throwException(env, IllegalArgument, "Invalid argument type specified");
            return false;

        default:
            snprintf(errbuf, errbufsize, "Unknown FFI error");
            //throwException(env, IllegalArgument, "Unknown FFI error");
            return false;
    }
}
Exemple #4
0
int main (void)
{
  ffi_cif cif;
#ifndef USING_MMAP
  static ffi_closure cl;
#endif
  ffi_closure *pcl;
  void* args_dbl[5];
  ffi_type* cls_struct_fields[5];
  ffi_type cls_struct_type;
  ffi_type* dbl_arg_types[5];

#ifdef USING_MMAP
  pcl = allocate_mmap (sizeof(ffi_closure));
#else
  pcl = &cl;
#endif

  cls_struct_type.size = 0;
  cls_struct_type.alignment = 0;
  cls_struct_type.type = FFI_TYPE_STRUCT;
  cls_struct_type.elements = cls_struct_fields;

  struct cls_struct_7byte g_dbl = { 127, 120, 1, 254 };
  struct cls_struct_7byte f_dbl = { 12, 128, 9, 255 };
  struct cls_struct_7byte res_dbl;

  cls_struct_fields[0] = &ffi_type_ushort;
  cls_struct_fields[1] = &ffi_type_ushort;
  cls_struct_fields[2] = &ffi_type_uchar;
  cls_struct_fields[3] = &ffi_type_ushort;
  cls_struct_fields[4] = NULL;

  dbl_arg_types[0] = &cls_struct_type;
  dbl_arg_types[1] = &cls_struct_type;
  dbl_arg_types[2] = NULL;

  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
		     dbl_arg_types) == FFI_OK);

  args_dbl[0] = &g_dbl;
  args_dbl[1] = &f_dbl;
  args_dbl[2] = NULL;

  ffi_call(&cif, FFI_FN(cls_struct_7byte_fn), &res_dbl, args_dbl);
  /* { dg-output "127 120 1 254 12 128 9 255: 139 248 10 509" } */
  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
  /* { dg-output "\nres: 139 248 10 509" } */

  CHECK(ffi_prep_closure(pcl, &cif, cls_struct_7byte_gn, NULL) == FFI_OK);

  res_dbl = ((cls_struct_7byte(*)(cls_struct_7byte, cls_struct_7byte))(pcl))(g_dbl, f_dbl);
  /* { dg-output "\n127 120 1 254 12 128 9 255: 139 248 10 509" } */
  printf("res: %d %d %d %d\n", res_dbl.a, res_dbl.b, res_dbl.c, res_dbl.d);
  /* { dg-output "\nres: 139 248 10 509" } */

  exit(0);
}
Exemple #5
0
int main (void)
{
  ffi_cif cif;
#ifndef USING_MMAP
  static ffi_closure cl;
#endif
  ffi_closure *pcl;
  void* args_dbl[5];
  ffi_type* cls_struct_fields[4];
  ffi_type cls_struct_type;
  ffi_type* dbl_arg_types[5];

#ifdef USING_MMAP
  pcl = allocate_mmap (sizeof(ffi_closure));
#else
  pcl = &cl;
#endif

  cls_struct_type.size = 0;
  cls_struct_type.alignment = 0;
  cls_struct_type.type = FFI_TYPE_STRUCT;
  cls_struct_type.elements = cls_struct_fields;

  struct cls_struct_align g_dbl = { 12, (void *)4951, 127 };
  struct cls_struct_align f_dbl = { 1, (void *)9320, 13 };
  struct cls_struct_align res_dbl;

  cls_struct_fields[0] = &ffi_type_uchar;
  cls_struct_fields[1] = &ffi_type_pointer;
  cls_struct_fields[2] = &ffi_type_uchar;
  cls_struct_fields[3] = NULL;

  dbl_arg_types[0] = &cls_struct_type;
  dbl_arg_types[1] = &cls_struct_type;
  dbl_arg_types[2] = NULL;

  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
		     dbl_arg_types) == FFI_OK);

  args_dbl[0] = &g_dbl;
  args_dbl[1] = &f_dbl;
  args_dbl[2] = NULL;

  ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
  /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
  printf("res: %d %d %d\n", res_dbl.a, (size_t)res_dbl.b, res_dbl.c);
  /* { dg-output "\nres: 13 14271 140" } */

  CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);

  res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
  /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
  printf("res: %d %d %d\n", res_dbl.a, (size_t)res_dbl.b, res_dbl.c);
  /* { dg-output "\nres: 13 14271 140" } */

  exit(0);
}
Exemple #6
0
int main (void)
{
  ffi_cif cif;
#ifndef USING_MMAP
  static ffi_closure cl;
#endif
  ffi_closure *pcl;
  void* args_dbl[3];
  ffi_type* cls_struct_fields[4];
  ffi_type cls_struct_type;
  ffi_type* dbl_arg_types[3];

#ifdef USING_MMAP
  pcl = allocate_mmap (sizeof(ffi_closure));
#else
  pcl = &cl;
#endif

  cls_struct_type.size = 0;
  cls_struct_type.alignment = 0;
  cls_struct_type.type = FFI_TYPE_STRUCT;
  cls_struct_type.elements = cls_struct_fields;

  struct cls_struct_20byte g_dbl = { 1, 2.0, 3.0 };
  struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
  struct cls_struct_20byte res_dbl;

  cls_struct_fields[0] = &ffi_type_uint32;
  cls_struct_fields[1] = &ffi_type_double;
  cls_struct_fields[2] = &ffi_type_double;
  cls_struct_fields[3] = NULL;

  dbl_arg_types[0] = &cls_struct_type;
  dbl_arg_types[1] = &cls_struct_type;
  dbl_arg_types[2] = NULL;

  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
		     dbl_arg_types) == FFI_OK);

  args_dbl[0] = &g_dbl;
  args_dbl[1] = &f_dbl;
  args_dbl[2] = NULL;

  ffi_call(&cif, FFI_FN(cls_struct_20byte_fn), &res_dbl, args_dbl);
  /* { dg-output "1 2 3 4 5 7: 5 7 10" } */
  printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
  /* { dg-output "\nres: 5 7 10" } */

  CHECK(ffi_prep_closure(pcl, &cif, cls_struct_20byte_gn, NULL) == FFI_OK);

  res_dbl = ((cls_struct_20byte(*)(cls_struct_20byte, cls_struct_20byte))(pcl))(g_dbl, f_dbl);
  /* { dg-output "\n1 2 3 4 5 7: 5 7 10" } */
  printf("res: %d %g %g\n", res_dbl.a, res_dbl.b, res_dbl.c);
  /* { dg-output "\nres: 5 7 10" } */

  exit(0);
}
Exemple #7
0
static VALUE
initialize(int rbargc, VALUE argv[], VALUE self)
{
    VALUE ret;
    VALUE args;
    VALUE abi;
    fiddle_closure * cl;
    ffi_cif * cif;
    ffi_closure *pcl;
    ffi_status result;
    int i, argc;

    if (2 == rb_scan_args(rbargc, argv, "21", &ret, &args, &abi))
        abi = INT2NUM(FFI_DEFAULT_ABI);

    Check_Type(args, T_ARRAY);

    argc = RARRAY_LENINT(args);

    TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl);

    cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *));

    for (i = 0; i < argc; i++) {
        int type = NUM2INT(RARRAY_PTR(args)[i]);
        cl->argv[i] = INT2FFI_TYPE(type);
    }
    cl->argv[argc] = NULL;

    rb_iv_set(self, "@ctype", ret);
    rb_iv_set(self, "@args", args);

    cif = &cl->cif;
    pcl = cl->pcl;

    result = ffi_prep_cif(cif, NUM2INT(abi), argc,
                          INT2FFI_TYPE(NUM2INT(ret)),
                          cl->argv);

    if (FFI_OK != result)
        rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);

#ifndef DONT_USE_FFI_CLOSURE_ALLOC
    result = ffi_prep_closure_loc(pcl, cif, callback,
                                  (void *)self, cl->code);
#else
    result = ffi_prep_closure(pcl, cif, callback, (void *)self);
    cl->code = (void *)pcl;
    mprotect(pcl, sizeof(pcl), PROT_READ | PROT_EXEC);
#endif

    if (FFI_OK != result)
        rb_raise(rb_eRuntimeError, "error prepping closure %d", result);

    return self;
}
Exemple #8
0
int main (void)
{
  ffi_cif cif;
#ifndef USING_MMAP
  static ffi_closure cl;
#endif
  ffi_closure *pcl;
  void* args_dbl[5];
  ffi_type* cls_struct_fields[4];
  ffi_type cls_struct_type;
  ffi_type* dbl_arg_types[5];

#ifdef USING_MMAP
  pcl = allocate_mmap (sizeof(ffi_closure));
#else
  pcl = &cl;
#endif

  cls_struct_type.size = 0;
  cls_struct_type.alignment = 0;
  cls_struct_type.type = FFI_TYPE_STRUCT;
  cls_struct_type.elements = cls_struct_fields;

  struct cls_struct_3byte_1 g_dbl = { 15, 125 };
  struct cls_struct_3byte_1 f_dbl = { 9, 19 };
  struct cls_struct_3byte_1 res_dbl;

  cls_struct_fields[0] = &ffi_type_uchar;
  cls_struct_fields[1] = &ffi_type_ushort;
  cls_struct_fields[2] = NULL;

  dbl_arg_types[0] = &cls_struct_type;
  dbl_arg_types[1] = &cls_struct_type;
  dbl_arg_types[2] = NULL;

  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
		     dbl_arg_types) == FFI_OK);

  args_dbl[0] = &g_dbl;
  args_dbl[1] = &f_dbl;
  args_dbl[2] = NULL;

  ffi_call(&cif, FFI_FN(cls_struct_3byte_fn1), &res_dbl, args_dbl);
  /* { dg-output "15 125 9 19: 24 144" } */
  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
  /* { dg-output "\nres: 24 144" } */

  CHECK(ffi_prep_closure(pcl, &cif, cls_struct_3byte_gn1, NULL) == FFI_OK);

  res_dbl = ((cls_struct_3byte_1(*)(cls_struct_3byte_1, cls_struct_3byte_1))(pcl))(g_dbl, f_dbl);
  /* { dg-output "\n15 125 9 19: 24 144" } */
  printf("res: %d %d\n", res_dbl.a, res_dbl.b);
  /* { dg-output "\nres: 24 144" } */

  exit(0);
}
Exemple #9
0
ffi_status
ffi_prep_closure_loc(ffi_closure* closure, ffi_cif* cif,
        void (*fun)(ffi_cif*, void*, void**, void*),
        void* user_data, void* code)
{
    ffi_status retval = ffi_prep_closure(closure, cif, fun, user_data);
    if (retval == FFI_OK) {
        mprotect(closure, sizeof(ffi_closure), PROT_READ | PROT_EXEC);
    }
    return retval;
}
Exemple #10
0
int main (void)
{
  ffi_cif cif;
  static ffi_closure cl;
  ffi_closure *pcl = &cl;
  void* args_dbl[5];
  ffi_type* cls_struct_fields[5];
  ffi_type cls_struct_type;
  ffi_type* dbl_arg_types[5];

  cls_struct_type.size = 0;
  cls_struct_type.alignment = 0;
  cls_struct_type.type = FFI_TYPE_STRUCT;
  cls_struct_type.elements = cls_struct_fields;

  struct cls_struct_4_1byte g_dbl = { 12, 13, 14, 15 };
  struct cls_struct_4_1byte f_dbl = { 178, 179, 180, 181 };
  struct cls_struct_4_1byte res_dbl;

  cls_struct_fields[0] = &ffi_type_uchar;
  cls_struct_fields[1] = &ffi_type_uchar;
  cls_struct_fields[2] = &ffi_type_uchar;
  cls_struct_fields[3] = &ffi_type_uchar;
  cls_struct_fields[4] = NULL;

  dbl_arg_types[0] = &cls_struct_type;
  dbl_arg_types[1] = &cls_struct_type;
  dbl_arg_types[2] = NULL;

  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
		     dbl_arg_types) == FFI_OK);

  args_dbl[0] = &g_dbl;
  args_dbl[1] = &f_dbl;
  args_dbl[2] = NULL;

  ffi_call(&cif, FFI_FN(cls_struct_4_1byte_fn), &res_dbl, args_dbl);
  /* { dg-output "12 13 14 15 178 179 180 181: 190 192 194 196" } */
  CHECK( res_dbl.a == (g_dbl.a + f_dbl.a));
  CHECK( res_dbl.b == (g_dbl.b + f_dbl.b));
  CHECK( res_dbl.c == (g_dbl.c + f_dbl.c));
  CHECK( res_dbl.d == (g_dbl.d + f_dbl.d));

  CHECK(ffi_prep_closure(pcl, &cif, cls_struct_4_1byte_gn, NULL) == FFI_OK);

  res_dbl = ((cls_struct_4_1byte(*)(cls_struct_4_1byte, cls_struct_4_1byte))(pcl))(g_dbl, f_dbl);
  /* { dg-output "\n12 13 14 15 178 179 180 181: 190 192 194 196" } */
  CHECK( res_dbl.a == (g_dbl.a + f_dbl.a));
  CHECK( res_dbl.b == (g_dbl.b + f_dbl.b));
  CHECK( res_dbl.c == (g_dbl.c + f_dbl.c));
  CHECK( res_dbl.d == (g_dbl.d + f_dbl.d));

  exit(0);
}
Exemple #11
0
int main (void)
{
  ffi_cif cif;
#ifndef USING_MMAP
  static ffi_closure cl;
#endif
  ffi_closure *pcl;
  void * args_dbl[5];
  ffi_type * cl_arg_types[5];
  ffi_arg res_call;
  signed char a, c;
  signed short b, d, res_closure;

#ifdef USING_MMAP
  pcl = allocate_mmap (sizeof(ffi_closure));
#else
  pcl = &cl;
#endif

  a = 1;
  b = 32765;
  c = 127;
  d = -128;

  args_dbl[0] = &a;
  args_dbl[1] = &b;
  args_dbl[2] = &c;
  args_dbl[3] = &d;
  args_dbl[4] = NULL;

  cl_arg_types[0] = &ffi_type_schar;
  cl_arg_types[1] = &ffi_type_sshort;
  cl_arg_types[2] = &ffi_type_schar;
  cl_arg_types[3] = &ffi_type_sshort;
  cl_arg_types[4] = NULL;

  /* Initialize the cif */
  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
		     &ffi_type_sshort, cl_arg_types) == FFI_OK);

  ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
  /* { dg-output "1 32765 127 -128: 32765" } */
  printf("res: %d\n", res_call);
  /* { dg-output "\nres: 32765" } */

  CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL)  == FFI_OK);

  res_closure = (*((test_type)pcl))(1, 32765, 127, -128);
  /* { dg-output "\n1 32765 127 -128: 32765" } */
  printf("res: %d\n", res_closure);
  /* { dg-output "\nres: 32765" } */

  exit(0);
}
Exemple #12
0
int main(void)
{
    ffi_type* my_ffi_struct_fields[4];
    ffi_type my_ffi_struct_type;
    ffi_cif cif;
    static ffi_closure cl;
    ffi_closure *pcl = &cl;
    void* args[4];
    ffi_type* arg_types[3];

    struct my_ffi_struct g = { 1.0, 2.0, 3.0 };
    struct my_ffi_struct f = { 1.0, 2.0, 3.0 };
    struct my_ffi_struct res;

    my_ffi_struct_type.size = 0;
    my_ffi_struct_type.alignment = 0;
    my_ffi_struct_type.type = FFI_TYPE_STRUCT;
    my_ffi_struct_type.elements = my_ffi_struct_fields;

    my_ffi_struct_fields[0] = &ffi_type_double;
    my_ffi_struct_fields[1] = &ffi_type_double;
    my_ffi_struct_fields[2] = &ffi_type_double;
    my_ffi_struct_fields[3] = NULL;

    arg_types[0] = &my_ffi_struct_type;
    arg_types[1] = &my_ffi_struct_type;
    arg_types[2] = NULL;

    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &my_ffi_struct_type,
		       arg_types) == FFI_OK);

    args[0] = &g;
    args[1] = &f;
    args[2] = NULL;
    ffi_call(&cif, FFI_FN(callee), &res, args);
    /* { dg-output "1 2 3 1 2 3: 2 4 6" } */

    CHECK(res.a == 2.0);
    CHECK(res.b == 4.0);
    CHECK(res.c == 6.0);

    CHECK(ffi_prep_closure(pcl, &cif, stub, NULL) == FFI_OK);

    res = ((my_ffi_struct(*)(struct my_ffi_struct, struct my_ffi_struct))(pcl))(g, f);
    /* { dg-output "\n1 2 3 1 2 3: 2 4 6" } */

    CHECK(res.a == 2.0);
    CHECK(res.b == 4.0);
    CHECK(res.c == 6.0);

    exit(0);;
}
Exemple #13
0
// "Leaky" in that it exists for lifetime of program,
// kind of unavoidable though.
static ffi_closure *seed_make_rl_closure(SeedObject function)
{
  ffi_cif *cif;
  ffi_closure *closure;

  cif = g_new0(ffi_cif, 1);
  closure = mmap(0, sizeof(ffi_closure), PROT_READ | PROT_WRITE |
		 PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
  ffi_prep_cif(cif, FFI_DEFAULT_ABI, 0, &ffi_type_sint, 0);
  ffi_prep_closure(closure, cif, seed_handle_rl_closure, function);

  return closure;
}
Exemple #14
0
static bool
callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize)
{
    FunctionType* fnInfo = (FunctionType *) ctx;
    ffi_status ffiStatus;

    ffiStatus = ffi_prep_closure(code, &fnInfo->ffi_cif, callback_invoke, closure);
    if (ffiStatus != FFI_OK) {
        snprintf(errmsg, errmsgsize, "ffi_prep_closure failed.  status=%#x", ffiStatus);
        return false;
    }

    return true;
}
Exemple #15
0
int main (void)
{
  ffi_cif cif;
#ifndef USING_MMAP
  static ffi_closure cl;
#endif
  ffi_closure *pcl;
  ffi_type * cl_arg_types[17];
  int res;

#ifdef USING_MMAP
  pcl = allocate_mmap (sizeof(ffi_closure));
#else
  pcl = &cl;
#endif

  cl_arg_types[0] = &ffi_type_uint64;
  cl_arg_types[1] = &ffi_type_uint;
  cl_arg_types[2] = &ffi_type_uint64;
  cl_arg_types[3] = &ffi_type_uint;
  cl_arg_types[4] = &ffi_type_sshort;
  cl_arg_types[5] = &ffi_type_uint64;
  cl_arg_types[6] = &ffi_type_uint;
  cl_arg_types[7] = &ffi_type_uint;
  cl_arg_types[8] = &ffi_type_double;
  cl_arg_types[9] = &ffi_type_uint;
  cl_arg_types[10] = &ffi_type_uint;
  cl_arg_types[11] = &ffi_type_float;
  cl_arg_types[12] = &ffi_type_uint;
  cl_arg_types[13] = &ffi_type_uint;
  cl_arg_types[14] = &ffi_type_uint;
  cl_arg_types[15] = &ffi_type_uint;
  cl_arg_types[16] = NULL;

  /* Initialize the cif */
  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
		     &ffi_type_sint, cl_arg_types) == FFI_OK);

  CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn0,
			 (void *) 3 /* userdata */) == FFI_OK);

  res = (*((closure_test_type0)pcl))
    (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
     19, 21, 1);
  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
  printf("res: %d\n",res);
  /* { dg-output "\nres: 680" } */
     exit(0);
}
Exemple #16
0
int main (void)
{
  ffi_cif cif;
#ifndef USING_MMAP
  static ffi_closure cl;
#endif
  ffi_closure *pcl;
  ffi_type * cl_arg_types[17];
  int res;

#ifdef USING_MMAP
  pcl = allocate_mmap (sizeof(ffi_closure));
#else
  pcl = &cl;
#endif

  cl_arg_types[0] = &ffi_type_float;
  cl_arg_types[1] = &ffi_type_float;
  cl_arg_types[2] = &ffi_type_float;
  cl_arg_types[3] = &ffi_type_float;
  cl_arg_types[4] = &ffi_type_float;
  cl_arg_types[5] = &ffi_type_float;
  cl_arg_types[6] = &ffi_type_float;
  cl_arg_types[7] = &ffi_type_float;
  cl_arg_types[8] = &ffi_type_double;
  cl_arg_types[9] = &ffi_type_uint;
  cl_arg_types[10] = &ffi_type_float;
  cl_arg_types[11] = &ffi_type_float;
  cl_arg_types[12] = &ffi_type_uint;
  cl_arg_types[13] = &ffi_type_float;
  cl_arg_types[14] = &ffi_type_float;
  cl_arg_types[15] = &ffi_type_uint;
  cl_arg_types[16] = NULL;

  /* Initialize the cif */
  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
		     &ffi_type_sint, cl_arg_types) == FFI_OK);

  CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn3,
			 (void *) 3 /* userdata */)  == FFI_OK);

  res = (*((closure_test_type3)pcl))
    (1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13,
     19.19, 21.21, 1);
  /* { dg-output "1 2 3 4 5 6 7 8 9 10 11 12 13 19 21 1 3: 135" } */
  printf("res: %d\n",res);
  /* { dg-output "\nres: 135" } */
  exit(0);
}
Exemple #17
0
int main (void)
{
  ffi_cif cif;
  static ffi_closure cl;
  ffi_closure *pcl = &cl;
  void* args_dbl[5];
  ffi_type* cls_struct_fields[4];
  ffi_type cls_struct_type;
  ffi_type* dbl_arg_types[5];

  cls_struct_type.size = 0;
  cls_struct_type.alignment = 0;
  cls_struct_type.type = FFI_TYPE_STRUCT;
  cls_struct_type.elements = cls_struct_fields;

  struct cls_struct_3byte g_dbl = { 12, 119 };
  struct cls_struct_3byte f_dbl = { 1, 15 };
  struct cls_struct_3byte res_dbl;

  cls_struct_fields[0] = &ffi_type_ushort;
  cls_struct_fields[1] = &ffi_type_uchar;
  cls_struct_fields[2] = NULL;

  dbl_arg_types[0] = &cls_struct_type;
  dbl_arg_types[1] = &cls_struct_type;
  dbl_arg_types[2] = NULL;

  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
		     dbl_arg_types) == FFI_OK);

  args_dbl[0] = &g_dbl;
  args_dbl[1] = &f_dbl;
  args_dbl[2] = NULL;

  ffi_call(&cif, FFI_FN(cls_struct_3byte_fn), &res_dbl, args_dbl);
  /* { dg-output "12 119 1 15: 13 134" } */
  CHECK( res_dbl.a == (g_dbl.a + f_dbl.a));
  CHECK( res_dbl.b == (g_dbl.b + f_dbl.b));

  CHECK(ffi_prep_closure(pcl, &cif, cls_struct_3byte_gn, NULL) == FFI_OK);

  res_dbl = ((cls_struct_3byte(*)(cls_struct_3byte, cls_struct_3byte))(pcl))(g_dbl, f_dbl);
  /* { dg-output "\n12 119 1 15: 13 134" } */
  CHECK( res_dbl.a == (g_dbl.a + f_dbl.a));
  CHECK( res_dbl.b == (g_dbl.b + f_dbl.b));

  exit(0);
}
Exemple #18
0
void*
createAdjustor (int cconv, 
                StgStablePtr hptr,
                StgFunPtr wptr,
                char *typeString)
{
    ffi_cif *cif;
    ffi_type **arg_types;
    nat n_args, i;
    ffi_type *result_type;
    ffi_closure *cl;
    int r, abi;
    void *code;

    n_args = strlen(typeString) - 1;
    cif = stgMallocBytes(sizeof(ffi_cif), "createAdjustor");
    arg_types = stgMallocBytes(n_args * sizeof(ffi_type*), "createAdjustor");

    result_type = char_to_ffi_type(typeString[0]);
    for (i=0; i < n_args; i++) {
        arg_types[i] = char_to_ffi_type(typeString[i+1]);
    }
    switch (cconv) {
#if defined(mingw32_HOST_OS) && defined(i386_HOST_ARCH)
    case 0: /* stdcall */
        abi = FFI_STDCALL;
        break;
#endif
    case 1: /* ccall */
        abi = FFI_DEFAULT_ABI;
        break;
    default:
        barf("createAdjustor: convention %d not supported on this platform", cconv);
    }

    r = ffi_prep_cif(cif, abi, n_args, result_type, arg_types);
    if (r != FFI_OK) barf("ffi_prep_cif failed: %d", r);
    
    cl = allocateExec(sizeof(ffi_closure), &code);
    if (cl == NULL) {
        barf("createAdjustor: failed to allocate memory");
    }

    r = ffi_prep_closure(cl, cif, (void*)wptr, hptr/*userdata*/);
    if (r != FFI_OK) barf("ffi_prep_closure failed: %d", r);

    return (void*)code;
}
Exemple #19
0
static bool
prep_trampoline(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize)
{
    ffi_status ffiStatus;

#if defined(USE_RAW)
    ffiStatus = ffi_prep_raw_closure(code, &mh_cif, attached_method_invoke, closure);
#else
    ffiStatus = ffi_prep_closure(code, &mh_cif, attached_method_invoke, closure);
#endif
    if (ffiStatus != FFI_OK) {
        snprintf(errmsg, errmsgsize, "ffi_prep_closure failed.  status=%#x", ffiStatus);
        return false;
    }

    return true;
}
Exemple #20
0
ffi_status
ffi_prep_java_raw_closure (ffi_raw_closure* cl,
		      ffi_cif *cif,
		      void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
		      void *user_data)
{
  ffi_status status;

  status = ffi_prep_closure ((ffi_closure*) cl,
			     cif,
			     &ffi_java_translate_args,
			     (void*)cl);
  if (status == FFI_OK)
    {
      cl->fun       = fun;
      cl->user_data = user_data;
    }

  return status;
}
Exemple #21
0
int main (void)
{
  ffi_cif cif;
  static ffi_closure cl;
  ffi_closure *pcl = &cl;
  ffi_type * cl_arg_types[2];


  cl_arg_types[0] = &ffi_type_ushort;
  cl_arg_types[1] = NULL;

  /* Initialize the cif */
  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
		     &ffi_type_ushort, cl_arg_types) == FFI_OK);

  CHECK(ffi_prep_closure(pcl, &cif, cls_ret_ushort_fn, NULL)  == FFI_OK);

  (*((cls_ret_ushort)pcl))(65535);
  /* { dg-output "65535: 65535" } */

  exit(0);
}
Exemple #22
0
static int alien_callback_new(lua_State *L) {
  int fn_ref;
  alien_Callback *ac;
  ffi_closure **ud;
  ffi_status status;
  ffi_abi abi;
  luaL_checktype(L, 1, LUA_TFUNCTION);
  ac = (alien_Callback *)malloc(sizeof(alien_Callback));
  ud = (ffi_closure **)lua_newuserdata(L, sizeof(ffi_closure**));
  if(ac != NULL && ud != NULL) {
    int j;
    *ud = malloc_closure();
    if(*ud == NULL) { free(ac); luaL_error(L, "alien: cannot allocate callback"); }
    ac->L = L;
    ac->ret_type = AT_VOID;
    ac->ffi_ret_type = &ffi_type_void;
    abi = FFI_DEFAULT_ABI;
    ac->nparams = 0;
    ac->params = NULL;
    ac->ffi_params = NULL;
    lua_pushvalue(L, 1);
    ac->fn_ref = lua_ref(L, 1);
    luaL_getmetatable(L, ALIEN_CALLBACK_META);
    lua_setmetatable(L, -2);
    status = ffi_prep_cif(&(ac->cif), abi, ac->nparams,
			  ac->ffi_ret_type, ac->ffi_params);
    if(status != FFI_OK) luaL_error(L, "alien: cannot create callback");
    status = ffi_prep_closure(*ud, &(ac->cif), &alien_callback_call, ac);
    ac->fn = *ud;
    ac->lib = NULL;
    ac->name = NULL;
    if(status != FFI_OK) luaL_error(L, "alien: cannot create callback");
    return 1;
  } else {
    if(ac) free(ac);
    luaL_error(L, "alien: cannot allocate callback");
  }
  return 0;
}
Exemple #23
0
int main (void)
{
  ffi_cif cif;
  static ffi_closure cl;
  ffi_closure *pcl = &cl;
  ffi_type * cl_arg_types[17];

  cl_arg_types[0] = &ffi_type_float;
  cl_arg_types[1] = &ffi_type_float;
  cl_arg_types[2] = &ffi_type_float;
  cl_arg_types[3] = &ffi_type_float;
  cl_arg_types[4] = &ffi_type_sshort;
  cl_arg_types[5] = &ffi_type_float;
  cl_arg_types[6] = &ffi_type_float;
  cl_arg_types[7] = &ffi_type_uint;
  cl_arg_types[8] = &ffi_type_double;
  cl_arg_types[9] = &ffi_type_uint;
  cl_arg_types[10] = &ffi_type_uint;
  cl_arg_types[11] = &ffi_type_float;
  cl_arg_types[12] = &ffi_type_uint;
  cl_arg_types[13] = &ffi_type_uint;
  cl_arg_types[14] = &ffi_type_uint;
  cl_arg_types[15] = &ffi_type_uint;
  cl_arg_types[16] = NULL;

  /* Initialize the cif */
  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
		     &ffi_type_sint, cl_arg_types) == FFI_OK);

  CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn1,
			 (void *) 3 /* userdata */)  == FFI_OK);

  (*((closure_test_type1)pcl))
	(1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
	 19, 21, 1);
  /* { dg-output "1 2 3 4 127 5 6 8 9 10 11 12 13 19 21 1 3: 255" } */
  exit(0);
}
Exemple #24
0
int main (void)
{
  ffi_cif cif;
#ifndef USING_MMAP
  static ffi_closure cl;
#endif
  ffi_closure *pcl;
  ffi_type * cl_arg_types[17];
  int i, res;

#ifdef USING_MMAP
  pcl = allocate_mmap (sizeof(ffi_closure));
#else
  pcl = &cl;
#endif

  for (i = 0; i < 15; i++) {
    cl_arg_types[i] = &ffi_type_uint64;
  }
  cl_arg_types[15] = &ffi_type_uint;
  cl_arg_types[16] = NULL;

  /* Initialize the cif */
  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
		     &ffi_type_sint, cl_arg_types) == FFI_OK);

  CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn0,
			 (void *) 3 /* userdata */) == FFI_OK);

  res = (*((closure_test_type0)pcl))
    (1LL, 2LL, 3LL, 4LL, 127LL, 429LL, 7LL, 8LL, 9LL, 10LL, 11LL, 12LL,
     13LL, 19LL, 21LL, 1);
  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
  printf("res: %d\n",res);
  /* { dg-output "\nres: 680" } */

  exit(0);
}
Exemple #25
0
int main (void)
{
  ffi_cif cif;
#ifndef USING_MMAP
  static ffi_closure cl;
#endif
  ffi_closure *pcl;
  ffi_type * cl_arg_types[3];
  int i, res;
#ifdef USING_MMAP
  pcl = allocate_mmap (sizeof(ffi_closure));
#else
  //pcl = &cl;
  pcl = malloc(sizeof(*pcl));

#endif

  cl_arg_types[0] = &ffi_type_pointer;
  cl_arg_types[1] = &ffi_type_pointer;
  cl_arg_types[2] = &ffi_type_pointer;

  /* Initialize the cif */
  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3,
		     &ffi_type_sint, cl_arg_types) == FFI_OK);

  CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn7,
			 (void *) 99 /* userdata */) == FFI_OK);

  base_func(4, 5, 6);
  /* { dg-output "4 5 6\n" } */

  (*((closure_test_type7)pcl))((void*)1, (void*)2, (void*)3);
  /* { dg-output "1 2 3\n" } */

  exit(0);
}
Exemple #26
0
int main (void)
{
	ffi_cif cif;
#ifndef USING_MMAP
	static ffi_closure cl;
#endif
	ffi_closure *pcl;
	void* args_dbl[5];
	ffi_type* cls_struct_fields[10];
	ffi_type cls_struct_type;
	ffi_type* dbl_arg_types[5];

#ifdef USING_MMAP
	pcl = allocate_mmap (sizeof(ffi_closure));
#else
	pcl = &cl;
#endif

	cls_struct_type.size = 0;
	cls_struct_type.alignment = 0;
	cls_struct_type.type = FFI_TYPE_STRUCT;
	cls_struct_type.elements = cls_struct_fields;

	struct_72byte e_dbl = { 9.0, 2.0, 6.0, 5.0, 3.0, 4.0, 8.0, 1.0, 7 };
	struct_72byte f_dbl = { 1.0, 2.0, 3.0, 7.0, 2.0, 5.0, 6.0, 7.0, 4 };
	struct_72byte g_dbl = { 4.0, 5.0, 7.0, 9.0, 1.0, 1.0, 2.0, 9.0, 3 };
	struct_72byte h_dbl = { 8.0, 6.0, 1.0, 4.0, 0.0, 3.0, 3.0, 1.0, 2 };
	struct_72byte res_dbl;

	cls_struct_fields[0] = &ffi_type_double;
	cls_struct_fields[1] = &ffi_type_double;
	cls_struct_fields[2] = &ffi_type_double;
	cls_struct_fields[3] = &ffi_type_double;
	cls_struct_fields[4] = &ffi_type_double;
	cls_struct_fields[5] = &ffi_type_double;
	cls_struct_fields[6] = &ffi_type_double;
	cls_struct_fields[7] = &ffi_type_double;
	cls_struct_fields[8] = &ffi_type_sint64;
	cls_struct_fields[9] = NULL;

	dbl_arg_types[0] = &cls_struct_type;
	dbl_arg_types[1] = &cls_struct_type;
	dbl_arg_types[2] = &cls_struct_type;
	dbl_arg_types[3] = &cls_struct_type;
	dbl_arg_types[4] = NULL;

	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type,
		dbl_arg_types) == FFI_OK);

	args_dbl[0] = &e_dbl;
	args_dbl[1] = &f_dbl;
	args_dbl[2] = &g_dbl;
	args_dbl[3] = &h_dbl;
	args_dbl[4] = NULL;

	ffi_call(&cif, FFI_FN(cls_struct_72byte_fn), &res_dbl, args_dbl);
	/* { dg-output "22 15 17 25 6 13 19 18 16" } */
	printf("res: %g %g %g %g %g %g %g %g %lld\n", res_dbl.a, res_dbl.b, res_dbl.c,
		res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */

	CHECK(ffi_prep_closure(pcl, &cif, cls_struct_72byte_gn, NULL) == FFI_OK);

	res_dbl = ((struct_72byte(*)(struct_72byte, struct_72byte,
		struct_72byte, struct_72byte))(pcl))(e_dbl, f_dbl, g_dbl, h_dbl);
	/* { dg-output "\n22 15 17 25 6 13 19 18 16" } */
	printf("res: %g %g %g %g %g %g %g %g %lld\n", res_dbl.a, res_dbl.b, res_dbl.c,
		res_dbl.d, res_dbl.e, res_dbl.f, res_dbl.g, res_dbl.h, res_dbl.i);
	/* { dg-output "\nres: 22 15 17 25 6 13 19 18 16" } */

	exit(0);
}
Exemple #27
0
int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
{
  ffi_cif cif;
  ffi_type *args[MAX_ARGS];
  void *values[MAX_ARGS];
  char *s;
  signed char sc;
  unsigned char uc;
  signed short ss;
  unsigned short us;
  unsigned long ul;
  long long ll;
  float f;
  double d;
  long double ld;
  signed int si1;
  signed int si2;

  ffi_arg rint;
  long long rlonglong;

  ffi_type ts1_type;
  ffi_type ts2_type;
  ffi_type ts3_type;
  ffi_type ts4_type;  
  ffi_type ts5_type;
  ffi_type *ts1_type_elements[4];
  ffi_type *ts2_type_elements[3];
  ffi_type *ts3_type_elements[2];
  ffi_type *ts4_type_elements[4];
  ffi_type *ts5_type_elements[3];

  ts1_type.size = 0;
  ts1_type.alignment = 0;
  ts1_type.type = FFI_TYPE_STRUCT;

  ts2_type.size = 0;
  ts2_type.alignment = 0;
  ts2_type.type = FFI_TYPE_STRUCT;

  ts3_type.size = 0;
  ts3_type.alignment = 0;
  ts3_type.type = FFI_TYPE_STRUCT;

  ts4_type.size = 0;
  ts4_type.alignment = 0;
  ts4_type.type = FFI_TYPE_STRUCT;

  ts5_type.size = 0;
  ts5_type.alignment = 0;
  ts5_type.type = FFI_TYPE_STRUCT;

  /*@-immediatetrans@*/
  ts1_type.elements = ts1_type_elements;
  ts2_type.elements = ts2_type_elements;
  ts3_type.elements = ts3_type_elements;
  ts4_type.elements = ts4_type_elements;
  ts5_type.elements = ts5_type_elements;
  /*@=immediatetrans@*/
  
  ts1_type_elements[0] = &ffi_type_uchar;
  ts1_type_elements[1] = &ffi_type_double;
  ts1_type_elements[2] = &ffi_type_uint;
  ts1_type_elements[3] = NULL;
  
  ts2_type_elements[0] = &ffi_type_double;
  ts2_type_elements[1] = &ffi_type_double;
  ts2_type_elements[2] = NULL;

  ts3_type_elements[0] = &ffi_type_sint;
  ts3_type_elements[1] = NULL;

  ts4_type_elements[0] = &ffi_type_uint;
  ts4_type_elements[1] = &ffi_type_uint;
  ts4_type_elements[2] = &ffi_type_uint;
  ts4_type_elements[3] = NULL;

  ts5_type_elements[0] = &ffi_type_schar;
  ts5_type_elements[1] = &ffi_type_schar;
  ts5_type_elements[2] = NULL;

  ul = 0;

  /* return value tests */
  {
#if defined(MIPS) /* || defined(ARM) */
    puts ("long long tests not run. This is a known bug on this architecture.");
#else
    args[0] = &ffi_type_sint64;
    values[0] = &ll;
    
    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
		       &ffi_type_sint64, args) == FFI_OK);

    for (ll = 0LL; ll < 100LL; ll++)
      {
	ul++;
	ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
	CHECK(rlonglong == ll);
      }

    for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
      {
	ul++;
	ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
	CHECK(rlonglong == ll);
      }
#endif

    args[0] = &ffi_type_schar;
    values[0] = &sc;
    
    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
		       &ffi_type_schar, args) == FFI_OK);

    for (sc = (signed char) -127; 
	 sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/)
      {
	ul++;
	ffi_call(&cif, FFI_FN(return_sc), &rint, values);
	CHECK(rint == (int) sc);
      }

    args[0] = &ffi_type_uchar;
    values[0] = &uc;
    
    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
		       &ffi_type_uchar, args) == FFI_OK);

    for (uc = (unsigned char) '\x00'; 
	 uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/)
      {
	ul++;
	ffi_call(&cif, FFI_FN(return_uc), &rint, values);
	CHECK(rint == (signed int) uc);
      }

    printf("%lu return value tests run\n", ul);
  }

#ifdef BROKEN_LONG_DOUBLE
  printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n");
#else
  /* float arg tests */
  {
    args[0] = &ffi_type_float;
    values[0] = &f;

    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
		       &ffi_type_longdouble, args) == FFI_OK);

    f = 3.14159;

#if 0
  /* This is ifdef'd out for now. long double support under SunOS/gcc
     is pretty much non-existent.  You'll get the odd bus error in library
     routines like printf().  */
    printf ("%Lf\n", ldblit(f));
#endif
    ld = 666;
    ffi_call(&cif, FFI_FN(ldblit), &ld, values);

#if 0
  /* This is ifdef'd out for now. long double support under SunOS/gcc
     is pretty much non-existent.  You'll get the odd bus error in library
     routines like printf().  */
    printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
#endif

    /* These are not always the same!! Check for a reasonable delta */
    /*@-realcompare@*/
    if (ld - ldblit(f) < LDBL_EPSILON)
    /*@=realcompare@*/
	puts("long double return value tests ok!");
    else
        CHECK(0);
  }

  /* float arg tests */
  {
    args[0] = &ffi_type_sint;
    values[0] = &si1;
    args[1] = &ffi_type_float;
    values[1] = &f;
    args[2] = &ffi_type_double;
    values[2] = &d;
    args[3] = &ffi_type_longdouble;
    values[3] = &ld;
    args[4] = &ffi_type_sint;
    values[4] = &si2;
    
    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5,
		       &ffi_type_sint, args) == FFI_OK);

    si1 = 6;
    f = 3.14159;
    d = (double)1.0/(double)3.0;
    ld = 2.71828182846L;
    si2 = 10;

    floating (si1, f, d, ld, si2);

    ffi_call(&cif, FFI_FN(floating), &rint, values);

    printf ("%d vs %d\n", rint, floating (si1, f, d, ld, si2));

    CHECK(rint == floating(si1, f, d, ld, si2));

    printf("float arg tests ok!\n");
  }
#endif

  /* strlen tests */
  {
    args[0] = &ffi_type_pointer;
    values[0] = (void*) &s;
    
    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
		       &ffi_type_sint, args) == FFI_OK);

    s = "a";
    ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
    CHECK(rint == 1);

    s = "1234567";
    ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
    CHECK(rint == 7);

    s = "1234567890123456789012345";
    ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
    CHECK(rint == 25);

    printf("strlen tests passed\n");
  }

  /* float arg tests */
  {
    args[0] = &ffi_type_float;
    values[0] = &f;
    
    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
		       &ffi_type_double, args) == FFI_OK);

    f = 3.14159;

    ffi_call(&cif, FFI_FN(dblit), &d, values);

    /* These are not always the same!! Check for a reasonable delta */
    /*@-realcompare@*/
    CHECK(d - dblit(f) < DBL_EPSILON);
    /*@=realcompare@*/

    printf("double return value tests ok!\n");
  }

  /* many arg tests */
  {
    float ff;
    float fa[13];
    
    for (ul = 0; ul < 13; ul++)
      {
	args[ul] = &ffi_type_float;
	values[ul] = &fa[ul];
	fa[ul] = (float) ul;
      }

    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, 
		       &ffi_type_float, args) == FFI_OK);

    /*@-usedef@*/
    ff =  many(fa[0], fa[1],
	       fa[2], fa[3],
	       fa[4], fa[5],
	       fa[6], fa[7],
	       fa[8], fa[9],
	       fa[10],fa[11],fa[12]);
    /*@=usedef@*/

    ffi_call(&cif, FFI_FN(many), &f, values);

    /*@-realcompare@*/
    if (f - ff < FLT_EPSILON)
    /*@=realcompare@*/
	printf("many arg tests ok!\n");
    else
#ifdef POWERPC
	printf("many arg tests failed!  This is a gcc bug.\n");
#else
        CHECK(0);
#endif
  }

  /* promotion tests */
  {
    args[0] = &ffi_type_schar;
    args[1] = &ffi_type_sshort;
    args[2] = &ffi_type_uchar;
    args[3] = &ffi_type_ushort;
    values[0] = &sc;
    values[1] = &ss;
    values[2] = &uc;
    values[3] = &us;
    
    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, 
		       &ffi_type_sint, args) == FFI_OK);

    us = 0;
    ul = 0;

    for (sc = (signed char) -127; 
	 sc <= (signed char) 120; /*@-type@*/ sc += 1 /*@=type@*/)
      for (ss = -30000; ss <= 30000; ss += 10000)
	for (uc = (unsigned char) 0; 
	     uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/)
	  for (us = 0; us <= 60000; us += 10000)
	    {
	      ul++;
	      ffi_call(&cif, FFI_FN(promotion), &rint, values);
	      CHECK(rint == (int) sc + (int) ss + (int) uc + (int) us);
	    }
    printf("%lu promotion tests run\n", ul);
  }

#ifndef X86_WIN32 /* Structures dont work on Win32 */

  /* struct tests */
  {
    test_structure_1 ts1_arg;
    /* This is a hack to get a properly aligned result buffer */
    test_structure_1 *ts1_result = 
      (test_structure_1 *) malloc (sizeof(test_structure_1));

    args[0] = &ts1_type;
    values[0] = &ts1_arg;
    
    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
		       &ts1_type, args) == FFI_OK);

    ts1_arg.uc = '\x01';
    ts1_arg.d = 3.14159;
    ts1_arg.ui = 555;

    ffi_call(&cif, FFI_FN(struct1), ts1_result, values);

    CHECK(ts1_result->ui == 556);
    CHECK(ts1_result->d == 3.14159 - 1);

    puts ("structure test 1 ok!\n");

    free (ts1_result);
  }

  /* struct tests */
  {
    test_structure_2 ts2_arg;

    /* This is a hack to get a properly aligned result buffer */
    test_structure_2 *ts2_result = 
      (test_structure_2 *) malloc (sizeof(test_structure_2));

    args[0] = &ts2_type;
    values[0] = &ts2_arg;
    
    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
		       &ts2_type, args) == FFI_OK);

    ts2_arg.d1 = 5.55;
    ts2_arg.d2 = 6.66;

    printf ("%g\n", ts2_result->d1);
    printf ("%g\n", ts2_result->d2);

    ffi_call(&cif, FFI_FN(struct2), ts2_result, values);

    printf ("%g\n", ts2_result->d1);
    printf ("%g\n", ts2_result->d2);
    
    CHECK(ts2_result->d1 == 5.55 - 1);
    CHECK(ts2_result->d2 == 6.66 - 1);

    printf("structure test 2 ok!\n");

    free (ts2_result);
  }

  /* struct tests */
  {
    int compare_value;
    test_structure_3 ts3_arg;
    test_structure_3 *ts3_result = 
      (test_structure_3 *) malloc (sizeof(test_structure_3));

    args[0] = &ts3_type;
    values[0] = &ts3_arg;
    
    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
		       &ts3_type, args) == FFI_OK);

    ts3_arg.si = -123;
    compare_value = ts3_arg.si;

    ffi_call(&cif, FFI_FN(struct3), ts3_result, values);

    printf ("%d %d\n", ts3_result->si, -(compare_value*2));

    if (ts3_result->si == -(ts3_arg.si*2))
	puts ("structure test 3 ok!");
    else
      {
	puts ("Structure test 3 found structure passing bug.");
	puts ("  Current versions of GCC are not 100% compliant with the");
	puts ("  n32 ABI.  There is a known problem related to passing");
	puts ("  small structures.  Send a bug report to the gcc maintainers.");
      }

    free (ts3_result);
  }

  /* struct tests */
  {
    test_structure_4 ts4_arg;

    /* This is a hack to get a properly aligned result buffer */
    test_structure_4 *ts4_result = 
      (test_structure_4 *) malloc (sizeof(test_structure_4));

    args[0] = &ts4_type;
    values[0] = &ts4_arg;
    
    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
		       &ts4_type, args) == FFI_OK);

    ts4_arg.ui1 = 2;
    ts4_arg.ui2 = 3;
    ts4_arg.ui3 = 4;

    ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
    
    if (ts4_result->ui3 == 2U * 3U * 4U)
      puts ("structure test 4 ok!");
    else
      puts ("Structure test 4 found GCC's structure passing bug.");

    free (ts4_result);
  }

  /* struct tests */
  {
    test_structure_5 ts5_arg1, ts5_arg2;

    /* This is a hack to get a properly aligned result buffer */
    test_structure_5 *ts5_result = 
      (test_structure_5 *) malloc (sizeof(test_structure_5));

    args[0] = &ts5_type;
    args[1] = &ts5_type;
    values[0] = &ts5_arg1;
    values[1] = &ts5_arg2;
    
    /* Initialize the cif */
    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, 
		       &ts5_type, args) == FFI_OK);

    ts5_arg1.c1 = 2;
    ts5_arg1.c2 = 6;
    ts5_arg2.c1 = 5;
    ts5_arg2.c2 = 3;

    ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
    
    if (ts5_result->c1 == 7 
	&& ts5_result->c2 == 3)
      puts ("structure test 5 ok!");
    else
      puts ("Structure test 5 found GCC's structure passing bug.");

    free (ts5_result);
  }

#else
  printf("Structure passing doesn't work on Win32.\n");
#endif /* X86_WIN32 */

# if FFI_CLOSURES
  /* A simple closure test */
    {
      ffi_closure cl;
      ffi_type * cl_arg_types[3];

      cl_arg_types[0] = &ffi_type_sint;
      cl_arg_types[1] = &ffi_type_float;
      cl_arg_types[2] = NULL;
      
      /* Initialize the cif */
      CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, 
	    	         &ffi_type_sint, cl_arg_types) == FFI_OK);

      CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn,
			     (void *) 3 /* userdata */)
	    == FFI_OK);
      CHECK((*((closure_test_type)(&cl)))(1, 2.0) == 6);
    }
# endif

  /* If we arrived here, all is good */
  (void) puts("\nLooks good. No surprises.\n");

  /*@-compdestroy@*/

  return 0;
}
Exemple #28
0
int main (void)
{
  ffi_cif cif;
#ifndef USING_MMAP
  static ffi_closure cl;
#endif
  ffi_closure *pcl;
  void* args_dbl[5];
  ffi_type* cls_struct_fields[4];
  ffi_type cls_struct_type;
  ffi_type* dbl_arg_types[5];

#ifdef USING_MMAP
  pcl = allocate_mmap (sizeof(ffi_closure));
#else
  pcl = &cl;
#endif

  cls_struct_type.size = 0;
  cls_struct_type.alignment = 0;
  cls_struct_type.type = FFI_TYPE_STRUCT;
  cls_struct_type.elements = cls_struct_fields;

  struct cls_struct_16byte h_dbl = { 7, 8.0, 9 };
  struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
  struct cls_struct_16byte res_dbl;

  cls_struct_fields[0] = &ffi_type_uint32;
  cls_struct_fields[1] = &ffi_type_double;
  cls_struct_fields[2] = &ffi_type_uint32;
  cls_struct_fields[3] = NULL;

  dbl_arg_types[0] = &cls_struct_type;
  dbl_arg_types[1] = &cls_struct_type;
  dbl_arg_types[2] = NULL;

  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type,
		     dbl_arg_types) == FFI_OK);

  args_dbl[0] = &h_dbl;
  args_dbl[1] = &j_dbl;
  args_dbl[2] = NULL;

  ffi_call(&cif, FFI_FN(cls_struct_16byte_fn), &res_dbl, args_dbl);
  /* { dg-output "7 8 9 1 9 3: 8 17 12" } */
  printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
  /* { dg-output "\nres: 8 17 12" } */

  res_dbl.a = 0;
  res_dbl.b = 0.0;
  res_dbl.c = 0;

  CHECK(ffi_prep_closure(pcl, &cif, cls_struct_16byte_gn, NULL) == FFI_OK);

  res_dbl = ((cls_struct_16byte(*)(cls_struct_16byte, cls_struct_16byte))(pcl))(h_dbl, j_dbl);
  /* { dg-output "\n7 8 9 1 9 3: 8 17 12" } */
  printf("res: %d %g %d\n", res_dbl.a, res_dbl.b, res_dbl.c);
  /* { dg-output "\nres: 8 17 12" } */

  exit(0);
}
Exemple #29
0
ffi_info *AllocFunctionCallback(PyObject *callable,
				PyObject *converters,
				PyObject *restype,
				int is_cdecl)
{
	int result;
	ffi_info *p;
	int nArgs, i;
	ffi_abi cc;

	nArgs = PySequence_Size(converters);
	p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs + 1));
	if (p == NULL) {
		PyErr_NoMemory();
		return NULL;
	}
	p->pcl = MallocClosure();
	if (p->pcl == NULL) {
		PyErr_NoMemory();
		goto error;
	}

	for (i = 0; i < nArgs; ++i) {
		PyObject *cnv = PySequence_GetItem(converters, i);
		if (cnv == NULL)
			goto error;
		p->atypes[i] = GetType(cnv);
		Py_DECREF(cnv);
	}
	p->atypes[i] = NULL;

	if (restype == Py_None) {
		p->setfunc = NULL;
		p->restype = &ffi_type_void;
	} else {
		StgDictObject *dict = PyType_stgdict(restype);
		if (dict == NULL || dict->setfunc == NULL) {
		  PyErr_SetString(PyExc_TypeError,
				  "invalid result type for callback function");
		  goto error;
		}
		p->setfunc = dict->setfunc;
		p->restype = &dict->ffi_type_pointer;
	}

	cc = FFI_DEFAULT_ABI;
#if defined(MS_WIN32) && !defined(_WIN32_WCE)
	if (is_cdecl == 0)
		cc = FFI_STDCALL;
#endif
	result = ffi_prep_cif(&p->cif, cc, nArgs,
			      GetType(restype),
			      &p->atypes[0]);
	if (result != FFI_OK) {
		PyErr_Format(PyExc_RuntimeError,
			     "ffi_prep_cif failed with %d", result);
		goto error;
	}
	result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p);
	if (result != FFI_OK) {
		PyErr_Format(PyExc_RuntimeError,
			     "ffi_prep_closure failed with %d", result);
		goto error;
	}

	p->converters = converters;
	p->callable = callable;
	return p;

  error:
	if (p) {
		if (p->pcl)
			FreeClosure(p->pcl);
		PyMem_Free(p);
	}
	return NULL;
}
CThunkObject *_ctypes_alloc_callback(PyObject *callable,
				    PyObject *converters,
				    PyObject *restype,
				    int flags)
{
	int result;
	CThunkObject *p;
	Py_ssize_t nArgs, i;
	ffi_abi cc;

	nArgs = PySequence_Size(converters);
	p = CThunkObject_new(nArgs);
	if (p == NULL)
		return NULL;

	assert(CThunk_CheckExact((PyObject *)p));

	p->pcl = _ctypes_alloc_closure();
	if (p->pcl == NULL) {
		PyErr_NoMemory();
		goto error;
	}

	p->flags = flags;
	for (i = 0; i < nArgs; ++i) {
		PyObject *cnv = PySequence_GetItem(converters, i);
		if (cnv == NULL)
			goto error;
		p->atypes[i] = _ctypes_get_ffi_type(cnv);
		Py_DECREF(cnv);
	}
	p->atypes[i] = NULL;

	Py_INCREF(restype);
	p->restype = restype;
	if (restype == Py_None) {
		p->setfunc = NULL;
		p->ffi_restype = &ffi_type_void;
	} else {
		StgDictObject *dict = PyType_stgdict(restype);
		if (dict == NULL || dict->setfunc == NULL) {
		  PyErr_SetString(PyExc_TypeError,
				  "invalid result type for callback function");
		  goto error;
		}
		p->setfunc = dict->setfunc;
		p->ffi_restype = &dict->ffi_type_pointer;
	}

	cc = FFI_DEFAULT_ABI;
#if defined(MS_WIN32) && !defined(_WIN32_WCE) && !defined(MS_WIN64)
	if ((flags & FUNCFLAG_CDECL) == 0)
		cc = FFI_STDCALL;
#endif
	result = ffi_prep_cif(&p->cif, cc,
			      Py_SAFE_DOWNCAST(nArgs, Py_ssize_t, int),
			      _ctypes_get_ffi_type(restype),
			      &p->atypes[0]);
	if (result != FFI_OK) {
		PyErr_Format(PyExc_RuntimeError,
			     "ffi_prep_cif failed with %d", result);
		goto error;
	}
	result = ffi_prep_closure(p->pcl, &p->cif, closure_fcn, p);
	if (result != FFI_OK) {
		PyErr_Format(PyExc_RuntimeError,
			     "ffi_prep_closure failed with %d", result);
		goto error;
	}

	Py_INCREF(converters);
	p->converters = converters;
	Py_INCREF(callable);
	p->callable = callable;
	return p;

  error:
	Py_XDECREF(p);
	return NULL;
}