diff --git a/include/mruby.h b/include/mruby.h index 1fd525a41..9d90869cb 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -273,6 +273,8 @@ typedef struct mrb_state { mrb_gc gc; + mrb_bool bootstrapping; + #ifndef MRB_NO_METHOD_CACHE struct mrb_cache_entry cache[MRB_METHOD_CACHE_SIZE]; #endif @@ -1247,6 +1249,7 @@ MRB_API mrb_state* mrb_open_core(void); * Pointer to the mrb_state to be closed. */ MRB_API void mrb_close(mrb_state *mrb); +MRB_API void mrb_method_cache_clear(mrb_state *mrb); /** * The memory allocation function. You can redefine this function for your own allocator. diff --git a/src/class.c b/src/class.c index a23b87447..1d7b42e9f 100644 --- a/src/class.c +++ b/src/class.c @@ -600,7 +600,6 @@ mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super) static mrb_value mrb_do_nothing(mrb_state *mrb, mrb_value); #ifndef MRB_NO_METHOD_CACHE -static void mc_clear(mrb_state *mrb); static void mc_clear_by_id(mrb_state *mrb, mrb_sym mid); #else #define mc_clear(mrb) @@ -1033,7 +1032,7 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_ MRB_SET_VISIBILITY_FLAGS(flags, (e ? MRB_ENV_VISIBILITY(e) : MRB_CI_VISIBILITY(ci))); } mt_put(mrb, h, mid, flags, ptr); - mc_clear_by_id(mrb, mid); + if (!mrb->bootstrapping) mc_clear_by_id(mrb, mid); } static void @@ -1900,7 +1899,7 @@ include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, stru skip: m = m->super; } - mc_clear(mrb); + if (!mrb->bootstrapping) mrb_method_cache_clear(mrb); return 0; } @@ -2503,8 +2502,8 @@ mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, m #ifndef MRB_NO_METHOD_CACHE /* clear whole method cache table */ -static void -mc_clear(mrb_state *mrb) +MRB_API void +mrb_method_cache_clear(mrb_state *mrb) { static const struct mrb_cache_entry ce_zero ={0}; diff --git a/src/state.c b/src/state.c index 1aeb42552..1b3d687b9 100644 --- a/src/state.c +++ b/src/state.c @@ -47,12 +47,16 @@ mrb_open_core(void) *mrb = mrb_state_zero; mrb->atexit_stack_len = 0; + mrb->bootstrapping = TRUE; if (mrb_core_init_protect(mrb, init_gc_and_core, NULL)) { mrb_close(mrb); return NULL; } + mrb_method_cache_clear(mrb); + mrb->bootstrapping = FALSE; + return mrb; }