mrb_value cfunc_pointer_free(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data = DATA_PTR(self); free(get_cfunc_pointer_data(data)); data->autofree = false; set_cfunc_pointer_data(data, NULL); return self; }
mrb_value cfunc_pointer_new_with_pointer(mrb_state *mrb, void *p, bool autofree) { struct cfunc_type_data *data = malloc(sizeof(struct cfunc_type_data)); data->refer = false; data->autofree = autofree; set_cfunc_pointer_data(data, p); return mrb_obj_value(Data_Wrap_Struct(mrb, mrb_ud(mrb)->cfunc_pointer_class, &cfunc_pointer_data_type, data)); }
mrb_value cfunc_pointer_realloc(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data = DATA_PTR(self); mrb_int alloc_size; mrb_get_args(mrb, "i", &alloc_size); set_cfunc_pointer_data(data, mrb_realloc(mrb, get_cfunc_pointer_data(data), alloc_size)); return self; }
mrb_value cfunc_pointer_class_malloc(mrb_state *mrb, mrb_value klass) { struct cfunc_type_data *data = malloc(sizeof(struct cfunc_type_data)); data->refer = false; data->autofree = false; mrb_int alloc_size; mrb_get_args(mrb, "i", &alloc_size); set_cfunc_pointer_data(data, malloc(alloc_size)); return mrb_obj_value(Data_Wrap_Struct(mrb, mrb_class_ptr(klass), &cfunc_pointer_data_type, data)); }
mrb_value cfunc_closure_initialize(mrb_state *mrb, mrb_value self) { struct cfunc_closure_data *data; data = mrb_data_check_get_ptr(mrb, self, &cfunc_closure_data_type); if (!data) { data = mrb_malloc(mrb, sizeof(struct cfunc_closure_data)); } data->refer = 0; data->autofree = 0; DATA_PTR(self) = data; DATA_TYPE(self) = &cfunc_closure_data_type; data->mrb = mrb; data->closure = NULL; data->arg_types = NULL; mrb_value rettype_mrb, block, args_mrb; mrb_get_args(mrb, "&oo", &block, &rettype_mrb, &args_mrb); data->argc = RARRAY_LEN(args_mrb); ffi_type *return_ffi_type = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(rettype_mrb))->ffi_type_value; data->return_type = rettype_mrb; data->arg_ffi_types = mrb_malloc(mrb, sizeof(ffi_type*) * data->argc); data->arg_types = mrb_malloc(mrb, sizeof(mrb_value) * data->argc); int i; for (i = 0; i < data->argc; ++i) { data->arg_types[i] = mrb_ary_ref(mrb, args_mrb, i); data->arg_ffi_types[i] = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(data->arg_types[i]))->ffi_type_value; } mrb_iv_set(mrb, self, mrb_intern_cstr(data->mrb, "@block"), block); void *closure_pointer = NULL; data->closure = ffi_closure_alloc(sizeof(ffi_closure) + sizeof(void*), &closure_pointer); data->cif = mrb_malloc(mrb, sizeof(ffi_cif)); if (data->closure) { if (ffi_prep_cif(data->cif, FFI_DEFAULT_ABI, data->argc, return_ffi_type, data->arg_ffi_types) == FFI_OK) { if (ffi_prep_closure_loc(data->closure, data->cif, cfunc_closure_call_binding, mrb_object(self), closure_pointer) == FFI_OK) { set_cfunc_pointer_data((struct cfunc_type_data *)data, closure_pointer); return self; } } } mrb_raise(mrb, E_SCRIPT_ERROR, "Internal FFI call error"); return mrb_nil_value(); }
mrb_value cfunc_pointer_initialize(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data; data = mrb_get_datatype(mrb, self, &cfunc_pointer_data_type); if (!data) { data = malloc(sizeof(struct cfunc_type_data)); } data->refer = false; data->autofree = false; DATA_PTR(self) = data; DATA_TYPE(self) = &cfunc_pointer_data_type; mrb_value ptr; int argc = mrb_get_args(mrb, "|o", &ptr); if(argc == 0) { set_cfunc_pointer_data(data, NULL); } else { set_cfunc_pointer_data(data, mobi_pointer_ptr(ptr)); } return self; }
static void cfunc_pointer_mrb_to_data(mrb_state *mrb, mrb_value val, struct cfunc_type_data *data) { set_cfunc_pointer_data(data, mobi_pointer_ptr(val)); }