summaryrefslogtreecommitdiff
path: root/ext/dl/closure.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/dl/closure.c')
-rw-r--r--ext/dl/closure.c230
1 files changed, 0 insertions, 230 deletions
diff --git a/ext/dl/closure.c b/ext/dl/closure.c
deleted file mode 100644
index a2e0b05bb4..0000000000
--- a/ext/dl/closure.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* -*- C -*-
- * $Id$
- */
-
-#include <ruby.h>
-#include "dl.h"
-#include <sys/mman.h>
-#include <dl_conversions.h>
-
-VALUE rb_cDLClosure;
-
-typedef struct {
- void * code;
- ffi_closure *pcl;
- ffi_cif * cif;
- int argc;
- ffi_type **argv;
-} dl_closure;
-
-static void
-dlclosure_free(void * ptr)
-{
- dl_closure * cls = (dl_closure *)ptr;
-#ifdef USE_NEW_CLOSURE_API
- ffi_closure_free(cls->pcl);
-#else
- munmap(cls->pcl, sizeof(cls->pcl));
-#endif
- xfree(cls->cif);
- if (cls->argv) xfree(cls->argv);
- xfree(cls);
-}
-
-static size_t
-dlclosure_memsize(const void * ptr)
-{
- dl_closure * cls = (dl_closure *)ptr;
- size_t size = 0;
-
- if (ptr) {
- size += sizeof(*cls);
- size += ffi_raw_size(cls->cif);
- size += sizeof(*cls->argv);
- size += sizeof(ffi_closure);
- }
- return size;
-}
-
-const rb_data_type_t dlclosure_data_type = {
- "dl/closure",
- 0, dlclosure_free, dlclosure_memsize,
-};
-
-void
-dlc_callback(ffi_cif *cif, void *resp, void **args, void *ctx)
-{
- VALUE self = (VALUE)ctx;
- VALUE rbargs = rb_iv_get(self, "@args");
- VALUE ctype = rb_iv_get(self, "@ctype");
- int argc = RARRAY_LENINT(rbargs);
- VALUE *params = xcalloc(argc, sizeof(VALUE *));
- VALUE ret;
- int i, dl_type;
-
- for (i = 0; i < argc; i++) {
- dl_type = NUM2INT(RARRAY_PTR(rbargs)[i]);
- switch (dl_type) {
- case DLTYPE_VOID:
- argc = 0;
- break;
- case DLTYPE_INT:
- params[i] = INT2NUM(*(int *)args[i]);
- break;
- case DLTYPE_VOIDP:
- params[i] = rb_dlptr_new(*(void **)args[i], 0, NULL);
- break;
- case DLTYPE_LONG:
- params[i] = LONG2NUM(*(long *)args[i]);
- break;
- case DLTYPE_CHAR:
- params[i] = INT2NUM(*(char *)args[i]);
- break;
- case DLTYPE_DOUBLE:
- params[i] = rb_float_new(*(double *)args[i]);
- break;
- case DLTYPE_FLOAT:
- params[i] = rb_float_new(*(float *)args[i]);
- break;
-#if HAVE_LONG_LONG
- case DLTYPE_LONG_LONG:
- params[i] = rb_ull2inum(*(unsigned LONG_LONG *)args[i]);
- break;
-#endif
- default:
- rb_raise(rb_eRuntimeError, "closure args: %d", dl_type);
- }
- }
-
- ret = rb_funcall2(self, rb_intern("call"), argc, params);
-
- dl_type = NUM2INT(ctype);
- switch (dl_type) {
- case DLTYPE_VOID:
- break;
- case DLTYPE_LONG:
- *(long *)resp = NUM2LONG(ret);
- break;
- case DLTYPE_CHAR:
- *(char *)resp = NUM2INT(ret);
- break;
- case DLTYPE_VOIDP:
- *(void **)resp = NUM2PTR(ret);
- break;
- case DLTYPE_INT:
- *(int *)resp = NUM2INT(ret);
- break;
- case DLTYPE_DOUBLE:
- *(double *)resp = NUM2DBL(ret);
- break;
- case DLTYPE_FLOAT:
- *(float *)resp = (float)NUM2DBL(ret);
- break;
-#if HAVE_LONG_LONG
- case DLTYPE_LONG_LONG:
- *(unsigned LONG_LONG *)resp = rb_big2ull(ret);
- break;
-#endif
- default:
- rb_raise(rb_eRuntimeError, "closure retval: %d", dl_type);
- }
- xfree(params);
-}
-
-static VALUE
-rb_dlclosure_allocate(VALUE klass)
-{
- dl_closure * closure;
-
- VALUE i = TypedData_Make_Struct(klass, dl_closure,
- &dlclosure_data_type, closure);
-
-#ifdef USE_NEW_CLOSURE_API
- closure->pcl = ffi_closure_alloc(sizeof(ffi_closure), &closure->code);
-#else
- closure->pcl = mmap(NULL, sizeof(ffi_closure), PROT_READ | PROT_WRITE,
- MAP_ANON | MAP_PRIVATE, -1, 0);
-#endif
- closure->cif = xmalloc(sizeof(ffi_cif));
-
- return i;
-}
-
-static VALUE
-rb_dlclosure_init(int rbargc, VALUE argv[], VALUE self)
-{
- VALUE ret;
- VALUE args;
- VALUE abi;
- dl_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);
-
- argc = RARRAY_LENINT(args);
-
- TypedData_Get_Struct(self, dl_closure, &dlclosure_data_type, cl);
-
- cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *));
-
- for (i = 0; i < argc; i++) {
- int dltype = NUM2INT(RARRAY_PTR(args)[i]);
- cl->argv[i] = DL2FFI_TYPE(dltype);
- }
- 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,
- DL2FFI_TYPE(NUM2INT(ret)),
- cl->argv);
-
- if (FFI_OK != result)
- rb_raise(rb_eRuntimeError, "error prepping CIF %d", result);
-
-#ifdef USE_NEW_CLOSURE_API
- result = ffi_prep_closure_loc(pcl, cif, dlc_callback,
- (void *)self, cl->code);
-#else
- result = ffi_prep_closure(pcl, cif, dlc_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;
-}
-
-static VALUE
-rb_dlclosure_to_i(VALUE self)
-{
- dl_closure * cl;
- void *code;
-
- TypedData_Get_Struct(self, dl_closure, &dlclosure_data_type, cl);
-
- code = cl->code;
-
- return PTR2NUM(code);
-}
-
-void
-Init_dlclosure(void)
-{
- rb_cDLClosure = rb_define_class_under(rb_mDL, "Closure", rb_cObject);
- rb_define_alloc_func(rb_cDLClosure, rb_dlclosure_allocate);
-
- rb_define_method(rb_cDLClosure, "initialize", rb_dlclosure_init, -1);
- rb_define_method(rb_cDLClosure, "to_i", rb_dlclosure_to_i, 0);
-}
-/* vim: set noet sw=4 sts=4 */