From 3fcd13e2ac3d3b85f8ce5467bf83300c9122ace2 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Fri, 29 May 2015 02:00:11 +0900 Subject: [PATCH 01/29] Fixes for latest mruby. --- include/cfunc.h | 10 +++---- mrbgem.rake | 7 +++-- src/cfunc_call.c | 16 +++++------ src/cfunc_closure.c | 10 +++---- src/cfunc_pointer.c | 38 ++++++++++++------------ src/cfunc_rubyvm.c | 17 ++++++----- src/cfunc_struct.c | 4 +-- src/cfunc_type.c | 70 ++++++++++++++++++++++----------------------- src/cfunc_utils.c | 2 +- src/vector.c | 6 ++-- test/func.c | 4 +-- 11 files changed, 93 insertions(+), 91 deletions(-) diff --git a/include/cfunc.h b/include/cfunc.h index 39587bc..a3d07d6 100644 --- a/include/cfunc.h +++ b/include/cfunc.h @@ -58,18 +58,18 @@ static inline struct cfunc_state * cfunc_state(mrb_state *mrb, struct RClass* obj) { if(obj == NULL) { - obj = (struct RClass*) mrb_object(mrb_vm_const_get(mrb, mrb_intern_cstr(mrb, "CFunc"))); + obj = mrb_module_get(mrb, "CFunc"); } - mrb_value state = mrb_mod_cv_get(mrb, obj, mrb_intern_cstr(mrb, "cfunc_state")); - return (struct cfunc_state *)mrb_voidp(state); + mrb_value state = mrb_mod_cv_get(mrb, obj, mrb_intern_lit(mrb, "cfunc_state")); + return (struct cfunc_state *)mrb_cptr(state); } static inline void set_cfunc_state(mrb_state *mrb, struct RClass* klass, struct cfunc_state *state) { - mrb_value mstate = mrb_voidp_value(mrb, state); - mrb_mod_cv_set(mrb, klass, mrb_intern_cstr(mrb, "cfunc_state"), mstate); + mrb_value mstate = mrb_cptr_value(mrb, state); + mrb_mod_cv_set(mrb, klass, mrb_intern_lit(mrb, "cfunc_state"), mstate); } #endif diff --git a/mrbgem.rake b/mrbgem.rake index b4e9f58..dca5e5a 100644 --- a/mrbgem.rake +++ b/mrbgem.rake @@ -4,16 +4,19 @@ MRuby::Gem::Specification.new('mruby-cfunc') do |spec| spec.license = 'MIT' spec.authors = 'MobiRuby developers' + spec.add_dependency 'mruby-print', :core => 'mruby-print' + spec.add_dependency 'mruby-enumerator', :core => 'mruby-enumerator' + def spec.use_pkg_config(pkg_config='pkg-config') self.linker.flags << `"#{pkg_config}" libffi --libs-only-L --libs-only-other`.chomp [self.cc, self.cxx, self.objc, self.mruby.cc, self.mruby.cxx, self.mruby.objc].each do |cc| - cc.include_paths << `"#{pkg_config}" libffi --cflags`.chomp + cc.flags << `"#{pkg_config}" libffi --cflags`.chomp end end def spec.download_libffi(libffi_version = '3.0.13', tar = 'tar') libffi_url = "ftp://sourceware.org/pub/libffi/libffi-#{libffi_version}.tar.gz" - libffi_build_root = "build/libffi/#{build.name}" + libffi_build_root = "#{MRUBY_ROOT}/build/libffi/#{build.name}" libffi_dir = "#{libffi_build_root}/libffi-#{libffi_version}" libffi_a = "#{libffi_dir}/lib/libffi.a" diff --git a/src/cfunc_call.c b/src/cfunc_call.c index 458679f..27aea01 100644 --- a/src/cfunc_call.c +++ b/src/cfunc_call.c @@ -49,7 +49,7 @@ get_proc_address(const char* funcname) static mrb_value cfunc_call(mrb_state *mrb, mrb_value self) { - int margc; + mrb_int margc; mrb_value mresult_type, mname, *margs; void **values = NULL; ffi_type **args = NULL; @@ -67,7 +67,7 @@ cfunc_call(mrb_state *mrb, mrb_value self) #endif if(fp == NULL) { - mrb_raisef(mrb, E_NAME_ERROR, "can't find C function %s", mrb_string_value_ptr(mrb, mname)); + mrb_raisef(mrb, E_NAME_ERROR, "can't find C function %S", mname); goto cfunc_call_exit; } } @@ -81,7 +81,7 @@ cfunc_call(mrb_state *mrb, mrb_value self) args = mrb_malloc(mrb, sizeof(ffi_type*) * margc); values = mrb_malloc(mrb, sizeof(void*) * margc); - mrb_sym sym_to_ffi_value = mrb_intern_cstr(mrb, "to_ffi_value"); + mrb_sym sym_to_ffi_value = mrb_intern_lit(mrb, "to_ffi_value"); mrb_value nil_ary[1]; nil_ary[0] = mrb_nil_value(); @@ -124,7 +124,7 @@ cfunc_call(mrb_state *mrb, mrb_value self) } } else { - mrb_raisef(mrb, E_NAME_ERROR, "Can't find C function %s", mname); + mrb_raisef(mrb, E_NAME_ERROR, "Can't find C function %S", mname); goto cfunc_call_exit; } @@ -138,7 +138,7 @@ cfunc_call(mrb_state *mrb, mrb_value self) static mrb_value cfunc_libcall(mrb_state *mrb, mrb_value self) { - int margc; + mrb_int margc; mrb_value mresult_type, mlib, mname, *margs; void **values = NULL; ffi_type **args = NULL; @@ -152,7 +152,7 @@ cfunc_libcall(mrb_state *mrb, mrb_value self) dlclose(dlh); if(fp == NULL) { - mrb_raisef(mrb, E_NAME_ERROR, "can't find C function %s", mrb_string_value_ptr(mrb, mname)); + mrb_raisef(mrb, E_NAME_ERROR, "can't find C function %S", mname); goto cfunc_call_exit; } } @@ -166,7 +166,7 @@ cfunc_libcall(mrb_state *mrb, mrb_value self) args = mrb_malloc(mrb, sizeof(ffi_type*) * margc); values = mrb_malloc(mrb, sizeof(void*) * margc); - mrb_sym sym_to_ffi_value = mrb_intern_cstr(mrb, "to_ffi_value"); + mrb_sym sym_to_ffi_value = mrb_intern_lit(mrb, "to_ffi_value"); mrb_value nil_ary[1]; nil_ary[0] = mrb_nil_value(); @@ -209,7 +209,7 @@ cfunc_libcall(mrb_state *mrb, mrb_value self) } } else { - mrb_raisef(mrb, E_NAME_ERROR, "Can't find C function %s", mname); + mrb_raisef(mrb, E_NAME_ERROR, "Can't find C function %S", mname); goto cfunc_call_exit; } diff --git a/src/cfunc_closure.c b/src/cfunc_closure.c index afa336d..ca2ad06 100644 --- a/src/cfunc_closure.c +++ b/src/cfunc_closure.c @@ -83,7 +83,7 @@ cfunc_closure_initialize(mrb_state *mrb, mrb_value self) 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); + mrb_iv_set(mrb, self, mrb_intern_lit(data->mrb, "@block"), block); void *closure_pointer = NULL; data->closure = ffi_closure_alloc(sizeof(ffi_closure) + sizeof(void*), &closure_pointer); @@ -91,7 +91,7 @@ cfunc_closure_initialize(mrb_state *mrb, mrb_value self) 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) { + if (ffi_prep_closure_loc(data->closure, data->cif, cfunc_closure_call_binding, mrb_ptr(self), closure_pointer) == FFI_OK) { set_cfunc_pointer_data((struct cfunc_type_data *)data, closure_pointer); return self; } @@ -121,8 +121,8 @@ cfunc_closure_call_binding(ffi_cif *cif, void *ret, void **args, void *self_) ary[i] = mrb_funcall(data->mrb, data->arg_types[i], "refer", 1, pointer); } - mrb_value block = mrb_iv_get(data->mrb, self, mrb_intern_cstr(data->mrb, "@block")); - mrb_value result = mrb_funcall_argv(data->mrb, block, mrb_intern_cstr(data->mrb, "call"), data->argc, ary); + mrb_value block = mrb_iv_get(data->mrb, self, mrb_intern_lit(data->mrb, "@block")); + mrb_value result = mrb_funcall_argv(data->mrb, block, mrb_intern_lit(data->mrb, "call"), data->argc, ary); mrb_free(data->mrb, ary); mrb_value ret_pointer = cfunc_pointer_new_with_pointer(data->mrb, ret, false); @@ -185,7 +185,7 @@ init_cfunc_closure(mrb_state *mrb, struct RClass* module) state->closure_class = closure_class; mrb_value ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_closure_ffi_type_data_type, &closure_mrb_ffi_type)); - mrb_obj_iv_set(mrb, (struct RObject*)closure_class, mrb_intern_cstr(mrb, "@ffi_type"), ffi_type); + mrb_obj_iv_set(mrb, (struct RObject*)closure_class, mrb_intern_lit(mrb, "@ffi_type"), ffi_type); mrb_define_method(mrb, closure_class, "initialize", cfunc_closure_initialize, ARGS_ANY()); } diff --git a/src/cfunc_pointer.c b/src/cfunc_pointer.c index 12ca494..e457acb 100644 --- a/src/cfunc_pointer.c +++ b/src/cfunc_pointer.c @@ -103,7 +103,7 @@ cfunc_pointer_refer(mrb_state *mrb, mrb_value klass) data->value._pointer = cfunc_pointer_ptr(pointer); struct RObject *obj = (struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_pointer_data_type, data); - mrb_obj_iv_set(mrb, obj, mrb_intern_cstr(mrb, "parent_pointer"), pointer); // keep for GC + mrb_obj_iv_set(mrb, obj, mrb_intern_lit(mrb, "parent_pointer"), pointer); // keep for GC return mrb_obj_value(obj); } @@ -166,7 +166,7 @@ cfunc_pointer_inspect(mrb_state *mrb, mrb_value self) struct cfunc_type_data *data = DATA_PTR(self); mrb_value type = mrb_funcall(mrb, mrb_obj_value(mrb_class(mrb, self)), "type", 0); - const char* classname = mrb_class_name(mrb, (struct RClass*)mrb_object(type)); + const char* classname = mrb_class_name(mrb, mrb_class_ptr(type)); if(!classname) { classname = "Unknown pointer"; } @@ -199,17 +199,8 @@ mrb_value cfunc_pointer_to_s(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data = DATA_PTR(self); - size_t len; - mrb_value str; - struct RString *s; const char* p = (const char*)get_cfunc_pointer_data(data); - - len = strlen(p); - str = mrb_str_new(mrb, 0, len); - s = mrb_str_ptr(str); - strcpy(s->ptr, p); - s->len = strlen(s->ptr); - return str; + return mrb_str_new_cstr(mrb, p); } @@ -225,7 +216,7 @@ cfunc_pointer_offset(mrb_state *mrb, mrb_value self) } else { mrb_value ptr = cfunc_pointer_new_with_pointer(mrb, (void*)((uint8_t*)get_cfunc_pointer_data(data) + offset), false); - mrb_obj_iv_set(mrb, mrb_obj_ptr(ptr), mrb_intern_cstr(mrb, "parent_pointer"), self); // keep for GC + mrb_obj_iv_set(mrb, mrb_obj_ptr(ptr), mrb_intern_lit(mrb, "parent_pointer"), self); // keep for GC return ptr; } } @@ -244,7 +235,7 @@ cfunc_pointer_addr(mrb_state *mrb, mrb_value self) } mrb_value obj = cfunc_pointer_new_with_pointer(mrb, ptr, false); - mrb_obj_iv_set(mrb, mrb_obj_ptr(obj), mrb_intern_cstr(mrb, "parent_pointer"), self); // keep for GC + mrb_obj_iv_set(mrb, mrb_obj_ptr(obj), mrb_intern_lit(mrb, "parent_pointer"), self); // keep for GC return obj; } @@ -252,8 +243,17 @@ cfunc_pointer_addr(mrb_state *mrb, mrb_value self) static mrb_value cfunc_string_addr(mrb_state *mrb, mrb_value self) { - mrb_value ptr = cfunc_pointer_new_with_pointer(mrb, &RSTRING_PTR(self), false); - mrb_obj_iv_set(mrb, mrb_obj_ptr(ptr), mrb_intern_cstr(mrb, "parent_pointer"), self); // keep for GC + // move string to heap + mrb_str_modify(mrb, RSTRING(self)); + if (RSTR_EMBED_P(RSTRING(self))) { + mrb_int const tmp_s = RSTRING_LEN(self); + mrb_str_resize(mrb, self, RSTRING_EMBED_LEN_MAX + 1); + mrb_str_resize(mrb, self, tmp_s); + mrb_assert(!RSTR_EMBED_P(RSTRING(self))); + } + + mrb_value ptr = cfunc_pointer_new_with_pointer(mrb, &RSTRING(self)->as.heap.ptr, false); + mrb_obj_iv_set(mrb, mrb_obj_ptr(ptr), mrb_intern_lit(mrb, "parent_pointer"), self); // keep for GC return ptr; } @@ -295,7 +295,7 @@ static void cfunc_pointer_ffi_data_destructor(mrb_state *mrb, void *p_) { // ToDo: when *p_ was local scope variant? -}; +} const struct mrb_data_type cfunc_pointer_ffi_data_type = { @@ -320,7 +320,7 @@ init_cfunc_pointer(mrb_state *mrb, struct RClass* module) struct RClass *pointer_class = mrb_define_class_under(mrb, module, "Pointer", state->type_class); mrb_value ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_pointer_ffi_data_type, &pointer_mrb_ffi_type)); - mrb_obj_iv_set(mrb, (struct RObject*)pointer_class, mrb_intern_cstr(mrb, "@ffi_type"), ffi_type); + mrb_obj_iv_set(mrb, (struct RObject*)pointer_class, mrb_intern_lit(mrb, "@ffi_type"), ffi_type); state->pointer_class = pointer_class; mrb_define_class_method(mrb, pointer_class, "refer", cfunc_pointer_refer, ARGS_REQ(1)); @@ -338,5 +338,5 @@ init_cfunc_pointer(mrb_state *mrb, struct RClass* module) // add method to system classes mrb_define_method(mrb, mrb->string_class, "addr", cfunc_string_addr, ARGS_NONE()); - mrb_obj_iv_set(mrb, (struct RObject *)mrb->string_class, mrb_intern_cstr(mrb, "@ffi_type"), ffi_type); + mrb_obj_iv_set(mrb, (struct RObject *)mrb->string_class, mrb_intern_lit(mrb, "@ffi_type"), ffi_type); } diff --git a/src/cfunc_rubyvm.c b/src/cfunc_rubyvm.c index eedd6a6..80e9089 100644 --- a/src/cfunc_rubyvm.c +++ b/src/cfunc_rubyvm.c @@ -79,7 +79,7 @@ struct task_arg* mrb_value_to_task_arg(mrb_state *mrb, mrb_value v) case MRB_TT_SYMBOL: { - size_t len; + mrb_int len; const char* name = mrb_sym2name_len(mrb, v.value.sym, &len); arg->value.string.len = len; arg->value.string.ptr = mrb_malloc(mrb, len + 1); @@ -89,10 +89,9 @@ struct task_arg* mrb_value_to_task_arg(mrb_state *mrb, mrb_value v) case MRB_TT_STRING: { - struct RString *str = mrb_str_ptr(v); - arg->value.string.len = str->len; + arg->value.string.len = RSTRING_LEN(v); arg->value.string.ptr = mrb_malloc(mrb, arg->value.string.len+1); - memcpy(arg->value.string.ptr, str->ptr, arg->value.string.len+1); + memcpy(arg->value.string.ptr, RSTRING_PTR(v), arg->value.string.len+1); } break; @@ -214,7 +213,7 @@ static void cfunc_rubyvm_data_destructor(mrb_state *mrb, void *p_) { // todo -}; +} const struct mrb_data_type cfunc_rubyvm_data_type = { @@ -228,7 +227,7 @@ static void cfunc_rubyvm_task_data_destructor(mrb_state *mrb, void *p) { free_queue_task(mrb, (struct queue_task*)p); -}; +} const struct mrb_data_type cfunc_rubyvm_task_data_type = { @@ -294,7 +293,7 @@ cfunc_rubyvm_dispatch(mrb_state *mrb, mrb_value self) struct cfunc_rubyvm_data *data = mrb_data_check_get_ptr(mrb, self, &cfunc_rubyvm_data_type); mrb_value name_obj, *args; - int args_len; + mrb_int args_len; mrb_get_args(mrb, "o*", &name_obj, &args, &args_len); struct queue_task *task = mrb_malloc(mrb, sizeof(struct queue_task)); @@ -368,7 +367,7 @@ cfunc_rubyvm_class_thread(mrb_state *mrb, mrb_value klass) // load script mrb_value filename, str; mrb_get_args(mrb, "S", &filename); - str = mrb_str_new_cstr(mrb, "mruby_data_"); + str = mrb_str_new_lit(mrb, "mruby_data_"); mrb_str_concat(mrb, str, mrb_str_new(mrb, RSTRING_PTR(filename), RSTRING_LEN(filename))); void *dlh = dlopen(NULL, RTLD_LAZY); @@ -376,7 +375,7 @@ cfunc_rubyvm_class_thread(mrb_state *mrb, mrb_value klass) if (!data->mrb_data) { dlclose(dlh); - mrb_raisef(mrb, E_SCRIPT_ERROR, "file '%s' not found.", RSTRING_PTR(str)); + mrb_raisef(mrb, E_SCRIPT_ERROR, "file '%S' not found.", str); } // initial pthread diff --git a/src/cfunc_struct.c b/src/cfunc_struct.c index 913d452..029bbfd 100644 --- a/src/cfunc_struct.c +++ b/src/cfunc_struct.c @@ -23,7 +23,7 @@ static void cfunc_struct_data_destructor(mrb_state *mrb, void *p_) { // todo -}; +} const struct mrb_data_type cfunc_struct_data_type = { @@ -72,7 +72,7 @@ cfunc_struct_define_struct(mrb_state *mrb, mrb_value klass) mft->c_to_mrb = &cfunc_type_ffi_struct_c_to_mrb; mrb_value __ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_struct_data_type, mft)); - mrb_obj_iv_set(mrb, (struct RObject*)(mrb_class_ptr(klass)), mrb_intern_cstr(mrb, "@ffi_type"), __ffi_type); + mrb_obj_iv_set(mrb, (struct RObject*)(mrb_class_ptr(klass)), mrb_intern_lit(mrb, "@ffi_type"), __ffi_type); return mrb_nil_value(); } diff --git a/src/cfunc_type.c b/src/cfunc_type.c index d4f0768..a916ee2 100644 --- a/src/cfunc_type.c +++ b/src/cfunc_type.c @@ -44,13 +44,13 @@ rclass_to_mrb_ffi_type(mrb_state *mrb, struct RClass *cls) { struct RClass *cls_ = cls; while(cls) { - mrb_value ffi_type = mrb_obj_iv_get(mrb, (struct RObject*)cls, mrb_intern_cstr(mrb, "@ffi_type")); + mrb_value ffi_type = mrb_obj_iv_get(mrb, (struct RObject*)cls, mrb_intern_lit(mrb, "@ffi_type")); if(mrb_test(ffi_type)) { return (struct mrb_ffi_type*)DATA_PTR(ffi_type); } cls = cls->super; } - mrb_raisef(mrb, E_TYPE_ERROR, "%s cannot convert to C value", mrb_class_name(mrb, cls_)); + mrb_raisef(mrb, E_TYPE_ERROR, "%S cannot convert to C value", mrb_class_path(mrb, cls_)); return NULL; } @@ -66,7 +66,7 @@ mrb_value_to_mrb_ffi_type(mrb_state *mrb, mrb_value val) case MRB_TT_FALSE: return rclass_to_mrb_ffi_type(mrb, cfunc_state(mrb, NULL)->sint32_class); default: - return rclass_to_mrb_ffi_type(mrb, mrb_object(val)->c); + return rclass_to_mrb_ffi_type(mrb, mrb_class(mrb, val)); } } @@ -85,7 +85,7 @@ cfunc_type_class_refer(mrb_state *mrb, mrb_value klass) data->value._pointer = cfunc_pointer_ptr(pointer); struct RObject *obj = (struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_type_data, data); - mrb_obj_iv_set(mrb, obj, mrb_intern_cstr(mrb, "parent_pointer"), pointer); // keep for GC + mrb_obj_iv_set(mrb, obj, mrb_intern_lit(mrb, "parent_pointer"), pointer); // keep for GC return mrb_obj_value(obj); } @@ -107,7 +107,7 @@ cfunc_type_initialize(mrb_state *mrb, mrb_value self) mrb_value val; int argc = mrb_get_args(mrb, "|o", &val); if(argc > 0) { - struct mrb_ffi_type *mft = rclass_to_mrb_ffi_type(mrb, mrb_object(self)->c); + struct mrb_ffi_type *mft = rclass_to_mrb_ffi_type(mrb, mrb_class(mrb, self)); if(mft && mft->mrb_to_data) { mft->mrb_to_data(mrb, val, data); } @@ -164,7 +164,7 @@ mrb_value cfunc_type_get_value(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); - struct mrb_ffi_type *mft = rclass_to_mrb_ffi_type(mrb, mrb_object(self)->c); + struct mrb_ffi_type *mft = rclass_to_mrb_ffi_type(mrb, mrb_class(mrb, self)); return mft->data_to_mrb(mrb, data); } @@ -176,7 +176,7 @@ cfunc_type_set_value(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "o", &val); struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); - struct mrb_ffi_type *mft = rclass_to_mrb_ffi_type(mrb, mrb_object(self)->c); + struct mrb_ffi_type *mft = rclass_to_mrb_ffi_type(mrb, mrb_class(mrb, self)); mft->mrb_to_data(mrb, val, data); return val; @@ -196,7 +196,7 @@ cfunc_type_addr(mrb_state *mrb, mrb_value self) ptr = cfunc_pointer_new_with_pointer(mrb, &data->value._pointer, false); } - mrb_obj_iv_set(mrb, mrb_obj_ptr(ptr), mrb_intern_cstr(mrb, "parent_pointer"), self); // keep for GC + mrb_obj_iv_set(mrb, mrb_obj_ptr(ptr), mrb_intern_lit(mrb, "parent_pointer"), self); // keep for GC return ptr; } @@ -248,8 +248,8 @@ int64_t mrb_to_int64(mrb_state *mrb, mrb_value val) } default: - mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %s given", - mrb_obj_classname(mrb, val)); + mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", + mrb_class_path(mrb, mrb_class(mrb, val))); } return 0; // can't reach here } @@ -291,8 +291,8 @@ mrb_float float_value(mrb_state *mrb, mrb_value val) } default: - mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %s given", - mrb_obj_classname(mrb, val)); + mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %S given", + mrb_class_path(mrb, mrb_class(mrb, val))); } return 0.0; // can't reach here } @@ -462,7 +462,7 @@ cfunc_nil_addr(mrb_state *mrb, mrb_value self) ptr = cfunc_pointer_new_with_pointer(mrb, &data->value._pointer, false); } - mrb_obj_iv_set(mrb, mrb_obj_ptr(ptr), mrb_intern_cstr(mrb, "parent_pointer"), self); // keep for GC + mrb_obj_iv_set(mrb, mrb_obj_ptr(ptr), mrb_intern_lit(mrb, "parent_pointer"), self); // keep for GC return ptr; } @@ -594,20 +594,20 @@ cfunc_type_ffi_##name##_mrb_to_data(mrb_state *mrb, mrb_value val, struct cfunc_ .data_to_mrb = &cfunc_type_ffi_##type_##_data_to_mrb \ } -define_cfunc_type(sint8, &ffi_type_sint8, int8_t, int64_to_mrb, mrb_to_int64); -define_cfunc_type(uint8, &ffi_type_uint8, uint8_t, int64_to_mrb, mrb_to_int64); +define_cfunc_type(sint8, &ffi_type_sint8, int8_t, int64_to_mrb, mrb_to_int64) +define_cfunc_type(uint8, &ffi_type_uint8, uint8_t, int64_to_mrb, mrb_to_int64) -define_cfunc_type(sint16, &ffi_type_sint16, int16_t, int64_to_mrb, mrb_to_int64); -define_cfunc_type(uint16, &ffi_type_uint16, uint16_t, int64_to_mrb, mrb_to_int64); +define_cfunc_type(sint16, &ffi_type_sint16, int16_t, int64_to_mrb, mrb_to_int64) +define_cfunc_type(uint16, &ffi_type_uint16, uint16_t, int64_to_mrb, mrb_to_int64) -define_cfunc_type(sint32, &ffi_type_sint32, int32_t, int64_to_mrb, mrb_to_int64); -define_cfunc_type(uint32, &ffi_type_uint32, uint32_t, int64_to_mrb, mrb_to_int64); +define_cfunc_type(sint32, &ffi_type_sint32, int32_t, int64_to_mrb, mrb_to_int64) +define_cfunc_type(uint32, &ffi_type_uint32, uint32_t, int64_to_mrb, mrb_to_int64) -define_cfunc_type(sint64, &ffi_type_sint64, int64_t, int64_to_mrb, mrb_to_int64); -define_cfunc_type(uint64, &ffi_type_uint64, uint64_t, int64_to_mrb, mrb_to_int64); +define_cfunc_type(sint64, &ffi_type_sint64, int64_t, int64_to_mrb, mrb_to_int64) +define_cfunc_type(uint64, &ffi_type_uint64, uint64_t, int64_to_mrb, mrb_to_int64) -define_cfunc_type(float, &ffi_type_float, float, mrb_float_value, float_value); -define_cfunc_type(double, &ffi_type_double, double, mrb_float_value, float_value); +define_cfunc_type(float, &ffi_type_float, float, mrb_float_value, float_value) +define_cfunc_type(double, &ffi_type_double, double, mrb_float_value, float_value) static struct mrb_ffi_type types[] = { @@ -661,22 +661,22 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module) for(i = 0; i < map_size; ++i) { struct RClass *new_class = mrb_define_class_under(mrb, module, types[i].name, type_class); mrb_value ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_class_ffi_data_type, &types[i])); - mrb_obj_iv_set(mrb, (struct RObject*)new_class, mrb_intern_cstr(mrb, "@ffi_type"), ffi_type); + mrb_obj_iv_set(mrb, (struct RObject*)new_class, mrb_intern_lit(mrb, "@ffi_type"), ffi_type); } DONE; mrb_value mod = mrb_obj_value(module); - state->void_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "Void"))); - state->uint8_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "UInt8"))); - state->sint8_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "SInt8"))); - state->uint16_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "UInt16"))); - state->sint16_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "SInt16"))); - state->uint32_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "UInt32"))); - state->sint32_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "SInt32"))); - state->uint64_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "UInt64"))); - state->sint64_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "SInt64"))); - state->float_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "Float"))); - state->double_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_cstr(mrb, "Double"))); + state->void_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "Void"))); + state->uint8_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "UInt8"))); + state->sint8_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "SInt8"))); + state->uint16_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "UInt16"))); + state->sint16_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "SInt16"))); + state->uint32_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "UInt32"))); + state->sint32_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "SInt32"))); + state->uint64_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "UInt64"))); + state->sint64_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "SInt64"))); + state->float_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "Float"))); + state->double_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "Double"))); DONE; mrb_define_class_method(mrb, mrb->nil_class, "size", cfunc_nil_size, ARGS_NONE()); diff --git a/src/cfunc_utils.c b/src/cfunc_utils.c index 23ed150..890c6ef 100644 --- a/src/cfunc_utils.c +++ b/src/cfunc_utils.c @@ -25,5 +25,5 @@ cfunc_mrb_raise_without_jump(mrb_state *mrb, struct RClass *c, const char *fmt, if (n < 0) { n = 0; } - mrb->exc = (struct RObject*)mrb_object(mrb_exc_new(mrb, c, buf, n)); + mrb->exc = mrb_obj_ptr(mrb_exc_new(mrb, c, buf, n)); } diff --git a/src/vector.c b/src/vector.c index 7e6c41c..08c75b1 100644 --- a/src/vector.c +++ b/src/vector.c @@ -106,7 +106,7 @@ int vector_set(vector_p vec, size_t i, void* data){ } int vector_insert(vector_p vec, size_t i, void* data){ - int x; + size_t x; if(i > vec->length) return -1; @@ -121,7 +121,7 @@ int vector_insert(vector_p vec, size_t i, void* data){ } void vector_remove(vector_p vec, size_t i){ - int x; + size_t x; if(i >= vec->length) return; vec->length--; @@ -131,7 +131,7 @@ void vector_remove(vector_p vec, size_t i){ } int vector_index(vector_p vec, void* data){ - int x; + size_t x; for(x=0;xlength;++x){ if(vec->data[x] == data){ return x; diff --git a/test/func.c b/test/func.c index 6d1b9d8..586e5f2 100644 --- a/test/func.c +++ b/test/func.c @@ -10,7 +10,7 @@ struct STest { struct STest cfunc_test_func1(struct STest val) { val.z = val.x + val.y; return val; -}; +} struct STest2 { struct STest s; @@ -20,7 +20,7 @@ struct STest2 { struct STest2 cfunc_test_func2(struct STest2 val) { val.xx = (double)(val.s.x + val.s.y) / val.s.z; return val; -}; +} int cfunc_test_func3(int (*func)(uint32_t, uint32_t)) { return func(10, 20); From 28a257807cb653f8ad703ab41f4ad78722ffd06b Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Sat, 30 May 2015 21:55:20 +0900 Subject: [PATCH 02/29] Suppress warning in assert call. --- test/sint64.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/sint64.rb b/test/sint64.rb index bd0a43d..0ed7793 100644 --- a/test/sint64.rb +++ b/test/sint64.rb @@ -34,7 +34,7 @@ sint.value = -1 assert_equal 0xffffffff, sint.low assert_equal 0xffffffff, sint.high - assert_equal -1, CFunc::SInt64.get(sint_ptr) + assert_equal(-1, CFunc::SInt64.get(sint_ptr)) sint = CFunc::SInt64.new(CFunc::SInt16.new(16)) assert_equal 16, sint.value From 559f36ff84ebe52a8fee5f8b95ecbe1ac45230de Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Sat, 30 May 2015 21:55:43 +0900 Subject: [PATCH 03/29] Pack arguments in `cfunc_closure_call_binding`. --- include/cfunc_closure.h | 2 ++ src/cfunc_closure.c | 41 ++++++++++++++++++++++++++++------------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/include/cfunc_closure.h b/include/cfunc_closure.h index e4a9697..04bf88b 100644 --- a/include/cfunc_closure.h +++ b/include/cfunc_closure.h @@ -29,6 +29,8 @@ struct cfunc_closure_data { mrb_value return_type; void *closure_pointer; + + int packed_args_size; }; #define cfunc_closure_data_pointer(mrb, val) \ diff --git a/src/cfunc_closure.c b/src/cfunc_closure.c index ca2ad06..497763f 100644 --- a/src/cfunc_closure.c +++ b/src/cfunc_closure.c @@ -67,6 +67,7 @@ cfunc_closure_initialize(mrb_state *mrb, mrb_value self) data->mrb = mrb; data->closure = NULL; data->arg_types = NULL; + data->packed_args_size = -1; mrb_value rettype_mrb, block, args_mrb; mrb_get_args(mrb, "&oo", &block, &rettype_mrb, &args_mrb); @@ -108,27 +109,41 @@ cfunc_closure_call_binding(ffi_cif *cif, void *ret, void **args, void *self_) { mrb_value self = mrb_obj_value(self_); struct cfunc_closure_data *data = DATA_PTR(self); + mrb_state *mrb = data->mrb; - int ai = mrb_gc_arena_save(data->mrb); + int ai = mrb_gc_arena_save(mrb); - mrb_value *ary = mrb_malloc(data->mrb, sizeof(mrb_value) * data->argc); + mrb_value *ary = mrb_malloc(mrb, sizeof(mrb_value) * data->argc); int i; + if (data->packed_args_size == -1) { + // calculate packed args size + size_t result = 0; + for (i = 0; i < data->argc; ++i) { + ffi_type const *t = data->arg_ffi_types[i]; + result += t->size + ((t->alignment - (t->size % t->alignment)) % t->alignment); + } + data->packed_args_size = result; + } + void *packed_args = mrb_malloc(mrb, data->packed_args_size); + mrb_value packed_args_value = cfunc_pointer_new_with_pointer(mrb, packed_args, true); + void *p = packed_args; for (i = 0; i < data->argc; ++i) { - // TODO: I felt too much consume memory - void *p = mrb_malloc(data->mrb, data->arg_ffi_types[i]->size); - memcpy(p, args[i], data->arg_ffi_types[i]->size); - mrb_value pointer = cfunc_pointer_new_with_pointer(data->mrb, p, true); - ary[i] = mrb_funcall(data->mrb, data->arg_types[i], "refer", 1, pointer); + ffi_type const *t = data->arg_ffi_types[i]; + memcpy(p, args[i], t->size); + mrb_value pointer = cfunc_pointer_new_with_pointer(mrb, p, false); + mrb_iv_set(mrb, pointer, mrb_intern_lit(mrb, "parent_pointer"), packed_args_value); // for GC + p = ((uint8_t*)p) + t->size + ((t->alignment - (t->size % t->alignment)) % t->alignment); + ary[i] = mrb_funcall(mrb, data->arg_types[i], "refer", 1, pointer); } - mrb_value block = mrb_iv_get(data->mrb, self, mrb_intern_lit(data->mrb, "@block")); - mrb_value result = mrb_funcall_argv(data->mrb, block, mrb_intern_lit(data->mrb, "call"), data->argc, ary); - mrb_free(data->mrb, ary); + mrb_value block = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@block")); + mrb_value result = mrb_funcall_argv(mrb, block, mrb_intern_lit(mrb, "call"), data->argc, ary); + mrb_free(mrb, ary); - mrb_value ret_pointer = cfunc_pointer_new_with_pointer(data->mrb, ret, false); - mrb_funcall(data->mrb, data->return_type, "set", 2, ret_pointer, result); + mrb_value ret_pointer = cfunc_pointer_new_with_pointer(mrb, ret, false); + mrb_funcall(mrb, data->return_type, "set", 2, ret_pointer, result); - mrb_gc_arena_restore(data->mrb, ai); + mrb_gc_arena_restore(mrb, ai); } From 271269f404300d8195be232bd6b5fcf50fb4ac64 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Thu, 25 Jun 2015 01:31:27 +0900 Subject: [PATCH 04/29] Replace deprecated macro. --- src/cfunc.c | 6 ++--- src/cfunc_call.c | 4 ++-- src/cfunc_closure.c | 2 +- src/cfunc_platform.c | 6 ++--- src/cfunc_pointer.c | 26 ++++++++++---------- src/cfunc_rubyvm.c | 10 ++++---- src/cfunc_struct.c | 2 +- src/cfunc_type.c | 56 ++++++++++++++++++++++---------------------- 8 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/cfunc.c b/src/cfunc.c index 4b8fec9..945dbdf 100644 --- a/src/cfunc.c +++ b/src/cfunc.c @@ -58,9 +58,9 @@ mrb_mruby_cfunc_gem_init(mrb_state* mrb) init_cfunc_rubyvm(mrb, ns); mrb_gc_arena_restore(mrb, ai); init_cfunc_platform(mrb, ns); mrb_gc_arena_restore(mrb, ai); - mrb_define_class_method(mrb, ns, "mrb_state", cfunc_mrb_state, ARGS_NONE()); - mrb_define_class_method(mrb, ns, "errno", cfunc_errno, ARGS_NONE()); - mrb_define_class_method(mrb, ns, "strerror", cfunc_strerror, ARGS_NONE()); + mrb_define_class_method(mrb, ns, "mrb_state", cfunc_mrb_state, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, ns, "errno", cfunc_errno, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, ns, "strerror", cfunc_strerror, MRB_ARGS_NONE()); } void diff --git a/src/cfunc_call.c b/src/cfunc_call.c index 27aea01..d625852 100644 --- a/src/cfunc_call.c +++ b/src/cfunc_call.c @@ -222,6 +222,6 @@ cfunc_libcall(mrb_state *mrb, mrb_value self) void init_cfunc_call(mrb_state *mrb, struct RClass* module) { - mrb_define_class_method(mrb, module, "call", cfunc_call, ARGS_ANY()); - mrb_define_module_function(mrb, module, "libcall", cfunc_libcall, ARGS_ANY()); + mrb_define_class_method(mrb, module, "call", cfunc_call, MRB_ARGS_ANY()); + mrb_define_module_function(mrb, module, "libcall", cfunc_libcall, MRB_ARGS_ANY()); } diff --git a/src/cfunc_closure.c b/src/cfunc_closure.c index 497763f..bf89c8d 100644 --- a/src/cfunc_closure.c +++ b/src/cfunc_closure.c @@ -202,5 +202,5 @@ init_cfunc_closure(mrb_state *mrb, struct RClass* module) mrb_value ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_closure_ffi_type_data_type, &closure_mrb_ffi_type)); mrb_obj_iv_set(mrb, (struct RObject*)closure_class, mrb_intern_lit(mrb, "@ffi_type"), ffi_type); - mrb_define_method(mrb, closure_class, "initialize", cfunc_closure_initialize, ARGS_ANY()); + mrb_define_method(mrb, closure_class, "initialize", cfunc_closure_initialize, MRB_ARGS_ANY()); } diff --git a/src/cfunc_platform.c b/src/cfunc_platform.c index 0cd52a7..964e416 100644 --- a/src/cfunc_platform.c +++ b/src/cfunc_platform.c @@ -45,7 +45,7 @@ void init_cfunc_platform(mrb_state *mrb, struct RClass* module) { struct RClass *struct_class = mrb_define_class_under(mrb, module, "Platform", mrb->object_class); - mrb_define_class_method(mrb, struct_class, "is_posix?", cfunc_platform_is_posix, ARGS_NONE()); - mrb_define_class_method(mrb, struct_class, "is_win32?", cfunc_platform_is_win32, ARGS_NONE()); - mrb_define_class_method(mrb, struct_class, "is_darwin?", cfunc_platform_is_darwin, ARGS_NONE()); + mrb_define_class_method(mrb, struct_class, "is_posix?", cfunc_platform_is_posix, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, struct_class, "is_win32?", cfunc_platform_is_win32, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, struct_class, "is_darwin?", cfunc_platform_is_darwin, MRB_ARGS_NONE()); } diff --git a/src/cfunc_pointer.c b/src/cfunc_pointer.c index e457acb..f6da2ee 100644 --- a/src/cfunc_pointer.c +++ b/src/cfunc_pointer.c @@ -323,20 +323,20 @@ init_cfunc_pointer(mrb_state *mrb, struct RClass* module) mrb_obj_iv_set(mrb, (struct RObject*)pointer_class, mrb_intern_lit(mrb, "@ffi_type"), ffi_type); state->pointer_class = pointer_class; - mrb_define_class_method(mrb, pointer_class, "refer", cfunc_pointer_refer, ARGS_REQ(1)); - mrb_define_class_method(mrb, pointer_class, "malloc", cfunc_pointer_class_malloc, ARGS_REQ(1)); - - mrb_define_method(mrb, pointer_class, "initialize", cfunc_pointer_initialize, ARGS_ANY()); - mrb_define_method(mrb, pointer_class, "realloc", cfunc_pointer_realloc, ARGS_REQ(1)); - mrb_define_method(mrb, pointer_class, "free", cfunc_pointer_free, ARGS_NONE()); - mrb_define_method(mrb, pointer_class, "inspect", cfunc_pointer_inspect, ARGS_NONE()); - mrb_define_method(mrb, pointer_class, "is_null?", cfunc_pointer_is_null, ARGS_NONE()); - mrb_define_method(mrb, pointer_class, "autofree", cfunc_pointer_autofree, ARGS_NONE()); - - mrb_define_method(mrb, pointer_class, "offset", cfunc_pointer_offset, ARGS_REQ(1)); - mrb_define_method(mrb, pointer_class, "to_s", cfunc_pointer_to_s, ARGS_NONE()); + mrb_define_class_method(mrb, pointer_class, "refer", cfunc_pointer_refer, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, pointer_class, "malloc", cfunc_pointer_class_malloc, MRB_ARGS_REQ(1)); + + mrb_define_method(mrb, pointer_class, "initialize", cfunc_pointer_initialize, MRB_ARGS_ANY()); + mrb_define_method(mrb, pointer_class, "realloc", cfunc_pointer_realloc, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, pointer_class, "free", cfunc_pointer_free, MRB_ARGS_NONE()); + mrb_define_method(mrb, pointer_class, "inspect", cfunc_pointer_inspect, MRB_ARGS_NONE()); + mrb_define_method(mrb, pointer_class, "is_null?", cfunc_pointer_is_null, MRB_ARGS_NONE()); + mrb_define_method(mrb, pointer_class, "autofree", cfunc_pointer_autofree, MRB_ARGS_NONE()); + + mrb_define_method(mrb, pointer_class, "offset", cfunc_pointer_offset, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, pointer_class, "to_s", cfunc_pointer_to_s, MRB_ARGS_NONE()); // add method to system classes - mrb_define_method(mrb, mrb->string_class, "addr", cfunc_string_addr, ARGS_NONE()); + mrb_define_method(mrb, mrb->string_class, "addr", cfunc_string_addr, MRB_ARGS_NONE()); mrb_obj_iv_set(mrb, (struct RObject *)mrb->string_class, mrb_intern_lit(mrb, "@ffi_type"), ffi_type); } diff --git a/src/cfunc_rubyvm.c b/src/cfunc_rubyvm.c index 80e9089..7788bff 100644 --- a/src/cfunc_rubyvm.c +++ b/src/cfunc_rubyvm.c @@ -397,15 +397,15 @@ init_cfunc_rubyvm(mrb_state *mrb, struct RClass* module) state->rubyvm_class = rubyvm_class; set_cfunc_state(mrb, rubyvm_class, state); - mrb_define_class_method(mrb, rubyvm_class, "thread", cfunc_rubyvm_class_thread, ARGS_REQ(1)); - mrb_define_method(mrb, rubyvm_class, "dispatch", cfunc_rubyvm_dispatch, ARGS_ANY()); + mrb_define_class_method(mrb, rubyvm_class, "thread", cfunc_rubyvm_class_thread, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, rubyvm_class, "dispatch", cfunc_rubyvm_dispatch, MRB_ARGS_ANY()); struct RClass *rubyvm_task_class = mrb_define_class_under(mrb, rubyvm_class, "Task", mrb->object_class); state->rubyvm_task_class = rubyvm_task_class; - mrb_define_method(mrb, rubyvm_task_class, "wait", cfunc_rubyvm_task_wait, ARGS_NONE()); - mrb_define_method(mrb, rubyvm_task_class, "result", cfunc_rubyvm_task_result, ARGS_NONE()); - mrb_define_method(mrb, rubyvm_task_class, "status", cfunc_rubyvm_task_status, ARGS_NONE()); + mrb_define_method(mrb, rubyvm_task_class, "wait", cfunc_rubyvm_task_wait, MRB_ARGS_NONE()); + mrb_define_method(mrb, rubyvm_task_class, "result", cfunc_rubyvm_task_result, MRB_ARGS_NONE()); + mrb_define_method(mrb, rubyvm_task_class, "status", cfunc_rubyvm_task_status, MRB_ARGS_NONE()); mrb_define_const(mrb, rubyvm_task_class, "QUEUED", mrb_fixnum_value(queue_task_queued)); mrb_define_const(mrb, rubyvm_task_class, "RUNNING", mrb_fixnum_value(queue_task_running)); diff --git a/src/cfunc_struct.c b/src/cfunc_struct.c index 029bbfd..3f84bcc 100644 --- a/src/cfunc_struct.c +++ b/src/cfunc_struct.c @@ -86,5 +86,5 @@ init_cfunc_struct(mrb_state *mrb, struct RClass* module) set_cfunc_state(mrb, struct_class, state); state->struct_class = struct_class; - mrb_define_class_method(mrb, struct_class, "define_struct", cfunc_struct_define_struct, ARGS_REQ(1)); + mrb_define_class_method(mrb, struct_class, "define_struct", cfunc_struct_define_struct, MRB_ARGS_REQ(1)); } diff --git a/src/cfunc_type.c b/src/cfunc_type.c index a916ee2..971981c 100644 --- a/src/cfunc_type.c +++ b/src/cfunc_type.c @@ -643,17 +643,17 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module) set_cfunc_state(mrb, type_class, state); int ai = mrb_gc_arena_save(mrb); - mrb_define_class_method(mrb, type_class, "refer", cfunc_type_class_refer, ARGS_REQ(1)); - mrb_define_class_method(mrb, type_class, "size", cfunc_type_size, ARGS_NONE()); - mrb_define_class_method(mrb, type_class, "align", cfunc_type_align, ARGS_NONE()); - mrb_define_class_method(mrb, type_class, "get", cfunc_type_class_get, ARGS_REQ(1)); - mrb_define_class_method(mrb, type_class, "set", cfunc_type_class_set, ARGS_REQ(2)); - - mrb_define_method(mrb, type_class, "initialize", cfunc_type_initialize, ARGS_ANY()); - mrb_define_method(mrb, type_class, "value", cfunc_type_get_value, ARGS_NONE()); - mrb_define_method(mrb, type_class, "value=", cfunc_type_set_value, ARGS_REQ(1)); - mrb_define_method(mrb, type_class, "addr", cfunc_type_addr, ARGS_NONE()); - mrb_define_method(mrb, type_class, "to_ffi_value", cfunc_type_addr, ARGS_NONE()); + mrb_define_class_method(mrb, type_class, "refer", cfunc_type_class_refer, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, type_class, "size", cfunc_type_size, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, type_class, "align", cfunc_type_align, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, type_class, "get", cfunc_type_class_get, MRB_ARGS_REQ(1)); + mrb_define_class_method(mrb, type_class, "set", cfunc_type_class_set, MRB_ARGS_REQ(2)); + + mrb_define_method(mrb, type_class, "initialize", cfunc_type_initialize, MRB_ARGS_ANY()); + mrb_define_method(mrb, type_class, "value", cfunc_type_get_value, MRB_ARGS_NONE()); + mrb_define_method(mrb, type_class, "value=", cfunc_type_set_value, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, type_class, "addr", cfunc_type_addr, MRB_ARGS_NONE()); + mrb_define_method(mrb, type_class, "to_ffi_value", cfunc_type_addr, MRB_ARGS_NONE()); DONE; int map_size = sizeof(types) / sizeof(struct mrb_ffi_type); @@ -679,30 +679,30 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module) state->double_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "Double"))); DONE; - mrb_define_class_method(mrb, mrb->nil_class, "size", cfunc_nil_size, ARGS_NONE()); - mrb_define_class_method(mrb, mrb->nil_class, "align", cfunc_nil_align, ARGS_NONE()); + mrb_define_class_method(mrb, mrb->nil_class, "size", cfunc_nil_size, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, mrb->nil_class, "align", cfunc_nil_align, MRB_ARGS_NONE()); DONE; // uint64 specific struct RClass *uint64_class = state->uint64_class; - mrb_define_class_method(mrb, uint64_class, "get", cfunc_uint64_class_get, ARGS_REQ(1)); - mrb_define_method(mrb, uint64_class, "value", cfunc_uint64_get_value, ARGS_NONE()); - mrb_define_method(mrb, uint64_class, "low", cfunc_uint64_get_low, ARGS_NONE()); - mrb_define_method(mrb, uint64_class, "low=", cfunc_uint64_set_low, ARGS_REQ(1)); - mrb_define_method(mrb, uint64_class, "high", cfunc_uint64_get_high, ARGS_NONE()); - mrb_define_method(mrb, uint64_class, "high=", cfunc_uint64_set_high, ARGS_REQ(1)); - mrb_define_method(mrb, uint64_class, "to_s", cfunc_uint64_to_s, ARGS_REQ(1)); - mrb_define_method(mrb, uint64_class, "divide", cfunc_uint64_divide, ARGS_REQ(1)); + mrb_define_class_method(mrb, uint64_class, "get", cfunc_uint64_class_get, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, uint64_class, "value", cfunc_uint64_get_value, MRB_ARGS_NONE()); + mrb_define_method(mrb, uint64_class, "low", cfunc_uint64_get_low, MRB_ARGS_NONE()); + mrb_define_method(mrb, uint64_class, "low=", cfunc_uint64_set_low, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, uint64_class, "high", cfunc_uint64_get_high, MRB_ARGS_NONE()); + mrb_define_method(mrb, uint64_class, "high=", cfunc_uint64_set_high, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, uint64_class, "to_s", cfunc_uint64_to_s, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, uint64_class, "divide", cfunc_uint64_divide, MRB_ARGS_REQ(1)); DONE; // sint64 specific struct RClass *sint64_class = state->sint64_class; - mrb_define_class_method(mrb, sint64_class, "get", cfunc_sint64_class_get, ARGS_REQ(1)); - mrb_define_method(mrb, sint64_class, "value", cfunc_sint64_get_value, ARGS_NONE()); - mrb_define_method(mrb, sint64_class, "low", cfunc_uint64_get_low, ARGS_NONE()); - mrb_define_method(mrb, sint64_class, "low=", cfunc_uint64_set_low, ARGS_REQ(1)); - mrb_define_method(mrb, sint64_class, "high", cfunc_uint64_get_high, ARGS_NONE()); - mrb_define_method(mrb, sint64_class, "high=", cfunc_uint64_set_high, ARGS_REQ(1)); - mrb_define_method(mrb, sint64_class, "to_s", cfunc_int64_to_s, ARGS_REQ(1)); + mrb_define_class_method(mrb, sint64_class, "get", cfunc_sint64_class_get, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, sint64_class, "value", cfunc_sint64_get_value, MRB_ARGS_NONE()); + mrb_define_method(mrb, sint64_class, "low", cfunc_uint64_get_low, MRB_ARGS_NONE()); + mrb_define_method(mrb, sint64_class, "low=", cfunc_uint64_set_low, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, sint64_class, "high", cfunc_uint64_get_high, MRB_ARGS_NONE()); + mrb_define_method(mrb, sint64_class, "high=", cfunc_uint64_set_high, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, sint64_class, "to_s", cfunc_int64_to_s, MRB_ARGS_REQ(1)); DONE; } From 82133f651e2540fe00a7fc99fd126ba43844a479 Mon Sep 17 00:00:00 2001 From: Takeshi Watanabe Date: Sun, 25 Mar 2018 17:40:42 +0900 Subject: [PATCH 05/29] Fixes for latest mruby. --- include/cfunc.h | 3 +- mrbgem.rake | 6 ++-- src/cfunc.c | 3 +- src/cfunc_call.c | 34 ++++++++++-------- src/cfunc_closure.c | 30 +++++++++------- src/cfunc_pointer.c | 24 ++++++++----- src/cfunc_rubyvm.c | 84 ++++++++++++++++++++++++++++++--------------- src/cfunc_struct.c | 26 ++++++++------ src/cfunc_type.c | 52 +++++++++++++++++----------- 9 files changed, 165 insertions(+), 97 deletions(-) diff --git a/include/cfunc.h b/include/cfunc.h index a3d07d6..f3994ac 100644 --- a/include/cfunc.h +++ b/include/cfunc.h @@ -57,10 +57,11 @@ struct cfunc_state { static inline struct cfunc_state * cfunc_state(mrb_state *mrb, struct RClass* obj) { + mrb_value state; if(obj == NULL) { obj = mrb_module_get(mrb, "CFunc"); } - mrb_value state = mrb_mod_cv_get(mrb, obj, mrb_intern_lit(mrb, "cfunc_state")); + state = mrb_mod_cv_get(mrb, obj, mrb_intern_lit(mrb, "cfunc_state")); return (struct cfunc_state *)mrb_cptr(state); } diff --git a/mrbgem.rake b/mrbgem.rake index dca5e5a..1828941 100644 --- a/mrbgem.rake +++ b/mrbgem.rake @@ -4,8 +4,8 @@ MRuby::Gem::Specification.new('mruby-cfunc') do |spec| spec.license = 'MIT' spec.authors = 'MobiRuby developers' - spec.add_dependency 'mruby-print', :core => 'mruby-print' - spec.add_dependency 'mruby-enumerator', :core => 'mruby-enumerator' + add_test_dependency 'mruby-print', core: 'mruby-print' + add_dependency 'mruby-enumerator', core: 'mruby-enumerator' def spec.use_pkg_config(pkg_config='pkg-config') self.linker.flags << `"#{pkg_config}" libffi --libs-only-L --libs-only-other`.chomp @@ -14,6 +14,8 @@ MRuby::Gem::Specification.new('mruby-cfunc') do |spec| end end + spec.respond_to?(:search_package) && spec.search_package('libffi') + def spec.download_libffi(libffi_version = '3.0.13', tar = 'tar') libffi_url = "ftp://sourceware.org/pub/libffi/libffi-#{libffi_version}.tar.gz" libffi_build_root = "#{MRUBY_ROOT}/build/libffi/#{build.name}" diff --git a/src/cfunc.c b/src/cfunc.c index 945dbdf..a4ea72e 100644 --- a/src/cfunc.c +++ b/src/cfunc.c @@ -46,10 +46,11 @@ mrb_mruby_cfunc_gem_init(mrb_state* mrb) { struct RClass *ns = mrb_define_module(mrb, "CFunc"); struct cfunc_state *state = mrb_malloc(mrb, sizeof(struct cfunc_state)); + int ai; set_cfunc_state(mrb, ns, state); state->namespace = ns; - int ai = mrb_gc_arena_save(mrb); + ai = mrb_gc_arena_save(mrb); init_cfunc_type(mrb, ns); mrb_gc_arena_restore(mrb, ai); init_cfunc_pointer(mrb, ns); mrb_gc_arena_restore(mrb, ai); init_cfunc_struct(mrb, ns); mrb_gc_arena_restore(mrb, ai); diff --git a/src/cfunc_call.c b/src/cfunc_call.c index d625852..f022441 100644 --- a/src/cfunc_call.c +++ b/src/cfunc_call.c @@ -53,15 +53,21 @@ cfunc_call(mrb_state *mrb, mrb_value self) mrb_value mresult_type, mname, *margs; void **values = NULL; ffi_type **args = NULL; + void *fp = NULL; + mrb_sym sym_to_ffi_value; + int i; + mrb_value nil_ary[1]; + ffi_type *result_type; + mrb_value mresult = mrb_nil_value(); + ffi_cif cif; mrb_get_args(mrb, "oo*", &mresult_type, &mname, &margs, &margc); - void *fp = NULL; if(mrb_string_p(mname) || mrb_symbol_p(mname)) { #ifndef _WIN32 void *dlh = dlopen(NULL, RTLD_LAZY); fp = dlsym(dlh, mrb_string_value_ptr(mrb, mname)); - dlclose(dlh); + // dlclose(dlh); #else fp = get_proc_address(mrb_string_value_ptr(mrb, mname)); #endif @@ -81,11 +87,9 @@ cfunc_call(mrb_state *mrb, mrb_value self) args = mrb_malloc(mrb, sizeof(ffi_type*) * margc); values = mrb_malloc(mrb, sizeof(void*) * margc); - mrb_sym sym_to_ffi_value = mrb_intern_lit(mrb, "to_ffi_value"); + sym_to_ffi_value = mrb_intern_lit(mrb, "to_ffi_value"); - mrb_value nil_ary[1]; nil_ary[0] = mrb_nil_value(); - int i; for(i = 0; i < margc; ++i) { if(mrb_respond_to(mrb, margs[i], sym_to_ffi_value)) { args[i] = mrb_value_to_mrb_ffi_type(mrb, margs[i])->ffi_type_value; @@ -97,14 +101,12 @@ cfunc_call(mrb_state *mrb, mrb_value self) } } - ffi_type *result_type = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(mresult_type))->ffi_type_value; + result_type = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(mresult_type))->ffi_type_value; if (result_type == NULL) { cfunc_mrb_raise_without_jump(mrb, E_ARGUMENT_ERROR, "ignore return type %s", mrb_class_name(mrb, mrb_class_ptr(mresult_type))); goto cfunc_call_exit; } - mrb_value mresult = mrb_nil_value(); - ffi_cif cif; if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, margc, result_type, args) == FFI_OK) { void *result; if(result_type->size > sizeof(long)) { @@ -142,10 +144,16 @@ cfunc_libcall(mrb_state *mrb, mrb_value self) mrb_value mresult_type, mlib, mname, *margs; void **values = NULL; ffi_type **args = NULL; + void *fp = NULL; + mrb_sym sym_to_ffi_value; + mrb_value nil_ary[1]; + int i; + ffi_type *result_type; + mrb_value mresult = mrb_nil_value(); + ffi_cif cif; mrb_get_args(mrb, "oSo*", &mresult_type, &mlib, &mname, &margs, &margc); - void *fp = NULL; if((mrb_string_p(mname) || mrb_symbol_p(mname))) { void *dlh = dlopen(mrb_string_value_ptr(mrb, mlib), RTLD_LAZY); fp = dlsym(dlh, mrb_string_value_ptr(mrb, mname)); @@ -166,11 +174,9 @@ cfunc_libcall(mrb_state *mrb, mrb_value self) args = mrb_malloc(mrb, sizeof(ffi_type*) * margc); values = mrb_malloc(mrb, sizeof(void*) * margc); - mrb_sym sym_to_ffi_value = mrb_intern_lit(mrb, "to_ffi_value"); + sym_to_ffi_value = mrb_intern_lit(mrb, "to_ffi_value"); - mrb_value nil_ary[1]; nil_ary[0] = mrb_nil_value(); - int i; for(i = 0; i < margc; ++i) { if(mrb_respond_to(mrb, margs[i], sym_to_ffi_value)) { args[i] = mrb_value_to_mrb_ffi_type(mrb, margs[i])->ffi_type_value; @@ -182,14 +188,12 @@ cfunc_libcall(mrb_state *mrb, mrb_value self) } } - ffi_type *result_type = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(mresult_type))->ffi_type_value; + result_type = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(mresult_type))->ffi_type_value; if (result_type == NULL) { cfunc_mrb_raise_without_jump(mrb, E_ARGUMENT_ERROR, "ignore return type %s", mrb_class_name(mrb, mrb_class_ptr(mresult_type))); goto cfunc_call_exit; } - mrb_value mresult = mrb_nil_value(); - ffi_cif cif; if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, margc, result_type, args) == FFI_OK) { void *result; if(result_type->size > sizeof(long)) { diff --git a/src/cfunc_closure.c b/src/cfunc_closure.c index bf89c8d..3384c82 100644 --- a/src/cfunc_closure.c +++ b/src/cfunc_closure.c @@ -55,6 +55,10 @@ mrb_value cfunc_closure_initialize(mrb_state *mrb, mrb_value self) { struct cfunc_closure_data *data; + mrb_value rettype_mrb, block, args_mrb; + ffi_type *return_ffi_type; + int i; + void *closure_pointer = NULL; data = mrb_data_check_get_ptr(mrb, self, &cfunc_closure_data_type); if (!data) { data = mrb_malloc(mrb, sizeof(struct cfunc_closure_data)); @@ -69,16 +73,14 @@ cfunc_closure_initialize(mrb_state *mrb, mrb_value self) data->arg_types = NULL; data->packed_args_size = -1; - 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; + 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; @@ -86,7 +88,6 @@ cfunc_closure_initialize(mrb_state *mrb, mrb_value self) mrb_iv_set(mrb, self, mrb_intern_lit(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)); @@ -115,6 +116,9 @@ cfunc_closure_call_binding(ffi_cif *cif, void *ret, void **args, void *self_) mrb_value *ary = mrb_malloc(mrb, sizeof(mrb_value) * data->argc); int i; + void *packed_args; + mrb_value packed_args_value, block, result, ret_pointer; + void *p; if (data->packed_args_size == -1) { // calculate packed args size size_t result = 0; @@ -124,23 +128,24 @@ cfunc_closure_call_binding(ffi_cif *cif, void *ret, void **args, void *self_) } data->packed_args_size = result; } - void *packed_args = mrb_malloc(mrb, data->packed_args_size); - mrb_value packed_args_value = cfunc_pointer_new_with_pointer(mrb, packed_args, true); - void *p = packed_args; + packed_args = mrb_malloc(mrb, data->packed_args_size); + packed_args_value = cfunc_pointer_new_with_pointer(mrb, packed_args, true); + p = packed_args; for (i = 0; i < data->argc; ++i) { ffi_type const *t = data->arg_ffi_types[i]; + mrb_value pointer; memcpy(p, args[i], t->size); - mrb_value pointer = cfunc_pointer_new_with_pointer(mrb, p, false); + pointer = cfunc_pointer_new_with_pointer(mrb, p, false); mrb_iv_set(mrb, pointer, mrb_intern_lit(mrb, "parent_pointer"), packed_args_value); // for GC p = ((uint8_t*)p) + t->size + ((t->alignment - (t->size % t->alignment)) % t->alignment); ary[i] = mrb_funcall(mrb, data->arg_types[i], "refer", 1, pointer); } - mrb_value block = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@block")); - mrb_value result = mrb_funcall_argv(mrb, block, mrb_intern_lit(mrb, "call"), data->argc, ary); + block = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@block")); + result = mrb_funcall_argv(mrb, block, mrb_intern_lit(mrb, "call"), data->argc, ary); mrb_free(mrb, ary); - mrb_value ret_pointer = cfunc_pointer_new_with_pointer(mrb, ret, false); + ret_pointer = cfunc_pointer_new_with_pointer(mrb, ret, false); mrb_funcall(mrb, data->return_type, "set", 2, ret_pointer, result); mrb_gc_arena_restore(mrb, ai); @@ -197,9 +202,10 @@ init_cfunc_closure(mrb_state *mrb, struct RClass* module) { struct cfunc_state *state = cfunc_state(mrb, module); struct RClass *closure_class = mrb_define_class_under(mrb, module, "Closure", state->pointer_class); + mrb_value ffi_type; state->closure_class = closure_class; - mrb_value ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_closure_ffi_type_data_type, &closure_mrb_ffi_type)); + ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_closure_ffi_type_data_type, &closure_mrb_ffi_type)); mrb_obj_iv_set(mrb, (struct RObject*)closure_class, mrb_intern_lit(mrb, "@ffi_type"), ffi_type); mrb_define_method(mrb, closure_class, "initialize", cfunc_closure_initialize, MRB_ARGS_ANY()); diff --git a/src/cfunc_pointer.c b/src/cfunc_pointer.c index f6da2ee..2327a70 100644 --- a/src/cfunc_pointer.c +++ b/src/cfunc_pointer.c @@ -63,13 +63,14 @@ mrb_value cfunc_pointer_class_malloc(mrb_state *mrb, mrb_value klass) { struct cfunc_type_data *data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); + mrb_int alloc_size; data->refer = false; data->autofree = false; - mrb_int alloc_size; mrb_get_args(mrb, "i", &alloc_size); set_cfunc_pointer_data(data, mrb_malloc(mrb, alloc_size)); + data->autofree = true; return mrb_obj_value(Data_Wrap_Struct(mrb, mrb_class_ptr(klass), &cfunc_pointer_data_type, data)); } @@ -79,12 +80,13 @@ mrb_value cfunc_pointer_new_with_pointer(mrb_state *mrb, void *p, bool autofree) { struct cfunc_type_data *data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); + struct cfunc_state *state; data->refer = false; data->autofree = autofree; set_cfunc_pointer_data(data, p); - struct cfunc_state *state = cfunc_state(mrb, NULL); + state = cfunc_state(mrb, NULL); return mrb_obj_value(Data_Wrap_Struct(mrb, state->pointer_class, &cfunc_pointer_data_type, data)); } @@ -94,15 +96,16 @@ cfunc_pointer_refer(mrb_state *mrb, mrb_value klass) { struct RClass *c = mrb_class_ptr(klass); struct cfunc_type_data *data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); + mrb_value pointer; + struct RObject *obj; data->refer = true; data->autofree = false; - mrb_value pointer; mrb_get_args(mrb, "o", &pointer); data->value._pointer = cfunc_pointer_ptr(pointer); - struct RObject *obj = (struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_pointer_data_type, data); + obj = (struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_pointer_data_type, data); mrb_obj_iv_set(mrb, obj, mrb_intern_lit(mrb, "parent_pointer"), pointer); // keep for GC return mrb_obj_value(obj); } @@ -112,6 +115,8 @@ mrb_value cfunc_pointer_initialize(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data; + mrb_value ptr; + int argc; data = mrb_data_check_get_ptr(mrb, self, &cfunc_pointer_data_type); if(!data) { data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); @@ -121,8 +126,7 @@ cfunc_pointer_initialize(mrb_state *mrb, mrb_value self) data->refer = false; data->autofree = false; - mrb_value ptr; - int argc = mrb_get_args(mrb, "|o", &ptr); + argc = mrb_get_args(mrb, "|o", &ptr); if(argc == 0) { set_cfunc_pointer_data(data, NULL); } @@ -164,6 +168,7 @@ mrb_value cfunc_pointer_inspect(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data = DATA_PTR(self); + char cstr[256]; mrb_value type = mrb_funcall(mrb, mrb_obj_value(mrb_class(mrb, self)), "type", 0); const char* classname = mrb_class_name(mrb, mrb_class_ptr(type)); @@ -171,7 +176,6 @@ cfunc_pointer_inspect(mrb_state *mrb, mrb_value self) classname = "Unknown pointer"; } - char cstr[256]; snprintf(cstr, sizeof(cstr), "<%s pointer=%p>", classname, get_cfunc_pointer_data(data)); return mrb_str_new_cstr(mrb, cstr); @@ -227,6 +231,7 @@ cfunc_pointer_addr(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data = DATA_PTR(self); void *ptr = NULL; + mrb_value obj; if(data->refer) { ptr = data->value._pointer; } @@ -234,7 +239,7 @@ cfunc_pointer_addr(mrb_state *mrb, mrb_value self) ptr = &data->value._pointer; } - mrb_value obj = cfunc_pointer_new_with_pointer(mrb, ptr, false); + obj = cfunc_pointer_new_with_pointer(mrb, ptr, false); mrb_obj_iv_set(mrb, mrb_obj_ptr(obj), mrb_intern_lit(mrb, "parent_pointer"), self); // keep for GC return obj; } @@ -243,6 +248,7 @@ cfunc_pointer_addr(mrb_state *mrb, mrb_value self) static mrb_value cfunc_string_addr(mrb_state *mrb, mrb_value self) { + mrb_value ptr; // move string to heap mrb_str_modify(mrb, RSTRING(self)); if (RSTR_EMBED_P(RSTRING(self))) { @@ -252,7 +258,7 @@ cfunc_string_addr(mrb_state *mrb, mrb_value self) mrb_assert(!RSTR_EMBED_P(RSTRING(self))); } - mrb_value ptr = cfunc_pointer_new_with_pointer(mrb, &RSTRING(self)->as.heap.ptr, false); + ptr = cfunc_pointer_new_with_pointer(mrb, &RSTRING(self)->as.heap.ptr, false); mrb_obj_iv_set(mrb, mrb_obj_ptr(ptr), mrb_intern_lit(mrb, "parent_pointer"), self); // keep for GC return ptr; } diff --git a/src/cfunc_rubyvm.c b/src/cfunc_rubyvm.c index 7788bff..581fab7 100644 --- a/src/cfunc_rubyvm.c +++ b/src/cfunc_rubyvm.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -97,14 +98,12 @@ struct task_arg* mrb_value_to_task_arg(mrb_state *mrb, mrb_value v) case MRB_TT_ARRAY: { - struct RArray *ary = mrb_ary_ptr(v); - - arg->value.array.len = ary->len; - arg->value.array.ptr = mrb_malloc(mrb, ary->len * sizeof(struct task_arg)); - int i; - for(i=0; ilen; i++) { - arg->value.array.ptr[i] = mrb_value_to_task_arg(mrb, ary->ptr[i]); + arg->value.array.len = RARRAY_LEN(v); + arg->value.array.ptr = mrb_malloc(mrb, RARRAY_LEN(v) * sizeof(struct task_arg)); + + for(i=0; ivalue.array.ptr[i] = mrb_value_to_task_arg(mrb, RARRAY_PTR(v)[i]); } } break; @@ -145,12 +144,11 @@ mrb_value task_arg_to_mrb_value(mrb_state *mrb, struct task_arg* arg) case MRB_TT_ARRAY: { - v = mrb_ary_new_capa(mrb, arg->value.array.len); - struct RArray *ary = mrb_ary_ptr(v); - ary->len = arg->value.array.len; int i; + v = mrb_ary_new_capa(mrb, arg->value.array.len); + mrb_ary_resize(mrb, v, arg->value.array.len); for(i=0; ivalue.array.len; i++) { - ary->ptr[i] = task_arg_to_mrb_value(mrb, arg->value.array.ptr[i]); + RARRAY_PTR(v)[i] = task_arg_to_mrb_value(mrb, arg->value.array.ptr[i]); } } break; @@ -180,6 +178,7 @@ free_task_arg(mrb_state *mrb, struct task_arg* arg) int i; for(i=0; ivalue.array.len; i++) { free_task_arg(mrb, arg->value.array.ptr[i]); + mrb_free(mrb, arg->value.array.ptr[i]); } mrb_free(mrb, arg->value.array.ptr); } @@ -199,9 +198,13 @@ free_queue_task(mrb_state *mrb, struct queue_task* task) int i; for(i=0; iargs_len; ++i) { free_task_arg(mrb, task->args[i]); + mrb_free(mrb, task->args[i]); } mrb_free(mrb, task->args); + + free_task_arg(mrb, task->result); mrb_free(mrb, task->result); + mrb_free(mrb, task->name); mrb_free(mrb, task); } @@ -210,9 +213,22 @@ free_queue_task(mrb_state *mrb, struct queue_task* task) static void -cfunc_rubyvm_data_destructor(mrb_state *mrb, void *p_) +cfunc_rubyvm_data_destructor(mrb_state *mrb, void *p) { - // todo + struct cfunc_rubyvm_data *vm = (struct cfunc_rubyvm_data*)p; + pthread_cancel(vm->thread); + + while (vm->queue->length != 0) { + struct queue_task *task = vector_dequeue(vm->queue); + free_queue_task(mrb, task); + } + destroy_vector(vm->queue); + + mrb_close(vm->state); + + pthread_mutex_destroy(&vm->queue_mutex); + pthread_cond_destroy(&vm->queue_cond); + mrb_free(mrb, vm); } @@ -240,41 +256,49 @@ cfunc_rubyvm_open(void *args) { struct cfunc_rubyvm_data *data = args; mrb_state *mrb = mrb_open(); + mrb_irep* irep; data->state = mrb; #ifdef DISABLE_GEMS init_cfunc_module(mrb); #endif - mrb_irep* irep = mrb_read_irep(mrb, data->mrb_data); + irep = mrb_read_irep(mrb, data->mrb_data); mrb_run(mrb, mrb_proc_new(mrb, irep), mrb_top_self(mrb)); + mrb_irep_decref(mrb, irep); + if (mrb->exc) { return NULL; } while(true) { + struct queue_task *task; + mrb_sym taskname; + int args_len; + mrb_value *args; + int i; + mrb_value result; pthread_mutex_lock(&data->queue_mutex); while(data->queue->length == 0) { pthread_cond_wait(&data->queue_cond, &data->queue_mutex); } - struct queue_task *task = vector_dequeue(data->queue); + task = vector_dequeue(data->queue); task->status = queue_task_running; - mrb_sym taskname = mrb_intern_cstr(mrb, task->name); + taskname = mrb_intern_cstr(mrb, task->name); - int args_len = task->args_len; - mrb_value *args = mrb_malloc(mrb, sizeof(struct task_arg) * task->args_len); - int i; + args_len = task->args_len; + args = mrb_malloc(mrb, sizeof(struct task_arg) * task->args_len); for(i=0; iargs_len; ++i) { args[i] = task_arg_to_mrb_value(data->state, task->args[i]); } pthread_mutex_unlock(&data->queue_mutex); - mrb_value result = mrb_funcall_argv(mrb, mrb_top_self(data->state), taskname, args_len, args); + result = mrb_funcall_argv(mrb, mrb_top_self(data->state), taskname, args_len, args); task->result = mrb_value_to_task_arg(mrb, result); task->status = queue_task_finished; pthread_cond_signal(&task->sync_cond); @@ -294,9 +318,14 @@ cfunc_rubyvm_dispatch(mrb_state *mrb, mrb_value self) mrb_value name_obj, *args; mrb_int args_len; + struct queue_task *task; + const char* name; + int name_len; + int i; + struct cfunc_state *state; mrb_get_args(mrb, "o*", &name_obj, &args, &args_len); - struct queue_task *task = mrb_malloc(mrb, sizeof(struct queue_task)); + task = mrb_malloc(mrb, sizeof(struct queue_task)); task->refcount = 2; task->result = NULL; task->status = queue_task_queued; @@ -304,14 +333,13 @@ cfunc_rubyvm_dispatch(mrb_state *mrb, mrb_value self) pthread_mutex_init(&task->sync_mutex, NULL); pthread_cond_init(&task->sync_cond, NULL); - const char* name = mrb_string_value_ptr(mrb, name_obj); - int name_len = strlen(name); + name = mrb_str_to_cstr(mrb, mrb_str_to_str(mrb, name_obj)); + name_len = strlen(name); task->name = mrb_malloc(mrb, name_len+1); strncpy(task->name, name, name_len+1); task->args_len = args_len; task->args = mrb_malloc(mrb, sizeof(struct task_arg) * task->args_len); - int i; for(i=0; iargs[i] = mrb_value_to_task_arg(mrb, args[i]); } @@ -321,7 +349,7 @@ cfunc_rubyvm_dispatch(mrb_state *mrb, mrb_value self) pthread_cond_signal(&data->queue_cond); pthread_mutex_unlock(&data->queue_mutex); - struct cfunc_state *state = cfunc_state(mrb, mrb_obj_ptr(self)->c); + state = cfunc_state(mrb, mrb_obj_ptr(self)->c); return mrb_obj_value((struct RObject *)Data_Wrap_Struct(mrb, state->rubyvm_task_class, &cfunc_rubyvm_task_data_type, task)); } @@ -363,6 +391,7 @@ cfunc_rubyvm_class_thread(mrb_state *mrb, mrb_value klass) struct RClass *c = mrb_class_ptr(klass); struct cfunc_rubyvm_data *data = mrb_malloc(mrb, sizeof(struct cfunc_rubyvm_data)); mrb_value self = mrb_obj_value((struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_rubyvm_data_type, data)); + void *dlh; // load script mrb_value filename, str; @@ -370,7 +399,7 @@ cfunc_rubyvm_class_thread(mrb_state *mrb, mrb_value klass) str = mrb_str_new_lit(mrb, "mruby_data_"); mrb_str_concat(mrb, str, mrb_str_new(mrb, RSTRING_PTR(filename), RSTRING_LEN(filename))); - void *dlh = dlopen(NULL, RTLD_LAZY); + dlh = dlopen(NULL, RTLD_LAZY); data->mrb_data = (const uint8_t *)dlsym(dlh, RSTRING_PTR(str)); if (!data->mrb_data) { @@ -392,6 +421,7 @@ void init_cfunc_rubyvm(mrb_state *mrb, struct RClass* module) { struct cfunc_state *state = cfunc_state(mrb, module); + struct RClass *rubyvm_task_class; struct RClass *rubyvm_class = mrb_define_class_under(mrb, module, "RubyVM", mrb->object_class); state->rubyvm_class = rubyvm_class; @@ -400,7 +430,7 @@ init_cfunc_rubyvm(mrb_state *mrb, struct RClass* module) mrb_define_class_method(mrb, rubyvm_class, "thread", cfunc_rubyvm_class_thread, MRB_ARGS_REQ(1)); mrb_define_method(mrb, rubyvm_class, "dispatch", cfunc_rubyvm_dispatch, MRB_ARGS_ANY()); - struct RClass *rubyvm_task_class = mrb_define_class_under(mrb, rubyvm_class, "Task", mrb->object_class); + rubyvm_task_class = mrb_define_class_under(mrb, rubyvm_class, "Task", mrb->object_class); state->rubyvm_task_class = rubyvm_task_class; mrb_define_method(mrb, rubyvm_task_class, "wait", cfunc_rubyvm_task_wait, MRB_ARGS_NONE()); diff --git a/src/cfunc_struct.c b/src/cfunc_struct.c index 3f84bcc..ec170f7 100644 --- a/src/cfunc_struct.c +++ b/src/cfunc_struct.c @@ -20,9 +20,12 @@ #include static void -cfunc_struct_data_destructor(mrb_state *mrb, void *p_) +cfunc_struct_data_destructor(mrb_state *mrb, void *p) { - // todo + struct mrb_ffi_type *mft = (struct mrb_ffi_type*)p; + mrb_free(mrb, mft->ffi_type_value->elements); + mrb_free(mrb, mft->ffi_type_value); + mrb_free(mrb, p); } @@ -50,28 +53,31 @@ mrb_value cfunc_struct_define_struct(mrb_state *mrb, mrb_value klass) { mrb_value elements_mrb; + ffi_type *tm_type; + ffi_type **tm_type_elements; + int i; + struct mrb_ffi_type *mft; + mrb_value __ffi_type; mrb_get_args(mrb, "A", &elements_mrb); - struct RArray *elements = mrb_ary_ptr(elements_mrb); - ffi_type *tm_type = mrb_malloc(mrb, sizeof(ffi_type)); + tm_type = mrb_malloc(mrb, sizeof(ffi_type)); tm_type->type = FFI_TYPE_STRUCT; tm_type->size = tm_type->alignment = 0; - ffi_type **tm_type_elements = mrb_malloc(mrb, sizeof(ffi_type*) * (elements->len + 1)); - int i; - for(i = 0; i < elements->len; ++i) { - tm_type_elements[i] = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(elements->ptr[i]))->ffi_type_value; + tm_type_elements = mrb_malloc(mrb, sizeof(ffi_type*) * (RARRAY_LEN(elements_mrb) + 1)); + for(i = 0; i < RARRAY_LEN(elements_mrb); ++i) { + tm_type_elements[i] = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(RARRAY_PTR(elements_mrb)[i]))->ffi_type_value; } tm_type_elements[i] = NULL; tm_type->elements = tm_type_elements; - struct mrb_ffi_type *mft = mrb_malloc(mrb, sizeof(struct mrb_ffi_type)); + mft = mrb_malloc(mrb, sizeof(struct mrb_ffi_type)); mft->name = mrb_class_name(mrb, mrb_class_ptr(klass)); mft->ffi_type_value = tm_type; mft->mrb_to_c = &cfunc_type_ffi_struct_mrb_to_c; mft->c_to_mrb = &cfunc_type_ffi_struct_c_to_mrb; - mrb_value __ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_struct_data_type, mft)); + __ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_struct_data_type, mft)); mrb_obj_iv_set(mrb, (struct RObject*)(mrb_class_ptr(klass)), mrb_intern_lit(mrb, "@ffi_type"), __ffi_type); return mrb_nil_value(); diff --git a/src/cfunc_type.c b/src/cfunc_type.c index 971981c..34982c7 100644 --- a/src/cfunc_type.c +++ b/src/cfunc_type.c @@ -76,15 +76,16 @@ cfunc_type_class_refer(mrb_state *mrb, mrb_value klass) { struct RClass *c = mrb_class_ptr(klass); struct cfunc_type_data *data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); + mrb_value pointer; + struct RObject *obj; data->autofree = false; - mrb_value pointer; mrb_get_args(mrb, "o", &pointer); data->refer = true; data->value._pointer = cfunc_pointer_ptr(pointer); - struct RObject *obj = (struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_type_data, data); + obj = (struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_type_data, data); mrb_obj_iv_set(mrb, obj, mrb_intern_lit(mrb, "parent_pointer"), pointer); // keep for GC return mrb_obj_value(obj); } @@ -94,6 +95,8 @@ static mrb_value cfunc_type_initialize(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data; + mrb_value val; + int argc; data = mrb_data_check_get_ptr(mrb, self, &cfunc_type_data); if (!data) { data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); @@ -104,8 +107,7 @@ cfunc_type_initialize(mrb_state *mrb, mrb_value self) DATA_PTR(self) = data; DATA_TYPE(self) = &cfunc_type_data; - mrb_value val; - int argc = mrb_get_args(mrb, "|o", &val); + argc = mrb_get_args(mrb, "|o", &val); if(argc > 0) { struct mrb_ffi_type *mft = rclass_to_mrb_ffi_type(mrb, mrb_class(mrb, self)); if(mft && mft->mrb_to_data) { @@ -140,9 +142,10 @@ mrb_value cfunc_type_class_get(mrb_state *mrb, mrb_value klass) { mrb_value pointer; + struct mrb_ffi_type *mft; mrb_get_args(mrb, "o", &pointer); - struct mrb_ffi_type *mft = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(klass)); + mft = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(klass)); return mft->c_to_mrb(mrb, cfunc_pointer_ptr(pointer)); } @@ -151,9 +154,10 @@ mrb_value cfunc_type_class_set(mrb_state *mrb, mrb_value klass) { mrb_value pointer, val; + struct mrb_ffi_type *mft; mrb_get_args(mrb, "oo", &pointer, &val); - struct mrb_ffi_type *mft = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(klass)); + mft = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(klass)); mft->mrb_to_c(mrb, val, cfunc_pointer_ptr(pointer)); return val; @@ -173,10 +177,12 @@ mrb_value cfunc_type_set_value(mrb_state *mrb, mrb_value self) { mrb_value val; + struct cfunc_type_data *data; + struct mrb_ffi_type *mft; mrb_get_args(mrb, "o", &val); - struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); - struct mrb_ffi_type *mft = rclass_to_mrb_ffi_type(mrb, mrb_class(mrb, self)); + data = (struct cfunc_type_data*)DATA_PTR(self); + mft = rclass_to_mrb_ffi_type(mrb, mrb_class(mrb, self)); mft->mrb_to_data(mrb, val, data); return val; @@ -303,11 +309,12 @@ mrb_value cfunc_uint64_class_get(mrb_state *mrb, mrb_value klass) { mrb_value pointer; + uint64_t uint64; mrb_get_args(mrb, "o", &pointer); - uint64_t uint64 = *(uint64_t*)cfunc_pointer_ptr(pointer); + uint64 = *(uint64_t*)cfunc_pointer_ptr(pointer); - if(uint64 > UINT32_MAX) { + if(uint64 > MRB_INT_MAX) { mrb_raise(mrb, E_TYPE_ERROR, "too big. Use low, high"); } return int64_to_mrb(mrb, uint64); @@ -366,9 +373,10 @@ mrb_value cfunc_uint64_set_low(mrb_state *mrb, mrb_value self) { mrb_value val; + struct cfunc_type_data *data; mrb_get_args(mrb, "o", &val); - struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); + data = (struct cfunc_type_data*)DATA_PTR(self); data->value._uint64 = (data->value._uint64 & 0xffffffff00000000) | (((uint64_t)mrb_to_int64(mrb, val)) & 0xffffffff); return val; } @@ -386,9 +394,10 @@ mrb_value cfunc_uint64_set_high(mrb_state *mrb, mrb_value self) { mrb_value val; + struct cfunc_type_data *data; mrb_get_args(mrb, "o", &val); - struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); + data = (struct cfunc_type_data*)DATA_PTR(self); data->value._uint64 = (data->value._uint64 & 0x00000000ffffffff) | (((uint64_t)mrb_to_int64(mrb, val)) << 32); return val; @@ -412,11 +421,12 @@ mrb_value cfunc_sint64_class_get(mrb_state *mrb, mrb_value klass) { mrb_value pointer; + int64_t sint64; mrb_get_args(mrb, "o", &pointer); - int64_t sint64 = *(int64_t*)cfunc_pointer_ptr(pointer); + sint64 = *(int64_t*)cfunc_pointer_ptr(pointer); - if(sint64 > INT32_MAX || sint64 < INT32_MIN) { + if(sint64 > MRB_INT_MAX || sint64 < MRB_INT_MIN) { mrb_raise(mrb, E_TYPE_ERROR, "out of range. Use low, high"); } return int64_to_mrb(mrb, sint64); @@ -638,11 +648,14 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module) { struct cfunc_state *state = cfunc_state(mrb, module); struct RClass *type_class = mrb_define_class_under(mrb, module, "Type", mrb->object_class); + int ai, map_size, i; + mrb_value mod; + struct RClass *uint64_class, *sint64_class; MRB_SET_INSTANCE_TT(type_class, MRB_TT_DATA); state->type_class = type_class; set_cfunc_state(mrb, type_class, state); - int ai = mrb_gc_arena_save(mrb); + ai = mrb_gc_arena_save(mrb); mrb_define_class_method(mrb, type_class, "refer", cfunc_type_class_refer, MRB_ARGS_REQ(1)); mrb_define_class_method(mrb, type_class, "size", cfunc_type_size, MRB_ARGS_NONE()); mrb_define_class_method(mrb, type_class, "align", cfunc_type_align, MRB_ARGS_NONE()); @@ -656,8 +669,7 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module) mrb_define_method(mrb, type_class, "to_ffi_value", cfunc_type_addr, MRB_ARGS_NONE()); DONE; - int map_size = sizeof(types) / sizeof(struct mrb_ffi_type); - int i; + map_size = sizeof(types) / sizeof(struct mrb_ffi_type); for(i = 0; i < map_size; ++i) { struct RClass *new_class = mrb_define_class_under(mrb, module, types[i].name, type_class); mrb_value ffi_type = mrb_obj_value(Data_Wrap_Struct(mrb, mrb->object_class, &cfunc_class_ffi_data_type, &types[i])); @@ -665,7 +677,7 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module) } DONE; - mrb_value mod = mrb_obj_value(module); + mod = mrb_obj_value(module); state->void_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "Void"))); state->uint8_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "UInt8"))); state->sint8_class = mrb_class_ptr(mrb_const_get(mrb, mod, mrb_intern_lit(mrb, "SInt8"))); @@ -684,7 +696,7 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module) DONE; // uint64 specific - struct RClass *uint64_class = state->uint64_class; + uint64_class = state->uint64_class; mrb_define_class_method(mrb, uint64_class, "get", cfunc_uint64_class_get, MRB_ARGS_REQ(1)); mrb_define_method(mrb, uint64_class, "value", cfunc_uint64_get_value, MRB_ARGS_NONE()); mrb_define_method(mrb, uint64_class, "low", cfunc_uint64_get_low, MRB_ARGS_NONE()); @@ -696,7 +708,7 @@ void init_cfunc_type(mrb_state *mrb, struct RClass* module) DONE; // sint64 specific - struct RClass *sint64_class = state->sint64_class; + sint64_class = state->sint64_class; mrb_define_class_method(mrb, sint64_class, "get", cfunc_sint64_class_get, MRB_ARGS_REQ(1)); mrb_define_method(mrb, sint64_class, "value", cfunc_sint64_get_value, MRB_ARGS_NONE()); mrb_define_method(mrb, sint64_class, "low", cfunc_uint64_get_low, MRB_ARGS_NONE()); From 19faf9c4b812a807d08f54936b03c1be69512d43 Mon Sep 17 00:00:00 2001 From: Takeshi Watanabe Date: Sun, 25 Mar 2018 18:09:08 +0900 Subject: [PATCH 06/29] Remove unnecessary gems. --- run_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/run_test.rb b/run_test.rb index b5cfd02..9e9fafa 100644 --- a/run_test.rb +++ b/run_test.rb @@ -11,9 +11,9 @@ MRuby::Build.new do |conf| toolchain :gcc - conf.gembox 'default' + # conf.gembox 'default' - conf.gem "#{root}/mrbgems/mruby-eval" + # conf.gem "#{root}/mrbgems/mruby-eval" conf.gem File.expand_path(File.dirname(__FILE__)) do |g| # g.use_pkg_config From d6ef658eeb1cf38c0f975a068f133fa9825dc2f3 Mon Sep 17 00:00:00 2001 From: Takeshi Watanabe Date: Tue, 3 Apr 2018 16:40:28 +0900 Subject: [PATCH 07/29] Fix pthread_cancel error. --- src/cfunc_rubyvm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cfunc_rubyvm.c b/src/cfunc_rubyvm.c index 581fab7..365315b 100644 --- a/src/cfunc_rubyvm.c +++ b/src/cfunc_rubyvm.c @@ -216,6 +216,8 @@ static void cfunc_rubyvm_data_destructor(mrb_state *mrb, void *p) { struct cfunc_rubyvm_data *vm = (struct cfunc_rubyvm_data*)p; + if (!vm) { return; } + pthread_cancel(vm->thread); while (vm->queue->length != 0) { @@ -404,6 +406,8 @@ cfunc_rubyvm_class_thread(mrb_state *mrb, mrb_value klass) if (!data->mrb_data) { dlclose(dlh); + mrb_free(mrb, data); + DATA_PTR(self) = NULL; mrb_raisef(mrb, E_SCRIPT_ERROR, "file '%S' not found.", str); } From cd491a27e89fc14841f33e1e9f2e79bfa2a5f9a3 Mon Sep 17 00:00:00 2001 From: Takeshi Watanabe Date: Tue, 3 Apr 2018 16:55:09 +0900 Subject: [PATCH 08/29] Fix test build error. --- mrbgem.rake | 37 +++++++++++++++++++++---------------- test/func.c | 13 +++++++++++++ test/func.txt | 8 ++++++++ test/main.c | 6 ++++++ 4 files changed, 48 insertions(+), 16 deletions(-) create mode 100644 test/func.txt diff --git a/mrbgem.rake b/mrbgem.rake index 1828941..3019902 100644 --- a/mrbgem.rake +++ b/mrbgem.rake @@ -7,6 +7,27 @@ MRuby::Gem::Specification.new('mruby-cfunc') do |spec| add_test_dependency 'mruby-print', core: 'mruby-print' add_dependency 'mruby-enumerator', core: 'mruby-enumerator' + rubyvm1_rbx = "#{dir}/test/_rubyvm1.rbx" + rubyvm1_c = "#{build_dir}/test/_rubyvm1.c" + rubyvm1_o = rubyvm1_c.ext('o') + spec.test_objs << rubyvm1_o + spec.test_preload = "#{dir}/test/mobitest.rb" + + file rubyvm1_o => rubyvm1_c + file rubyvm1_c => rubyvm1_rbx do |t| + open(rubyvm1_c, 'w') do |f| + f.puts '#include ' + build.mrbc.run f, rubyvm1_rbx, 'mruby_data__rubyvm1' + end + end + + if spec.respond_to?(:search_package) && spec.search_package('libffi') + spec.linker.libraries << 'pthread' << 'dl' + spec.cc.flags << %w(-pthread) + spec.linker.flags << "-Wl,--export-dynamic,--dynamic-list=#{spec.dir}/test/func.txt" + next + end + def spec.use_pkg_config(pkg_config='pkg-config') self.linker.flags << `"#{pkg_config}" libffi --libs-only-L --libs-only-other`.chomp [self.cc, self.cxx, self.objc, self.mruby.cc, self.mruby.cxx, self.mruby.objc].each do |cc| @@ -14,8 +35,6 @@ MRuby::Gem::Specification.new('mruby-cfunc') do |spec| end end - spec.respond_to?(:search_package) && spec.search_package('libffi') - def spec.download_libffi(libffi_version = '3.0.13', tar = 'tar') libffi_url = "ftp://sourceware.org/pub/libffi/libffi-#{libffi_version}.tar.gz" libffi_build_root = "#{MRUBY_ROOT}/build/libffi/#{build.name}" @@ -60,19 +79,5 @@ MRuby::Gem::Specification.new('mruby-cfunc') do |spec| # spec.objs << ["#{LIBFFI_DIR}/lib/libffi.a"] # spec.test_rbfiles = Dir.glob("#{dir}/test/*.rb") # spec.test_objs = Dir.glob("#{dir}/test/*.{c,cpp,m,asm,S}").map { |f| f.relative_path_from(dir).pathmap("#{build_dir}/%X.o") } - spec.test_preload = "#{dir}/test/mobitest.rb" - - rubyvm1_rbx = "#{dir}/test/_rubyvm1.rbx" - rubyvm1_c = "#{build_dir}/test/_rubyvm1.c" - rubyvm1_o = rubyvm1_c.ext('o') - spec.test_objs << rubyvm1_o - - file rubyvm1_o => rubyvm1_c - file rubyvm1_c => rubyvm1_rbx do |t| - open(rubyvm1_c, 'w') do |f| - f.puts '#include ' - build.mrbc.run f, rubyvm1_rbx, 'mruby_data__rubyvm1' - end - end end diff --git a/test/func.c b/test/func.c index 586e5f2..dbf15fc 100644 --- a/test/func.c +++ b/test/func.c @@ -33,3 +33,16 @@ int cfunc_test_func4(int a, int b) { int check_offset5(uint8_t *p1, uint8_t *p2) { return (p1+5)==p2 ? 1 : 0; } + +static int test_func(uint32_t v1, uint32_t v2) { return v1 + v2; } + +void test_func_ref() { + struct STest v1; + struct STest2 v2; + cfunc_test_func1(v1); + cfunc_test_func2(v2); + cfunc_test_func3(test_func); + cfunc_test_func4(0, 1); + uint8_t a, b; + check_offset5(&a, &b); +} diff --git a/test/func.txt b/test/func.txt new file mode 100644 index 0000000..01f169b --- /dev/null +++ b/test/func.txt @@ -0,0 +1,8 @@ +{ + cfunc_test_func1; + cfunc_test_func2; + cfunc_test_func3; + cfunc_test_func4; + check_offset5; + mruby_data__rubyvm1; +}; diff --git a/test/main.c b/test/main.c index 40c4349..9e587d1 100644 --- a/test/main.c +++ b/test/main.c @@ -5,7 +5,13 @@ #include "mruby/proc.h" #include "mruby/compile.h" +extern void test_func_ref(); +extern uint8_t const mruby_data__rubyvm1[]; + void mrb_mruby_cfunc_gem_test(mrb_state *mrb) { + uint8_t const *ptr; + test_func_ref(); + ptr = mruby_data__rubyvm1; } From e1aa4653527021315b76a5eff3dda064c677edc7 Mon Sep 17 00:00:00 2001 From: Takeshi Watanabe Date: Tue, 3 Apr 2018 16:58:52 +0900 Subject: [PATCH 09/29] Fix compile error in 1.3. --- src/cfunc_rubyvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfunc_rubyvm.c b/src/cfunc_rubyvm.c index 365315b..ac5fb9f 100644 --- a/src/cfunc_rubyvm.c +++ b/src/cfunc_rubyvm.c @@ -148,7 +148,7 @@ mrb_value task_arg_to_mrb_value(mrb_state *mrb, struct task_arg* arg) v = mrb_ary_new_capa(mrb, arg->value.array.len); mrb_ary_resize(mrb, v, arg->value.array.len); for(i=0; ivalue.array.len; i++) { - RARRAY_PTR(v)[i] = task_arg_to_mrb_value(mrb, arg->value.array.ptr[i]); + mrb_ary_set(mrb, v, i, task_arg_to_mrb_value(mrb, arg->value.array.ptr[i])); } } break; From 5669496d1deecffa4de4394155df5d4b1dfed456 Mon Sep 17 00:00:00 2001 From: Takeshi Watanabe Date: Tue, 3 Apr 2018 17:02:54 +0900 Subject: [PATCH 10/29] Remove unnecessary include. --- test/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/main.c b/test/main.c index 9e587d1..4b1a348 100644 --- a/test/main.c +++ b/test/main.c @@ -1,5 +1,3 @@ -#include "cfunc.h" - #include "mruby.h" #include "mruby/dump.h" #include "mruby/proc.h" From 5e2516362f30d0454e4bbc4652a4390502081324 Mon Sep 17 00:00:00 2001 From: Takeshi Watanabe Date: Tue, 3 Apr 2018 18:20:25 +0900 Subject: [PATCH 11/29] Fix travis build. --- mrbgem.rake | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mrbgem.rake b/mrbgem.rake index 3019902..8ac85e0 100644 --- a/mrbgem.rake +++ b/mrbgem.rake @@ -21,13 +21,6 @@ MRuby::Gem::Specification.new('mruby-cfunc') do |spec| end end - if spec.respond_to?(:search_package) && spec.search_package('libffi') - spec.linker.libraries << 'pthread' << 'dl' - spec.cc.flags << %w(-pthread) - spec.linker.flags << "-Wl,--export-dynamic,--dynamic-list=#{spec.dir}/test/func.txt" - next - end - def spec.use_pkg_config(pkg_config='pkg-config') self.linker.flags << `"#{pkg_config}" libffi --libs-only-L --libs-only-other`.chomp [self.cc, self.cxx, self.objc, self.mruby.cc, self.mruby.cxx, self.mruby.objc].each do |cc| @@ -61,6 +54,13 @@ MRuby::Gem::Specification.new('mruby-cfunc') do |spec| end end + if spec.respond_to?(:search_package) && spec.search_package('libffi') + spec.linker.libraries << 'pthread' << 'dl' + spec.cc.flags << %w(-pthread) + spec.linker.flags << "-Wl,--export-dynamic,--dynamic-list=#{spec.dir}/test/func.txt" + next + end + spec.linker.libraries << %w(ffi dl pthread) if ENV['OS'] == 'Windows_NT' From e6e69c05653e60bce3f9e9db745baa1541309381 Mon Sep 17 00:00:00 2001 From: Takeshi Watanabe Date: Thu, 5 Apr 2018 16:27:42 +0900 Subject: [PATCH 12/29] Suppress warning. --- test/func.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/func.c b/test/func.c index dbf15fc..9b7fcf4 100644 --- a/test/func.c +++ b/test/func.c @@ -37,8 +37,8 @@ int check_offset5(uint8_t *p1, uint8_t *p2) { static int test_func(uint32_t v1, uint32_t v2) { return v1 + v2; } void test_func_ref() { - struct STest v1; - struct STest2 v2; + struct STest v1 = {0, 0, 0}; + struct STest2 v2 = { {}, 0.0 }; cfunc_test_func1(v1); cfunc_test_func2(v2); cfunc_test_func3(test_func); From 4be424c6291144941fd546a7e7425bb44e5deb1c Mon Sep 17 00:00:00 2001 From: Takeshi Watanabe Date: Mon, 23 Apr 2018 11:54:19 +0900 Subject: [PATCH 13/29] Fix zero division. --- test/func.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/func.c b/test/func.c index 9b7fcf4..ef6fa17 100644 --- a/test/func.c +++ b/test/func.c @@ -37,7 +37,7 @@ int check_offset5(uint8_t *p1, uint8_t *p2) { static int test_func(uint32_t v1, uint32_t v2) { return v1 + v2; } void test_func_ref() { - struct STest v1 = {0, 0, 0}; + struct STest v1 = {0, 0, 1}; struct STest2 v2 = { {}, 0.0 }; cfunc_test_func1(v1); cfunc_test_func2(v2); From cda0977dd9dc635b2aa09a663e3326f71bbec985 Mon Sep 17 00:00:00 2001 From: Takeshi Watanabe Date: Mon, 23 Apr 2018 12:02:24 +0900 Subject: [PATCH 14/29] Fix correct value. --- test/func.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/func.c b/test/func.c index ef6fa17..f40a6df 100644 --- a/test/func.c +++ b/test/func.c @@ -38,7 +38,7 @@ static int test_func(uint32_t v1, uint32_t v2) { return v1 + v2; } void test_func_ref() { struct STest v1 = {0, 0, 1}; - struct STest2 v2 = { {}, 0.0 }; + struct STest2 v2 = { {0, 0, 1}, 0.0 }; cfunc_test_func1(v1); cfunc_test_func2(v2); cfunc_test_func3(test_func); From a61df49d6c8552c05bd1daa0fdf97a927472c7e3 Mon Sep 17 00:00:00 2001 From: take-cheeze Date: Thu, 21 Jun 2018 10:55:17 +0900 Subject: [PATCH 15/29] Fix dependencies. --- mrbgem.rake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mrbgem.rake b/mrbgem.rake index 8ac85e0..ed4fe9f 100644 --- a/mrbgem.rake +++ b/mrbgem.rake @@ -14,7 +14,8 @@ MRuby::Gem::Specification.new('mruby-cfunc') do |spec| spec.test_preload = "#{dir}/test/mobitest.rb" file rubyvm1_o => rubyvm1_c - file rubyvm1_c => rubyvm1_rbx do |t| + file rubyvm1_c => [rubyvm1_rbx, build.mrbcfile] do |t| + FileUtils.mkdir_p File.dirname t.name open(rubyvm1_c, 'w') do |f| f.puts '#include ' build.mrbc.run f, rubyvm1_rbx, 'mruby_data__rubyvm1' From d35eda4ea94935c682d338700e76e4a950c5263a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 20 Nov 2018 21:53:17 +0900 Subject: [PATCH 16/29] Silence C++ warning in `test/main.c`. --- test/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/main.c b/test/main.c index 4b1a348..c91c85f 100644 --- a/test/main.c +++ b/test/main.c @@ -12,4 +12,5 @@ mrb_mruby_cfunc_gem_test(mrb_state *mrb) uint8_t const *ptr; test_func_ref(); ptr = mruby_data__rubyvm1; + (void)ptr; } From 014ed7c1f8321efabcab67556fc252e67d3fc554 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 20 Nov 2018 21:54:08 +0900 Subject: [PATCH 17/29] Change `vector_swap()` argument type from `int` to `size_t`. To avoid different sign compare warnings. --- include/vector.h | 2 +- src/vector.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/vector.h b/include/vector.h index a71134b..fcce06c 100644 --- a/include/vector.h +++ b/include/vector.h @@ -101,7 +101,7 @@ void check_length(vector_p vec); /* Destroy the vector and free all the memory associated with it. */ void destroy_vector(vector_p vec); /* Swaps the pointers at indices i and j in the vector */ -void vector_swap(vector_p vec, int i, int j); +void vector_swap(vector_p vec, size_t i, size_t j); void vector_enqueue(vector_p vec, void* data); diff --git a/src/vector.c b/src/vector.c index 08c75b1..064290c 100644 --- a/src/vector.c +++ b/src/vector.c @@ -146,7 +146,7 @@ void destroy_vector(vector_p vec){ } -void vector_swap(vector_p vec, int i, int j){ +void vector_swap(vector_p vec, size_t i, size_t j){ void * temp; if(i >= vec->length || j >= vec->length) From 1fbc550377a876b04b8fea39887b6541e23f7f0c Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 20 Nov 2018 21:56:34 +0900 Subject: [PATCH 18/29] Avoid `namespace` C++ keyword from the source. --- include/cfunc.h | 2 +- src/cfunc.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/cfunc.h b/include/cfunc.h index f3994ac..4886a8c 100644 --- a/include/cfunc.h +++ b/include/cfunc.h @@ -33,7 +33,7 @@ #include "mruby/value.h" struct cfunc_state { - struct RClass *namespace; + struct RClass *ns; struct RClass *type_class; struct RClass *void_class; diff --git a/src/cfunc.c b/src/cfunc.c index a4ea72e..3d3671f 100644 --- a/src/cfunc.c +++ b/src/cfunc.c @@ -45,19 +45,19 @@ void mrb_mruby_cfunc_gem_init(mrb_state* mrb) { struct RClass *ns = mrb_define_module(mrb, "CFunc"); - struct cfunc_state *state = mrb_malloc(mrb, sizeof(struct cfunc_state)); + struct cfunc_state *state = (struct cfunc_state*)mrb_malloc(mrb, sizeof(struct cfunc_state)); int ai; set_cfunc_state(mrb, ns, state); - state->namespace = ns; + state->ns = ns; - ai = mrb_gc_arena_save(mrb); + ai = mrb_gc_arena_save(mrb); init_cfunc_type(mrb, ns); mrb_gc_arena_restore(mrb, ai); init_cfunc_pointer(mrb, ns); mrb_gc_arena_restore(mrb, ai); init_cfunc_struct(mrb, ns); mrb_gc_arena_restore(mrb, ai); init_cfunc_closure(mrb, ns); mrb_gc_arena_restore(mrb, ai); init_cfunc_call(mrb, ns); mrb_gc_arena_restore(mrb, ai); init_cfunc_rubyvm(mrb, ns); mrb_gc_arena_restore(mrb, ai); - init_cfunc_platform(mrb, ns); mrb_gc_arena_restore(mrb, ai); + init_cfunc_platform(mrb, ns); mrb_gc_arena_restore(mrb, ai); mrb_define_class_method(mrb, ns, "mrb_state", cfunc_mrb_state, MRB_ARGS_NONE()); mrb_define_class_method(mrb, ns, "errno", cfunc_errno, MRB_ARGS_NONE()); From 71e3f0778722f369af4548022204bb1d49f383eb Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 20 Nov 2018 21:57:46 +0900 Subject: [PATCH 19/29] Separate `mrb_string_p` and `mrb_symbol_p`. Since `mrb_string_value_ptr()` no longer convert symbols to strings automatically from mruby 2.0 and later. --- src/cfunc_call.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/cfunc_call.c b/src/cfunc_call.c index f022441..3020b9e 100644 --- a/src/cfunc_call.c +++ b/src/cfunc_call.c @@ -63,7 +63,10 @@ cfunc_call(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "oo*", &mresult_type, &mname, &margs, &margc); - if(mrb_string_p(mname) || mrb_symbol_p(mname)) { + if (mrb_symbol_p(mname)) { + mname = mrb_str_to_str(mrb, mname); + } + if(mrb_string_p(mname)) { #ifndef _WIN32 void *dlh = dlopen(NULL, RTLD_LAZY); fp = dlsym(dlh, mrb_string_value_ptr(mrb, mname)); @@ -154,7 +157,10 @@ cfunc_libcall(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "oSo*", &mresult_type, &mlib, &mname, &margs, &margc); - if((mrb_string_p(mname) || mrb_symbol_p(mname))) { + if (mrb_symbol_p(mname)) { + mname = mrb_str_to_str(mrb, mname); + } + if(mrb_string_p(mname)) { void *dlh = dlopen(mrb_string_value_ptr(mrb, mlib), RTLD_LAZY); fp = dlsym(dlh, mrb_string_value_ptr(mrb, mname)); dlclose(dlh); From 63dec3058172c629ec47142b18caf9961b083c25 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 20 Nov 2018 22:02:14 +0900 Subject: [PATCH 20/29] Add type cast to the assignment from `void*`. C++ requires explicit cast from `void*`. --- src/cfunc_call.c | 14 +++++++------- src/cfunc_closure.c | 20 +++++++++++--------- src/cfunc_pointer.c | 29 ++++++++++++++++------------- src/cfunc_rubyvm.c | 26 +++++++++++++------------- src/cfunc_struct.c | 6 +++--- src/cfunc_type.c | 6 +++--- 6 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/cfunc_call.c b/src/cfunc_call.c index 3020b9e..b6ba4a0 100644 --- a/src/cfunc_call.c +++ b/src/cfunc_call.c @@ -88,8 +88,8 @@ cfunc_call(mrb_state *mrb, mrb_value self) } } - args = mrb_malloc(mrb, sizeof(ffi_type*) * margc); - values = mrb_malloc(mrb, sizeof(void*) * margc); + args = (ffi_type**)mrb_malloc(mrb, sizeof(ffi_type*) * margc); + values = (void**)mrb_malloc(mrb, sizeof(void*) * margc); sym_to_ffi_value = mrb_intern_lit(mrb, "to_ffi_value"); nil_ary[0] = mrb_nil_value(); @@ -121,8 +121,8 @@ cfunc_call(mrb_state *mrb, mrb_value self) else { result = NULL; } - ffi_call(&cif, fp, result, values); - + ffi_call(&cif, (void(*)())fp, result, values); + if(result) { mrb_value result_ptr = cfunc_pointer_new_with_pointer(mrb, result, true); mresult = mrb_funcall(mrb, mresult_type, "refer", 1, result_ptr); @@ -178,8 +178,8 @@ cfunc_libcall(mrb_state *mrb, mrb_value self) } } - args = mrb_malloc(mrb, sizeof(ffi_type*) * margc); - values = mrb_malloc(mrb, sizeof(void*) * margc); + args = (ffi_type**)mrb_malloc(mrb, sizeof(ffi_type*) * margc); + values = (void**)mrb_malloc(mrb, sizeof(void*) * margc); sym_to_ffi_value = mrb_intern_lit(mrb, "to_ffi_value"); nil_ary[0] = mrb_nil_value(); @@ -211,7 +211,7 @@ cfunc_libcall(mrb_state *mrb, mrb_value self) else { result = NULL; } - ffi_call(&cif, fp, result, values); + ffi_call(&cif, (void(*)())fp, result, values); if(result) { mrb_value result_ptr = cfunc_pointer_new_with_pointer(mrb, result, true); diff --git a/src/cfunc_closure.c b/src/cfunc_closure.c index 3384c82..a4ff4b0 100644 --- a/src/cfunc_closure.c +++ b/src/cfunc_closure.c @@ -25,7 +25,8 @@ static void cfunc_closure_destructor(mrb_state *mrb, void *p_) { - struct cfunc_closure_data *p = p_; + struct cfunc_closure_data *p = (struct cfunc_closure_data*)p_; + if (p->closure) { ffi_closure_free(p->closure); } @@ -59,9 +60,10 @@ cfunc_closure_initialize(mrb_state *mrb, mrb_value self) ffi_type *return_ffi_type; int i; void *closure_pointer = NULL; - data = mrb_data_check_get_ptr(mrb, self, &cfunc_closure_data_type); + + data = (struct cfunc_closure_data*)mrb_data_check_get_ptr(mrb, self, &cfunc_closure_data_type); if (!data) { - data = mrb_malloc(mrb, sizeof(struct cfunc_closure_data)); + data = (struct cfunc_closure_data*)mrb_malloc(mrb, sizeof(struct cfunc_closure_data)); } data->refer = 0; data->autofree = 0; @@ -79,8 +81,8 @@ cfunc_closure_initialize(mrb_state *mrb, mrb_value self) 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); + data->arg_ffi_types = (ffi_type**)mrb_malloc(mrb, sizeof(ffi_type*) * data->argc); + data->arg_types = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * data->argc); 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; @@ -88,8 +90,8 @@ cfunc_closure_initialize(mrb_state *mrb, mrb_value self) mrb_iv_set(mrb, self, mrb_intern_lit(data->mrb, "@block"), block); - data->closure = ffi_closure_alloc(sizeof(ffi_closure) + sizeof(void*), &closure_pointer); - data->cif = mrb_malloc(mrb, sizeof(ffi_cif)); + data->closure = (ffi_closure*)ffi_closure_alloc(sizeof(ffi_closure) + sizeof(void*), &closure_pointer); + data->cif = (ffi_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) { @@ -109,12 +111,12 @@ void cfunc_closure_call_binding(ffi_cif *cif, void *ret, void **args, void *self_) { mrb_value self = mrb_obj_value(self_); - struct cfunc_closure_data *data = DATA_PTR(self); + struct cfunc_closure_data *data = (struct cfunc_closure_data*)DATA_PTR(self); mrb_state *mrb = data->mrb; int ai = mrb_gc_arena_save(mrb); - mrb_value *ary = mrb_malloc(mrb, sizeof(mrb_value) * data->argc); + mrb_value *ary = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * data->argc); int i; void *packed_args; mrb_value packed_args_value, block, result, ret_pointer; diff --git a/src/cfunc_pointer.c b/src/cfunc_pointer.c index 2327a70..77d7926 100644 --- a/src/cfunc_pointer.c +++ b/src/cfunc_pointer.c @@ -62,7 +62,7 @@ void set_cfunc_pointer_data(struct cfunc_type_data *data, void *p) mrb_value cfunc_pointer_class_malloc(mrb_state *mrb, mrb_value klass) { - struct cfunc_type_data *data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); + struct cfunc_type_data *data = (struct cfunc_type_data*)mrb_malloc(mrb, sizeof(struct cfunc_type_data)); mrb_int alloc_size; data->refer = false; data->autofree = false; @@ -79,7 +79,7 @@ cfunc_pointer_class_malloc(mrb_state *mrb, mrb_value klass) mrb_value cfunc_pointer_new_with_pointer(mrb_state *mrb, void *p, bool autofree) { - struct cfunc_type_data *data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); + struct cfunc_type_data *data = (struct cfunc_type_data*)mrb_malloc(mrb, sizeof(struct cfunc_type_data)); struct cfunc_state *state; data->refer = false; data->autofree = autofree; @@ -95,7 +95,7 @@ mrb_value cfunc_pointer_refer(mrb_state *mrb, mrb_value klass) { struct RClass *c = mrb_class_ptr(klass); - struct cfunc_type_data *data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); + struct cfunc_type_data *data = (struct cfunc_type_data*)mrb_malloc(mrb, sizeof(struct cfunc_type_data)); mrb_value pointer; struct RObject *obj; data->refer = true; @@ -117,9 +117,10 @@ cfunc_pointer_initialize(mrb_state *mrb, mrb_value self) struct cfunc_type_data *data; mrb_value ptr; int argc; - data = mrb_data_check_get_ptr(mrb, self, &cfunc_pointer_data_type); + + data = (struct cfunc_type_data*)mrb_data_check_get_ptr(mrb, self, &cfunc_pointer_data_type); if(!data) { - data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); + data = (struct cfunc_type_data*)mrb_malloc(mrb, sizeof(struct cfunc_type_data)); DATA_PTR(self) = data; DATA_TYPE(self) = &cfunc_pointer_data_type; } @@ -141,7 +142,7 @@ cfunc_pointer_initialize(mrb_state *mrb, mrb_value self) mrb_value cfunc_pointer_realloc(mrb_state *mrb, mrb_value self) { - struct cfunc_type_data *data = DATA_PTR(self); + struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); mrb_int alloc_size; mrb_get_args(mrb, "i", &alloc_size); @@ -154,7 +155,7 @@ cfunc_pointer_realloc(mrb_state *mrb, mrb_value self) mrb_value cfunc_pointer_free(mrb_state *mrb, mrb_value self) { - struct cfunc_type_data *data = DATA_PTR(self); + struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); mrb_free(mrb, get_cfunc_pointer_data(data)); data->autofree = false; @@ -167,7 +168,7 @@ cfunc_pointer_free(mrb_state *mrb, mrb_value self) mrb_value cfunc_pointer_inspect(mrb_state *mrb, mrb_value self) { - struct cfunc_type_data *data = DATA_PTR(self); + struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); char cstr[256]; mrb_value type = mrb_funcall(mrb, mrb_obj_value(mrb_class(mrb, self)), "type", 0); @@ -185,7 +186,7 @@ cfunc_pointer_inspect(mrb_state *mrb, mrb_value self) mrb_value cfunc_pointer_is_null(mrb_state *mrb, mrb_value self) { - struct cfunc_type_data *data = DATA_PTR(self); + struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); return (get_cfunc_pointer_data(data) == NULL) ? mrb_true_value() : mrb_false_value(); } @@ -193,7 +194,7 @@ cfunc_pointer_is_null(mrb_state *mrb, mrb_value self) mrb_value cfunc_pointer_autofree(mrb_state *mrb, mrb_value self) { - struct cfunc_type_data *data = DATA_PTR(self); + struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); data->autofree = true; return self; } @@ -202,7 +203,7 @@ cfunc_pointer_autofree(mrb_state *mrb, mrb_value self) mrb_value cfunc_pointer_to_s(mrb_state *mrb, mrb_value self) { - struct cfunc_type_data *data = DATA_PTR(self); + struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); const char* p = (const char*)get_cfunc_pointer_data(data); return mrb_str_new_cstr(mrb, p); } @@ -211,8 +212,9 @@ cfunc_pointer_to_s(mrb_state *mrb, mrb_value self) mrb_value cfunc_pointer_offset(mrb_state *mrb, mrb_value self) { - struct cfunc_type_data *data = DATA_PTR(self); + struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); mrb_int offset; + mrb_get_args(mrb, "i", &offset); if(offset == 0) { @@ -229,9 +231,10 @@ cfunc_pointer_offset(mrb_state *mrb, mrb_value self) mrb_value cfunc_pointer_addr(mrb_state *mrb, mrb_value self) { - struct cfunc_type_data *data = DATA_PTR(self); + struct cfunc_type_data *data = (struct cfunc_type_data*)DATA_PTR(self); void *ptr = NULL; mrb_value obj; + if(data->refer) { ptr = data->value._pointer; } diff --git a/src/cfunc_rubyvm.c b/src/cfunc_rubyvm.c index ac5fb9f..2c38a81 100644 --- a/src/cfunc_rubyvm.c +++ b/src/cfunc_rubyvm.c @@ -64,7 +64,7 @@ struct queue_task { struct task_arg* mrb_value_to_task_arg(mrb_state *mrb, mrb_value v) { - struct task_arg *arg = mrb_malloc(mrb, sizeof(struct task_arg)); + struct task_arg *arg = (struct task_arg*)mrb_malloc(mrb, sizeof(struct task_arg)); arg->tt = mrb_type(v); switch (mrb_type(v)) { @@ -83,7 +83,7 @@ struct task_arg* mrb_value_to_task_arg(mrb_state *mrb, mrb_value v) mrb_int len; const char* name = mrb_sym2name_len(mrb, v.value.sym, &len); arg->value.string.len = len; - arg->value.string.ptr = mrb_malloc(mrb, len + 1); + arg->value.string.ptr = (char*)mrb_malloc(mrb, len + 1); memcpy(arg->value.string.ptr, name, len + 1); } break; @@ -91,7 +91,7 @@ struct task_arg* mrb_value_to_task_arg(mrb_state *mrb, mrb_value v) case MRB_TT_STRING: { arg->value.string.len = RSTRING_LEN(v); - arg->value.string.ptr = mrb_malloc(mrb, arg->value.string.len+1); + arg->value.string.ptr = (char*)mrb_malloc(mrb, arg->value.string.len+1); memcpy(arg->value.string.ptr, RSTRING_PTR(v), arg->value.string.len+1); } break; @@ -221,7 +221,7 @@ cfunc_rubyvm_data_destructor(mrb_state *mrb, void *p) pthread_cancel(vm->thread); while (vm->queue->length != 0) { - struct queue_task *task = vector_dequeue(vm->queue); + struct queue_task *task = (struct queue_task*)vector_dequeue(vm->queue); free_queue_task(mrb, task); } destroy_vector(vm->queue); @@ -256,7 +256,7 @@ const struct mrb_data_type cfunc_rubyvm_task_data_type = { void* cfunc_rubyvm_open(void *args) { - struct cfunc_rubyvm_data *data = args; + struct cfunc_rubyvm_data *data = (struct cfunc_rubyvm_data*)args; mrb_state *mrb = mrb_open(); mrb_irep* irep; data->state = mrb; @@ -288,7 +288,7 @@ cfunc_rubyvm_open(void *args) pthread_cond_wait(&data->queue_cond, &data->queue_mutex); } - task = vector_dequeue(data->queue); + task = (struct queue_task*)vector_dequeue(data->queue); task->status = queue_task_running; taskname = mrb_intern_cstr(mrb, task->name); @@ -316,7 +316,7 @@ cfunc_rubyvm_open(void *args) mrb_value cfunc_rubyvm_dispatch(mrb_state *mrb, mrb_value self) { - struct cfunc_rubyvm_data *data = mrb_data_check_get_ptr(mrb, self, &cfunc_rubyvm_data_type); + struct cfunc_rubyvm_data *data = (struct cfunc_rubyvm_data*)mrb_data_check_get_ptr(mrb, self, &cfunc_rubyvm_data_type); mrb_value name_obj, *args; mrb_int args_len; @@ -327,7 +327,7 @@ cfunc_rubyvm_dispatch(mrb_state *mrb, mrb_value self) struct cfunc_state *state; mrb_get_args(mrb, "o*", &name_obj, &args, &args_len); - task = mrb_malloc(mrb, sizeof(struct queue_task)); + task = (struct queue_task*)mrb_malloc(mrb, sizeof(struct queue_task)); task->refcount = 2; task->result = NULL; task->status = queue_task_queued; @@ -337,7 +337,7 @@ cfunc_rubyvm_dispatch(mrb_state *mrb, mrb_value self) name = mrb_str_to_cstr(mrb, mrb_str_to_str(mrb, name_obj)); name_len = strlen(name); - task->name = mrb_malloc(mrb, name_len+1); + task->name = (char*)mrb_malloc(mrb, name_len+1); strncpy(task->name, name, name_len+1); task->args_len = args_len; @@ -359,7 +359,7 @@ cfunc_rubyvm_dispatch(mrb_state *mrb, mrb_value self) mrb_value cfunc_rubyvm_task_status(mrb_state *mrb, mrb_value self) { - struct queue_task *task = DATA_PTR(self); + struct queue_task *task = (struct queue_task*)DATA_PTR(self); return mrb_fixnum_value(task->status); } @@ -367,7 +367,7 @@ cfunc_rubyvm_task_status(mrb_state *mrb, mrb_value self) mrb_value cfunc_rubyvm_task_result(mrb_state *mrb, mrb_value self) { - struct queue_task *task = DATA_PTR(self); + struct queue_task *task = (struct queue_task*)DATA_PTR(self); return task_arg_to_mrb_value(mrb, task->result); } @@ -375,7 +375,7 @@ cfunc_rubyvm_task_result(mrb_state *mrb, mrb_value self) mrb_value cfunc_rubyvm_task_wait(mrb_state *mrb, mrb_value self) { - struct queue_task *task = DATA_PTR(self); + struct queue_task *task = (struct queue_task*)DATA_PTR(self); if(task->status == queue_task_queued || task->status == queue_task_running) { pthread_mutex_lock(&task->sync_mutex); pthread_cond_wait(&task->sync_cond, &task->sync_mutex); @@ -391,7 +391,7 @@ cfunc_rubyvm_class_thread(mrb_state *mrb, mrb_value klass) { // init bindle data with RubyVM object struct RClass *c = mrb_class_ptr(klass); - struct cfunc_rubyvm_data *data = mrb_malloc(mrb, sizeof(struct cfunc_rubyvm_data)); + struct cfunc_rubyvm_data *data = (struct cfunc_rubyvm_data*)mrb_malloc(mrb, sizeof(struct cfunc_rubyvm_data)); mrb_value self = mrb_obj_value((struct RObject *)Data_Wrap_Struct(mrb, c, &cfunc_rubyvm_data_type, data)); void *dlh; diff --git a/src/cfunc_struct.c b/src/cfunc_struct.c index ec170f7..a9f8491 100644 --- a/src/cfunc_struct.c +++ b/src/cfunc_struct.c @@ -60,18 +60,18 @@ cfunc_struct_define_struct(mrb_state *mrb, mrb_value klass) mrb_value __ffi_type; mrb_get_args(mrb, "A", &elements_mrb); - tm_type = mrb_malloc(mrb, sizeof(ffi_type)); + tm_type = (ffi_type*)mrb_malloc(mrb, sizeof(ffi_type)); tm_type->type = FFI_TYPE_STRUCT; tm_type->size = tm_type->alignment = 0; - tm_type_elements = mrb_malloc(mrb, sizeof(ffi_type*) * (RARRAY_LEN(elements_mrb) + 1)); + tm_type_elements = (ffi_type**)mrb_malloc(mrb, sizeof(ffi_type*) * (RARRAY_LEN(elements_mrb) + 1)); for(i = 0; i < RARRAY_LEN(elements_mrb); ++i) { tm_type_elements[i] = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(RARRAY_PTR(elements_mrb)[i]))->ffi_type_value; } tm_type_elements[i] = NULL; tm_type->elements = tm_type_elements; - mft = mrb_malloc(mrb, sizeof(struct mrb_ffi_type)); + mft = (struct mrb_ffi_type*)mrb_malloc(mrb, sizeof(struct mrb_ffi_type)); mft->name = mrb_class_name(mrb, mrb_class_ptr(klass)); mft->ffi_type_value = tm_type; mft->mrb_to_c = &cfunc_type_ffi_struct_mrb_to_c; diff --git a/src/cfunc_type.c b/src/cfunc_type.c index 34982c7..52d57ff 100644 --- a/src/cfunc_type.c +++ b/src/cfunc_type.c @@ -75,7 +75,7 @@ static mrb_value cfunc_type_class_refer(mrb_state *mrb, mrb_value klass) { struct RClass *c = mrb_class_ptr(klass); - struct cfunc_type_data *data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); + struct cfunc_type_data *data = (struct cfunc_type_data*)mrb_malloc(mrb, sizeof(struct cfunc_type_data)); mrb_value pointer; struct RObject *obj; data->autofree = false; @@ -97,9 +97,9 @@ cfunc_type_initialize(mrb_state *mrb, mrb_value self) struct cfunc_type_data *data; mrb_value val; int argc; - data = mrb_data_check_get_ptr(mrb, self, &cfunc_type_data); + data = (struct cfunc_type_data*)mrb_data_check_get_ptr(mrb, self, &cfunc_type_data); if (!data) { - data = mrb_malloc(mrb, sizeof(struct cfunc_type_data)); + data = (struct cfunc_type_data*)mrb_malloc(mrb, sizeof(struct cfunc_type_data)); data->value._uint64 = 0; } data->autofree = false; From 4ddf9a6a9cc6b53a96f685d9b6edf4008e0f4123 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 20 Nov 2018 22:03:16 +0900 Subject: [PATCH 21/29] Reorder struct member initialization in declaration order of members. --- src/cfunc_closure.c | 6 +++--- src/cfunc_pointer.c | 6 +++--- src/cfunc_type.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cfunc_closure.c b/src/cfunc_closure.c index a4ff4b0..8c81a6b 100644 --- a/src/cfunc_closure.c +++ b/src/cfunc_closure.c @@ -192,10 +192,10 @@ cfunc_closure_mrb_to_data(mrb_state *mrb, mrb_value val, struct cfunc_type_data static struct mrb_ffi_type closure_mrb_ffi_type = { .name = "Closure", .ffi_type_value = &ffi_type_pointer, - .mrb_to_c = &cfunc_closure_mrb_to_c, - .c_to_mrb = &cfunc_closure_c_to_mrb, + .data_to_mrb = &cfunc_closure_data_to_mrb, .mrb_to_data = &cfunc_closure_mrb_to_data, - .data_to_mrb = &cfunc_closure_data_to_mrb + .c_to_mrb = &cfunc_closure_c_to_mrb, + .mrb_to_c = &cfunc_closure_mrb_to_c }; diff --git a/src/cfunc_pointer.c b/src/cfunc_pointer.c index 77d7926..b61545f 100644 --- a/src/cfunc_pointer.c +++ b/src/cfunc_pointer.c @@ -315,10 +315,10 @@ const struct mrb_data_type cfunc_pointer_ffi_data_type = { static struct mrb_ffi_type pointer_mrb_ffi_type = { .name = "Pointer", .ffi_type_value = &ffi_type_pointer, - .mrb_to_c = &cfunc_pointer_mrb_to_c, - .c_to_mrb = &cfunc_pointer_c_to_mrb, + .data_to_mrb = &cfunc_pointer_data_to_mrb, .mrb_to_data = &cfunc_pointer_mrb_to_data, - .data_to_mrb = &cfunc_pointer_data_to_mrb + .c_to_mrb = &cfunc_pointer_c_to_mrb, + .mrb_to_c = &cfunc_pointer_mrb_to_c }; diff --git a/src/cfunc_type.c b/src/cfunc_type.c index 52d57ff..c6cf3d6 100644 --- a/src/cfunc_type.c +++ b/src/cfunc_type.c @@ -598,10 +598,10 @@ cfunc_type_ffi_##name##_mrb_to_data(mrb_state *mrb, mrb_value val, struct cfunc_ { \ .name = #name_, \ .ffi_type_value = &ffi_type_##type_, \ - .mrb_to_c = &cfunc_type_ffi_##type_##_mrb_to_c, \ - .c_to_mrb = &cfunc_type_ffi_##type_##_c_to_mrb, \ + .data_to_mrb = &cfunc_type_ffi_##type_##_data_to_mrb, \ .mrb_to_data = &cfunc_type_ffi_##type_##_mrb_to_data, \ - .data_to_mrb = &cfunc_type_ffi_##type_##_data_to_mrb \ + .c_to_mrb = &cfunc_type_ffi_##type_##_c_to_mrb, \ + .mrb_to_c = &cfunc_type_ffi_##type_##_mrb_to_c \ } define_cfunc_type(sint8, &ffi_type_sint8, int8_t, int64_to_mrb, mrb_to_int64) From e6d6ce5bc0e4c12c403c791199f442915996e017 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 20 Nov 2018 22:04:08 +0900 Subject: [PATCH 22/29] `enum` should be declared outside of `struct` definition. Otherwise `enum` become private to the struct scope in C++. --- src/cfunc_rubyvm.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cfunc_rubyvm.c b/src/cfunc_rubyvm.c index 2c38a81..234e8a2 100644 --- a/src/cfunc_rubyvm.c +++ b/src/cfunc_rubyvm.c @@ -41,13 +41,15 @@ struct task_arg { }; +enum queue_task_status { + queue_task_queued, + queue_task_running, + queue_task_finished +}; + struct queue_task { char* name; - enum queue_task_status { - queue_task_queued, - queue_task_running, - queue_task_finished - } status; + enum queue_task_status status; struct task_arg **args; int args_len; From 6835a391c79196ea5780bbf074fdfeb42cdf64b5 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 20 Nov 2018 22:05:42 +0900 Subject: [PATCH 23/29] Fixed bugs in the size of `mrb_malloc` allocation. --- src/cfunc_rubyvm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cfunc_rubyvm.c b/src/cfunc_rubyvm.c index 234e8a2..c4e7614 100644 --- a/src/cfunc_rubyvm.c +++ b/src/cfunc_rubyvm.c @@ -102,7 +102,7 @@ struct task_arg* mrb_value_to_task_arg(mrb_state *mrb, mrb_value v) { int i; arg->value.array.len = RARRAY_LEN(v); - arg->value.array.ptr = mrb_malloc(mrb, RARRAY_LEN(v) * sizeof(struct task_arg)); + arg->value.array.ptr = (struct task_arg**)mrb_malloc(mrb, RARRAY_LEN(v) * sizeof(struct task_arg*)); for(i=0; ivalue.array.ptr[i] = mrb_value_to_task_arg(mrb, RARRAY_PTR(v)[i]); @@ -295,7 +295,7 @@ cfunc_rubyvm_open(void *args) taskname = mrb_intern_cstr(mrb, task->name); args_len = task->args_len; - args = mrb_malloc(mrb, sizeof(struct task_arg) * task->args_len); + args = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * task->args_len); for(i=0; iargs_len; ++i) { args[i] = task_arg_to_mrb_value(data->state, task->args[i]); } @@ -343,7 +343,7 @@ cfunc_rubyvm_dispatch(mrb_state *mrb, mrb_value self) strncpy(task->name, name, name_len+1); task->args_len = args_len; - task->args = mrb_malloc(mrb, sizeof(struct task_arg) * task->args_len); + task->args = (struct task_arg**)mrb_malloc(mrb, sizeof(struct task_arg*) * task->args_len); for(i=0; iargs[i] = mrb_value_to_task_arg(mrb, args[i]); } From ac0384a348aad584065f853a5522c28d2bbf822f Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 20 Nov 2018 22:06:58 +0900 Subject: [PATCH 24/29] Move local variable declaration to the top of the function. --- test/func.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/func.c b/test/func.c index f40a6df..9ed7086 100644 --- a/test/func.c +++ b/test/func.c @@ -37,12 +37,13 @@ int check_offset5(uint8_t *p1, uint8_t *p2) { static int test_func(uint32_t v1, uint32_t v2) { return v1 + v2; } void test_func_ref() { + uint8_t a, b; + struct STest v1 = {0, 0, 1}; struct STest2 v2 = { {0, 0, 1}, 0.0 }; cfunc_test_func1(v1); cfunc_test_func2(v2); cfunc_test_func3(test_func); cfunc_test_func4(0, 1); - uint8_t a, b; check_offset5(&a, &b); } From 14f32999b9e80f74f088338aa9b7303aadde01f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20Marsza=C5=82ek?= Date: Fri, 19 Feb 2021 16:09:36 +0100 Subject: [PATCH 25/29] 2.1.2 remove mrb_run, replaced with mrb_top_run --- src/cfunc_rubyvm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cfunc_rubyvm.c b/src/cfunc_rubyvm.c index c4e7614..297adc3 100644 --- a/src/cfunc_rubyvm.c +++ b/src/cfunc_rubyvm.c @@ -269,7 +269,7 @@ cfunc_rubyvm_open(void *args) irep = mrb_read_irep(mrb, data->mrb_data); - mrb_run(mrb, mrb_proc_new(mrb, irep), mrb_top_self(mrb)); + mrb_top_run(mrb, mrb_proc_new(mrb, irep), mrb_top_self(mrb), 0); mrb_irep_decref(mrb, irep); From d817f46809e3009f9858cfe29222cff1ad962c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20Marsza=C5=82ek?= Date: Fri, 19 Feb 2021 16:12:22 +0100 Subject: [PATCH 26/29] fixed building libffi upgrade libffi version to 3.3 fixed downloading (binary streams!) fixed depreciation of Kernel.open with uri fixed building on windows & mingw toolchain --- mrbgem.rake | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mrbgem.rake b/mrbgem.rake index ed4fe9f..3ac897e 100644 --- a/mrbgem.rake +++ b/mrbgem.rake @@ -29,7 +29,7 @@ MRuby::Gem::Specification.new('mruby-cfunc') do |spec| end end - def spec.download_libffi(libffi_version = '3.0.13', tar = 'tar') + def spec.download_libffi(libffi_version = '3.3', tar = 'tar') libffi_url = "ftp://sourceware.org/pub/libffi/libffi-#{libffi_version}.tar.gz" libffi_build_root = "#{MRUBY_ROOT}/build/libffi/#{build.name}" libffi_dir = "#{libffi_build_root}/libffi-#{libffi_version}" @@ -37,16 +37,18 @@ MRuby::Gem::Specification.new('mruby-cfunc') do |spec| unless File.exists?(libffi_a) puts "Downloading #{libffi_url}" - open(libffi_url, 'r') do |ftp| + URI.open(libffi_url, 'rb') do |ftp| libffi_tar = ftp.read puts "Extracting" FileUtils.mkdir_p libffi_build_root - IO.popen("#{tar} xfz - -C #{filename libffi_build_root}", 'w') do |f| + IO.popen("#{tar} xfz - -C #{filename libffi_build_root}", 'wb') do |f| f.write libffi_tar end puts "Done" end - sh %Q{(cd #{filename libffi_dir} && CC=#{build.cc.command} CFLAGS="#{build.cc.all_flags.gsub('\\','\\\\').gsub('"', '\\"')}" ./configure --prefix=`pwd` && make clean install)} + Dir.chdir(filename libffi_dir) do + sh %Q{env CC=#{build.cc.command} CFLAGS="#{build.cc.all_flags.gsub('\\', '\\\\').gsub('"', '\\"')}" ./configure --prefix="#{Dir.pwd}" && make clean install} + end end self.linker.library_paths << File.dirname(libffi_a) From 6864711052352d4627df00b7289037d2554b3e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20Marsza=C5=82ek?= Date: Fri, 19 Feb 2021 16:14:19 +0100 Subject: [PATCH 27/29] updated docs how to compile on windows how to use to call .dll functions on windows --- README.md | 54 +++++++++++++++++++++++++++++--------- examples/windows_cfunc1.rb | 43 ++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 examples/windows_cfunc1.rb diff --git a/README.md b/README.md index 8ac2d10..90b58d9 100644 --- a/README.md +++ b/README.md @@ -2,23 +2,21 @@ Interface to C functions on mruby. it's based on [libffi](http://sourceware.org/libffi/). - ## Build status [![Build Status](https://secure.travis-ci.org/mobiruby/mruby-cfunc.png)](http://travis-ci.org/mobiruby/mruby-cfunc) - ## Install It's mrbgems. -When you use in your project, please add below to your ``build_config.rb``. +When you use in your project, please add below to your `build_config.rb`. ```ruby conf.gem 'path/to/here' do |g| # g.use_pkg_config # use pkg-config for libffi linking # g.download_libffi # download and link latest libffi - + # if your libffi is installed in a non standard path # g.cc.include_paths << '[...]/include' # g.linker.library_paths << '[...]/lib' @@ -29,28 +27,60 @@ If you want to run tests, please run below command. make test +## Windows -## Todo +To compile on windows you have to provie dlfcn-win32 libraray. + +- install ruby from rubyinstaller.org - get newest with devkit, 64bit +- after installing run as admin: + +`ridk install 1 2 3` -* Test! -* Improve error handling -* Support anonymous struct -* Examples -* Documents +- run msys2 console & install library: +`pacman -S mingw-w64-x86_64-dlfcn` + +- active ridk ruby build system by adding at the top of you Rakefile line: + +`ruby RubyInstaller::Runtime.enable_msys_apps ` + +- then add to your build_config.rb - to build libffi & link it staically: + +```ruby +MRuby::Build.new do |conf| + toolchain :gcc + conf.gem mgem: "cfunc" do |gem| + gem.download_libffi + gem.linker.flags << "-static" + end + + # ... rest of build_config.rb +end +``` + +- now you can build mruby with cfunc mgem! :) + +## Todo + +- Test! +- Improve error handling +- Support anonymous struct +- Examples +- Documents ## Contributing Feel free to open tickets or send pull requests with improvements. Thanks in advance for your help! - ## Authors Original Authors "MobiRuby developers" are [https://github.com/mobiruby/mobiruby-ios/tree/master/AUTHORS](https://github.com/mobiruby/mobiruby-ios/tree/master/AUTHORS) - ## License See Copyright Notice in [cfunc.h](https://github.com/mobiruby/mruby-cfunc/blob/master/include/cfunc.h). +``` + +``` diff --git a/examples/windows_cfunc1.rb b/examples/windows_cfunc1.rb new file mode 100644 index 0000000..304473c --- /dev/null +++ b/examples/windows_cfunc1.rb @@ -0,0 +1,43 @@ +module Win32 + module User32 + # win32 api compatibile version + # each libcall format is like this: + # - return tyupe + # - libraray + # - function to call + # - variable number of arguments to function + # - last param CFunc::Int.ew(X) - where X is number of arguments you pass above + DLL = CFunc.libcall(CFunc::Pointer, "kernel32.dll", "LoadLibraryA", "user32.dll", CFunc::Int.new(1)) + MessageBeep = begin + ptr = CFunc.libcall(CFunc::Pointer, "kernel32.dll", "GetProcAddress", DLL, "MessageBeep", CFunc::Int.new(2)) + CFunc::FunctionPointer.new(ptr).tap do |func| + func.arguments_type = [CFunc::UInt32] + func.result_type = CFunc::UInt32 + end + end + + MB_ICONASTERISK = 0x40 + + # shortcut version - it's a little bit slower, because it will try to open user32.dll again + MessageBox = proc do |text, caption, type| + CFunc.libcall( + CFunc::UInt32, # retrun type + "user32.dll", # dll + "MessageBoxA", # function + nil, text, caption, CFunc::Int.new(type), # args + CFunc::Int.new(4) # number of args + ) + end + + MB_OKCANCEL = 0x1 + end +end + +# then you can call MessageBeep like that +Win32::User32::MessageBeep.call(Win32::User32::MB_ICONASTERISK) + +# if you want get return value: +ret = Win32::User32::MessageBeep.call(Win32::User32::MB_ICONASTERISK).value + +# and calling shortcut version +Win32::User32::MessageBox.("MRuby MessageBox", "MRuby MessageBox", Win32::User32::MB_OKCANCEL) From ca6e9f593f92577b6710b1062ddece96daf233b2 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 5 Mar 2021 14:36:46 +0900 Subject: [PATCH 28/29] cfunc_rubyvm.c: update for the recent mruby source. --- src/cfunc_rubyvm.c | 114 ++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/src/cfunc_rubyvm.c b/src/cfunc_rubyvm.c index 297adc3..48398d0 100644 --- a/src/cfunc_rubyvm.c +++ b/src/cfunc_rubyvm.c @@ -71,49 +71,54 @@ struct task_arg* mrb_value_to_task_arg(mrb_state *mrb, mrb_value v) arg->tt = mrb_type(v); switch (mrb_type(v)) { case MRB_TT_FALSE: + if (mrb_nil_p(v)) { + arg->value.i = 0; + break; + } + /* fall through */ case MRB_TT_TRUE: + arg->value.i = 1; + break; case MRB_TT_FIXNUM: - arg->value.i = v.value.i; - break; + arg->value.i = mrb_integer(v); + break; case MRB_TT_FLOAT: - arg->value.f = v.value.f; - break; + arg->value.f = mrb_float(v); + break; case MRB_TT_SYMBOL: - { - mrb_int len; - const char* name = mrb_sym2name_len(mrb, v.value.sym, &len); - arg->value.string.len = len; - arg->value.string.ptr = (char*)mrb_malloc(mrb, len + 1); - memcpy(arg->value.string.ptr, name, len + 1); - } - break; + { + mrb_int len; + const char* name = mrb_sym_name_len(mrb, mrb_symbol(v), &len); + arg->value.string.len = len; + arg->value.string.ptr = (char*)mrb_malloc(mrb, len + 1); + memcpy(arg->value.string.ptr, name, len + 1); + } + break; case MRB_TT_STRING: - { - arg->value.string.len = RSTRING_LEN(v); - arg->value.string.ptr = (char*)mrb_malloc(mrb, arg->value.string.len+1); - memcpy(arg->value.string.ptr, RSTRING_PTR(v), arg->value.string.len+1); - } - break; + { + arg->value.string.len = RSTRING_LEN(v); + arg->value.string.ptr = (char*)mrb_malloc(mrb, arg->value.string.len+1); + memcpy(arg->value.string.ptr, RSTRING_PTR(v), arg->value.string.len+1); + } + break; case MRB_TT_ARRAY: - { - int i; - arg->value.array.len = RARRAY_LEN(v); - arg->value.array.ptr = (struct task_arg**)mrb_malloc(mrb, RARRAY_LEN(v) * sizeof(struct task_arg*)); - - for(i=0; ivalue.array.ptr[i] = mrb_value_to_task_arg(mrb, RARRAY_PTR(v)[i]); - } + { + arg->value.array.len = RARRAY_LEN(v); + arg->value.array.ptr = (struct task_arg**)mrb_malloc(mrb, RARRAY_LEN(v) * sizeof(struct task_arg*)); + for(int i=0; ivalue.array.ptr[i] = mrb_value_to_task_arg(mrb, RARRAY_PTR(v)[i]); } - break; + } + break; default: - mrb_free(mrb, arg); - mrb_raise(mrb, E_TYPE_ERROR, "cannot pass to other RubyVM"); - break; + mrb_free(mrb, arg); + mrb_raise(mrb, E_TYPE_ERROR, "cannot pass to other RubyVM"); + break; } return arg; @@ -124,40 +129,45 @@ mrb_value task_arg_to_mrb_value(mrb_state *mrb, struct task_arg* arg) { mrb_value v; - mrb_type(v) = arg->tt; switch (arg->tt) { case MRB_TT_FALSE: + if (arg->value.i == 0) + v = mrb_nil_value(); + else + v = mrb_false_value(); + break; case MRB_TT_TRUE: + v = mrb_true_value(); + break; case MRB_TT_FIXNUM: - v.value.i = arg->value.i; - break; + v = mrb_int_value(mrb, arg->value.i); + break; case MRB_TT_FLOAT: - v.value.f = arg->value.f; - break; + v = mrb_float_value(mrb, arg->value.i); + break; case MRB_TT_SYMBOL: - v.value.sym = mrb_intern_cstr(mrb, arg->value.string.ptr); - break; + v = mrb_symbol_value(mrb_intern_cstr(mrb, arg->value.string.ptr)); + break; case MRB_TT_STRING: - v = mrb_str_new(mrb, arg->value.string.ptr, arg->value.string.len); - break; + v = mrb_str_new(mrb, arg->value.string.ptr, arg->value.string.len); + break; case MRB_TT_ARRAY: - { - int i; - v = mrb_ary_new_capa(mrb, arg->value.array.len); - mrb_ary_resize(mrb, v, arg->value.array.len); - for(i=0; ivalue.array.len; i++) { - mrb_ary_set(mrb, v, i, task_arg_to_mrb_value(mrb, arg->value.array.ptr[i])); - } + { + v = mrb_ary_new_capa(mrb, arg->value.array.len); + mrb_ary_resize(mrb, v, arg->value.array.len); + for(int i=0; ivalue.array.len; i++) { + mrb_ary_set(mrb, v, i, task_arg_to_mrb_value(mrb, arg->value.array.ptr[i])); } - break; + } + break; default: - mrb_raise(mrb, E_TYPE_ERROR, "cannot pass to other RubyVM"); - break; + mrb_raise(mrb, E_TYPE_ERROR, "cannot pass to other RubyVM"); + break; } return v; @@ -262,14 +272,14 @@ cfunc_rubyvm_open(void *args) mrb_state *mrb = mrb_open(); mrb_irep* irep; data->state = mrb; - + #ifdef DISABLE_GEMS init_cfunc_module(mrb); #endif irep = mrb_read_irep(mrb, data->mrb_data); - mrb_top_run(mrb, mrb_proc_new(mrb, irep), mrb_top_self(mrb), 0); + mrb_toplevel_run(mrb, mrb_proc_new(mrb, irep)); mrb_irep_decref(mrb, irep); @@ -289,7 +299,7 @@ cfunc_rubyvm_open(void *args) while(data->queue->length == 0) { pthread_cond_wait(&data->queue_cond, &data->queue_mutex); } - + task = (struct queue_task*)vector_dequeue(data->queue); task->status = queue_task_running; taskname = mrb_intern_cstr(mrb, task->name); From 840949abfee014a4baf2f2e79827f83413c1501f Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 5 Mar 2021 14:37:31 +0900 Subject: [PATCH 29/29] .gitignore: exclude `.lock` files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d421d4f..6c3d637 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ tmp *.d *.dSYM *.a +*.lock # Packages # ############