From bfd2a539edab8ef7935a75de8a6885d74ff9e8ef Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 26 Mar 2014 01:09:09 +0900 Subject: add new function mrb_toplevel_run to prevent running through C function boudaries on exceptions; close #1942 --- include/mruby.h | 1 + src/load.c | 4 ++-- src/parse.y | 2 +- src/vm.c | 17 +++++++++++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/include/mruby.h b/include/mruby.h index 17d4f1e19..9c63689a0 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -276,6 +276,7 @@ void mrb_close(mrb_state*); mrb_value mrb_top_self(mrb_state *); mrb_value mrb_run(mrb_state*, struct RProc*, mrb_value); +mrb_value mrb_toplevel_run(mrb_state*, struct RProc*); mrb_value mrb_context_run(mrb_state*, struct RProc*, mrb_value, unsigned int); void mrb_p(mrb_state*, mrb_value); diff --git a/src/load.c b/src/load.c index ca78dbf8c..5b093b751 100644 --- a/src/load.c +++ b/src/load.c @@ -512,7 +512,7 @@ mrb_load_irep_cxt(mrb_state *mrb, const uint8_t *bin, mrbc_context *c) proc = mrb_proc_new(mrb, irep); mrb_irep_decref(mrb, irep); if (c && c->no_exec) return mrb_obj_value(proc); - val = mrb_context_run(mrb, proc, mrb_top_self(mrb), 0); + val = mrb_toplevel_run(mrb, proc); return val; } @@ -733,7 +733,7 @@ mrb_load_irep_file_cxt(mrb_state *mrb, FILE* fp, mrbc_context *c) proc = mrb_proc_new(mrb, irep); mrb_irep_decref(mrb, irep); if (c && c->no_exec) return mrb_obj_value(proc); - val = mrb_context_run(mrb, proc, mrb_top_self(mrb), 0); + val = mrb_toplevel_run(mrb, proc); return val; } diff --git a/src/parse.y b/src/parse.y index 67d1aee2f..e6ac036bc 100644 --- a/src/parse.y +++ b/src/parse.y @@ -5506,7 +5506,7 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c) if (mrb->c->ci) { mrb->c->ci->target_class = target; } - v = mrb_context_run(mrb, proc, mrb_top_self(mrb), 0); + v = mrb_toplevel_run(mrb, proc); if (mrb->exc) return mrb_nil_value(); return v; } diff --git a/src/vm.c b/src/vm.c index 8504cc34c..505f3f955 100644 --- a/src/vm.c +++ b/src/vm.c @@ -2270,3 +2270,20 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) { return mrb_context_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */ } + +mrb_value +mrb_toplevel_run(mrb_state *mrb, struct RProc *proc) +{ + mrb_callinfo *ci; + mrb_value v; + + if (!mrb->c->cibase || mrb->c->ci == mrb->c->cibase) { + return mrb_context_run(mrb, proc, mrb_top_self(mrb), 0); + } + ci = cipush(mrb); + ci->acc = CI_ACC_SKIP; + v = mrb_context_run(mrb, proc, mrb_top_self(mrb), 0); + cipop(mrb); + + return v; +} -- cgit v1.2.3