summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYuichiro MASUI <[email protected]>2013-01-22 20:18:48 +0900
committerYuichiro MASUI <[email protected]>2013-01-22 20:18:48 +0900
commit310b0dce8fa1e3f98b2184c2b6c1a0f091c2d4eb (patch)
treedf4a8cc57c2d5b52fe20aa3fafbc6508799e3512
parentcc2e4e73deea917ffd0c9ce6ad2840455df7b60b (diff)
downloadmruby-310b0dce8fa1e3f98b2184c2b6c1a0f091c2d4eb.tar.gz
mruby-310b0dce8fa1e3f98b2184c2b6c1a0f091c2d4eb.zip
Added finalizer of mrbgems
-rw-r--r--doc/mrbgems/README.md15
-rw-r--r--doc/mrbgems/c_and_ruby_extension_example/src/example.c5
-rw-r--r--doc/mrbgems/c_extension_example/src/example.c5
-rw-r--r--src/init.c9
-rw-r--r--src/state.c3
-rw-r--r--tasks/mrbgem_spec.rake6
-rw-r--r--tasks/mrbgems.rake8
-rw-r--r--tools/mrbc/mrbc.c5
8 files changed, 56 insertions, 0 deletions
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