diff --git a/include/mruby/proc.h b/include/mruby/proc.h index d4e576f28..4c3db2a62 100644 --- a/include/mruby/proc.h +++ b/include/mruby/proc.h @@ -140,7 +140,8 @@ void mrb_vm_ci_proc_set(mrb_callinfo *ci, const struct RProc *p); struct RClass * mrb_vm_ci_target_class(const mrb_callinfo *ci); void mrb_vm_ci_target_class_set(mrb_callinfo *ci, struct RClass *tc); struct REnv * mrb_vm_ci_env(const mrb_callinfo *ci); -void mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e); +MRB_API void mrb_vm_ci_env_clear(mrb_callinfo *ci); +MRB_API void mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e); MRB_END_DECL diff --git a/lib/mruby/gem.rb b/lib/mruby/gem.rb index 64c6f3dee..3ac952fcb 100644 --- a/lib/mruby/gem.rb +++ b/lib/mruby/gem.rb @@ -224,7 +224,7 @@ module MRuby f.puts %Q[ exit(EXIT_FAILURE);] f.puts %Q[ }] f.puts %Q[ struct REnv *e = mrb_vm_ci_env(mrb->c->cibase);] - f.puts %Q[ mrb_vm_ci_env_set(mrb->c->cibase, NULL);] + f.puts %Q[ mrb_vm_ci_env_clear(mrb->c->cibase);] f.puts %Q[ mrb_env_unshare(mrb, e, FALSE);] end f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] diff --git a/src/vm.c b/src/vm.c index 289924ae0..2c72e35ab 100644 --- a/src/vm.c +++ b/src/vm.c @@ -295,8 +295,8 @@ mrb_vm_ci_env(const mrb_callinfo *ci) return CI_ENV(ci); } -void -mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) +static inline void +ci_env_set(mrb_callinfo *ci, struct REnv *e) { if (ci->u.env) { if (ci->u.env->tt == MRB_TT_ENV) { @@ -308,11 +308,9 @@ mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) ci->u.target_class = ci->u.env->c; } } - else { - if (e) { - e->c = ci->u.target_class; - ci->u.env = e; - } + else if (e) { + e->c = ci->u.target_class; + ci->u.env = e; } } else { @@ -320,6 +318,25 @@ mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) } } +MRB_API void +mrb_vm_ci_env_set(mrb_callinfo *ci, struct REnv *e) +{ + ci_env_set(ci, e); +} + +MRB_API void +mrb_vm_ci_env_clear(mrb_callinfo *ci) +{ + if (ci->u.env) { + if (ci->u.env->tt == MRB_TT_ENV) { + ci->u.target_class = ci->u.env->c; + } + } + else { + ci->u.env = NULL; + } +} + #define CINFO_NONE 0 #define CINFO_SKIP 1 #define CINFO_DIRECT 2 @@ -405,7 +422,7 @@ cipop(mrb_state *mrb) mrb_callinfo *ci = c->ci; struct REnv *env = CI_ENV(ci); - mrb_vm_ci_env_set(ci, NULL); // make possible to free by GC if env is not needed + ci_env_set(ci, NULL); // make possible to free env by GC if not needed struct RProc *b = ci->blk; if (b && !mrb_object_dead_p(mrb, (struct RBasic*)b) && b->tt == MRB_TT_PROC && !MRB_PROC_STRICT_P(b) && MRB_PROC_ENV(b) == CI_ENV(&ci[-1])) {