Commit 64300b2c authored by take_cheeze's avatar take_cheeze

Add API `mrb_atexit()`.

`mrb_final_mrbgems` will be called as mrb_state atexit function.
Maybe useful in #1844.
parent c071ad13
...@@ -102,6 +102,8 @@ enum gc_state { ...@@ -102,6 +102,8 @@ enum gc_state {
struct mrb_jmpbuf; struct mrb_jmpbuf;
typedef void (*mrb_atexit_func)(struct mrb_state*);
typedef struct mrb_state { typedef struct mrb_state {
struct mrb_jmpbuf *jmp; struct mrb_jmpbuf *jmp;
...@@ -169,6 +171,9 @@ typedef struct mrb_state { ...@@ -169,6 +171,9 @@ typedef struct mrb_state {
struct RClass *eStandardError_class; struct RClass *eStandardError_class;
void *ud; /* auxiliary data */ void *ud; /* auxiliary data */
mrb_atexit_func *atexit_stack;
mrb_int atexit_stack_len;
} mrb_state; } mrb_state;
#if __STDC_VERSION__ >= 201112L #if __STDC_VERSION__ >= 201112L
...@@ -413,6 +418,8 @@ void* mrb_pool_realloc(struct mrb_pool*, void*, size_t oldlen, size_t newlen); ...@@ -413,6 +418,8 @@ void* mrb_pool_realloc(struct mrb_pool*, void*, size_t oldlen, size_t newlen);
mrb_bool mrb_pool_can_realloc(struct mrb_pool*, void*, size_t); mrb_bool mrb_pool_can_realloc(struct mrb_pool*, void*, size_t);
void* mrb_alloca(mrb_state *mrb, size_t); void* mrb_alloca(mrb_state *mrb, size_t);
void mrb_atexit(mrb_state *mrb, mrb_atexit_func func);
#ifdef MRB_DEBUG #ifdef MRB_DEBUG
#include <assert.h> #include <assert.h>
#define mrb_assert(p) assert(p) #define mrb_assert(p) assert(p)
......
...@@ -54,11 +54,3 @@ mrb_init_core(mrb_state *mrb) ...@@ -54,11 +54,3 @@ mrb_init_core(mrb_state *mrb)
mrb_init_mrbgems(mrb); DONE; mrb_init_mrbgems(mrb); DONE;
#endif #endif
} }
void
mrb_final_core(mrb_state *mrb)
{
#ifndef DISABLE_GEMS
mrb_final_mrbgems(mrb); DONE;
#endif
}
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
void mrb_init_heap(mrb_state*); void mrb_init_heap(mrb_state*);
void mrb_init_core(mrb_state*); void mrb_init_core(mrb_state*);
void mrb_final_core(mrb_state*);
static mrb_value static mrb_value
inspect_main(mrb_state *mrb, mrb_value mod) inspect_main(mrb_state *mrb, mrb_value mod)
...@@ -40,6 +39,7 @@ mrb_open_allocf(mrb_allocf f, void *ud) ...@@ -40,6 +39,7 @@ mrb_open_allocf(mrb_allocf f, void *ud)
mrb->ud = ud; mrb->ud = ud;
mrb->allocf = f; mrb->allocf = f;
mrb->current_white_part = MRB_GC_WHITE_A; mrb->current_white_part = MRB_GC_WHITE_A;
mrb->atexit_stack_len = 0;
#ifndef MRB_GC_FIXED_ARENA #ifndef MRB_GC_FIXED_ARENA
mrb->arena = (struct RBasic**)mrb_malloc(mrb, sizeof(struct RBasic*)*MRB_GC_ARENA_SIZE); mrb->arena = (struct RBasic**)mrb_malloc(mrb, sizeof(struct RBasic*)*MRB_GC_ARENA_SIZE);
...@@ -221,7 +221,11 @@ mrb_free_context(mrb_state *mrb, struct mrb_context *c) ...@@ -221,7 +221,11 @@ mrb_free_context(mrb_state *mrb, struct mrb_context *c)
void void
mrb_close(mrb_state *mrb) mrb_close(mrb_state *mrb)
{ {
mrb_final_core(mrb); mrb_int i;
for (i = mrb->atexit_stack_len; i > 0; --i) {
mrb->atexit_stack[i - 1](mrb);
}
/* free */ /* free */
mrb_gc_free_gv(mrb); mrb_gc_free_gv(mrb);
...@@ -258,3 +262,18 @@ mrb_top_self(mrb_state *mrb) ...@@ -258,3 +262,18 @@ mrb_top_self(mrb_state *mrb)
} }
return mrb_obj_value(mrb->top_self); return mrb_obj_value(mrb->top_self);
} }
void
mrb_atexit(mrb_state *mrb, mrb_atexit_func f)
{
size_t stack_size;
stack_size = sizeof(mrb_atexit_func) * (mrb->atexit_stack_len + 1);
if (mrb->atexit_stack_len == 0) {
mrb->atexit_stack = (mrb_atexit_func*)mrb_malloc(mrb, stack_size);
} else {
mrb->atexit_stack = (mrb_atexit_func*)mrb_realloc(mrb, mrb->atexit_stack, stack_size);
}
mrb->atexit_stack[mrb->atexit_stack_len++] = f;
}
...@@ -26,14 +26,15 @@ MRuby.each_target do ...@@ -26,14 +26,15 @@ MRuby.each_target do
f.puts %Q[] 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[#{gems.map{|g| "void GENERATED_TMP_mrb_%s_gem_final(mrb_state* mrb);" % g.funcname}.join("\n")}]
f.puts %Q[] f.puts %Q[]
f.puts %Q[void] f.puts %Q[static void]
f.puts %Q[mrb_init_mrbgems(mrb_state *mrb) {] f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {]
f.puts %Q[#{gems.map{|g| "GENERATED_TMP_mrb_%s_gem_init(mrb);" % g.funcname}.join("\n")}] f.puts %Q[#{gems.map{|g| "GENERATED_TMP_mrb_%s_gem_final(mrb);" % g.funcname}.join("\n")}]
f.puts %Q[}] f.puts %Q[}]
f.puts %Q[] f.puts %Q[]
f.puts %Q[void] f.puts %Q[void]
f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {] f.puts %Q[mrb_init_mrbgems(mrb_state *mrb) {]
f.puts %Q[#{gems.map{|g| "GENERATED_TMP_mrb_%s_gem_final(mrb);" % g.funcname}.join("\n")}] f.puts %Q[#{gems.map{|g| "GENERATED_TMP_mrb_%s_gem_init(mrb);" % g.funcname}.join("\n")}]
f.puts %Q[mrb_atexit(mrb, mrb_final_mrbgems);]
f.puts %Q[}] f.puts %Q[}]
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment