From 310b0dce8fa1e3f98b2184c2b6c1a0f091c2d4eb Mon Sep 17 00:00:00 2001 From: Yuichiro MASUI Date: Tue, 22 Jan 2013 20:18:48 +0900 Subject: Added finalizer of mrbgems --- doc/mrbgems/README.md | 15 +++++++++++++++ doc/mrbgems/c_and_ruby_extension_example/src/example.c | 5 +++++ doc/mrbgems/c_extension_example/src/example.c | 5 +++++ src/init.c | 9 +++++++++ src/state.c | 3 +++ tasks/mrbgem_spec.rake | 6 ++++++ tasks/mrbgems.rake | 8 ++++++++ tools/mrbc/mrbc.c | 5 +++++ 8 files changed, 56 insertions(+) diff --git a/doc/mrbgems/README.md b/doc/mrbgems/README.md index 9e930d8b2..fb27aa37b 100644 --- a/doc/mrbgems/README.md +++ b/doc/mrbgems/README.md @@ -106,6 +106,21 @@ mrb_c_extension_example_gem_init(mrb_state* mrb) { } ``` +### Finalize + +mrbgems expects that you have implemented a C method called +```mrb_YOURGEMNAME_gem_final(mrb_state)```. ```YOURGEMNAME``` will be replaced +by the name of your GEM. If you call your GEM *c_extension_example*, your +finalizer method could look like this: + +``` +void +mrb_c_extension_example_gem_final(mrb_state* mrb) { + free(someone); +} +``` + + ### Example ``` diff --git a/doc/mrbgems/c_and_ruby_extension_example/src/example.c b/doc/mrbgems/c_and_ruby_extension_example/src/example.c index 3d3cb20c9..7651ae5c0 100644 --- a/doc/mrbgems/c_and_ruby_extension_example/src/example.c +++ b/doc/mrbgems/c_and_ruby_extension_example/src/example.c @@ -13,3 +13,8 @@ mrb_c_and_ruby_extension_example_gem_init(mrb_state* mrb) { struct RClass *class_cextension = mrb_define_module(mrb, "CRubyExtension"); mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, ARGS_NONE()); } + +void +mrb_c_and_ruby_extension_example_gem_final(mrb_state* mrb) { + // finalizer +} diff --git a/doc/mrbgems/c_extension_example/src/example.c b/doc/mrbgems/c_extension_example/src/example.c index 11f54e6d2..fa166186d 100644 --- a/doc/mrbgems/c_extension_example/src/example.c +++ b/doc/mrbgems/c_extension_example/src/example.c @@ -13,3 +13,8 @@ mrb_c_extension_example_gem_init(mrb_state* mrb) { struct RClass *class_cextension = mrb_define_module(mrb, "CExtension"); mrb_define_class_method(mrb, class_cextension, "c_method", mrb_c_method, ARGS_NONE()); } + +void +mrb_c_extension_example_gem_final(mrb_state* mrb) { + // finalizer +} diff --git a/src/init.c b/src/init.c index 48008b150..73ff8fce2 100644 --- a/src/init.c +++ b/src/init.c @@ -28,6 +28,7 @@ void mrb_init_time(mrb_state*); void mrb_init_math(mrb_state*); void mrb_init_mrblib(mrb_state*); void mrb_init_mrbgems(mrb_state*); +void mrb_final_mrbgems(mrb_state*); #define DONE mrb_gc_arena_restore(mrb, 0); void @@ -70,3 +71,11 @@ mrb_init_core(mrb_state *mrb) mrb_init_mrbgems(mrb); DONE; #endif } + +void +mrb_final_core(mrb_state *mrb) +{ +#ifndef DISABLE_GEMS + mrb_final_mrbgems(mrb); DONE; +#endif +} \ No newline at end of file diff --git a/src/state.c b/src/state.c index c1ad4c6ad..c48997a7c 100644 --- a/src/state.c +++ b/src/state.c @@ -12,6 +12,7 @@ void mrb_init_heap(mrb_state*); void mrb_init_core(mrb_state*); void mrb_init_ext(mrb_state*); +void mrb_final_core(mrb_state*); mrb_state* mrb_open_allocf(mrb_allocf f, void *ud) @@ -88,6 +89,8 @@ mrb_close(mrb_state *mrb) { int i; + mrb_final_core(mrb); + /* free */ mrb_gc_free_gv(mrb); mrb_free(mrb, mrb->stbase); diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index 906f47ad0..5af721b0d 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -105,6 +105,8 @@ module MRuby print_gem_init_header f build.mrbc.run f, rbfiles, "gem_mrblib_irep_#{funcname}" unless rbfiles.empty? f.puts %Q[void mrb_#{funcname}_gem_init(mrb_state *mrb);] + f.puts %Q[void mrb_#{funcname}_gem_final(mrb_state *mrb);] + f.puts %Q[] f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_init(mrb_state *mrb) {] f.puts %Q[ int ai = mrb_gc_arena_save(mrb);] f.puts %Q[ mrb_#{funcname}_gem_init(mrb);] if objs != [objfile("#{build_dir}/gem_init")] @@ -117,6 +119,10 @@ module MRuby end f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] f.puts %Q[}] + f.puts %Q[] + f.puts %Q[void GENERATED_TMP_mrb_#{funcname}_gem_final(mrb_state *mrb) {] + f.puts %Q[ mrb_#{funcname}_gem_final(mrb);] if objs != [objfile("#{build_dir}/gem_init")] + f.puts %Q[}] end end # generate_gem_init diff --git a/tasks/mrbgems.rake b/tasks/mrbgems.rake index dc5e67eef..9d8798ef3 100644 --- a/tasks/mrbgems.rake +++ b/tasks/mrbgems.rake @@ -24,10 +24,18 @@ MRuby.each_target do f.puts %Q[#include "mruby.h"] f.puts %Q[] f.puts %Q[#{gems.map{|g| "void GENERATED_TMP_mrb_%s_gem_init(mrb_state* mrb);" % g.funcname}.join("\n")}] + f.puts %Q[] + f.puts %Q[#{gems.map{|g| "void GENERATED_TMP_mrb_%s_gem_final(mrb_state* mrb);" % g.funcname}.join("\n")}] + f.puts %Q[] f.puts %Q[void] f.puts %Q[mrb_init_mrbgems(mrb_state *mrb) {] f.puts %Q[#{gems.map{|g| "GENERATED_TMP_mrb_%s_gem_init(mrb);" % g.funcname}.join("\n")}] f.puts %Q[}] + f.puts %Q[] + f.puts %Q[void] + f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {] + f.puts %Q[#{gems.map{|g| "GENERATED_TMP_mrb_%s_gem_final(mrb);" % g.funcname}.join("\n")}] + f.puts %Q[}] end end end diff --git a/tools/mrbc/mrbc.c b/tools/mrbc/mrbc.c index 4dc9871c7..63762143a 100644 --- a/tools/mrbc/mrbc.c +++ b/tools/mrbc/mrbc.c @@ -231,4 +231,9 @@ void mrb_init_mrbgems(mrb_state *mrb) { } + +void +mrb_final_mrbgems(mrb_state *mrb) +{ +} #endif -- cgit v1.2.3