summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-eval/src/eval.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-02-04 16:19:31 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2017-02-04 16:19:31 +0900
commit48e0bbbfeea8268b09ad0a6bbc840834cc443fe0 (patch)
tree882a58b328d81b6ac23530f9f7a215365bf64ba6 /mrbgems/mruby-eval/src/eval.c
parentbf4e79cc62af809138bc7db7e54ece67080b5fa8 (diff)
downloadmruby-48e0bbbfeea8268b09ad0a6bbc840834cc443fe0.tar.gz
mruby-48e0bbbfeea8268b09ad0a6bbc840834cc443fe0.zip
Make `eval` to use trampoline technique; fix #3415
Now `eval()` can call Fiber.yield etc.
Diffstat (limited to 'mrbgems/mruby-eval/src/eval.c')
-rw-r--r--mrbgems/mruby-eval/src/eval.c17
1 files changed, 7 insertions, 10 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c
index 26dd728ba..81bc80280 100644
--- a/mrbgems/mruby-eval/src/eval.c
+++ b/mrbgems/mruby-eval/src/eval.c
@@ -5,6 +5,9 @@
#include <mruby/proc.h>
#include <mruby/opcode.h>
+mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p);
+mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self);
+
static struct mrb_irep *
get_closure_irep(mrb_state *mrb, int level)
{
@@ -209,22 +212,15 @@ f_eval(mrb_state *mrb, mrb_value self)
mrb_value binding = mrb_nil_value();
char *file = NULL;
mrb_int line = 1;
- mrb_value ret;
struct RProc *proc;
mrb_get_args(mrb, "s|ozi", &s, &len, &binding, &file, &line);
proc = create_proc_from_string(mrb, s, len, binding, file, line);
- ret = mrb_top_run(mrb, proc, mrb->c->stack[0], 0);
- if (mrb->exc) {
- mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
- }
-
- return ret;
+ mrb_assert(!MRB_PROC_CFUNC_P(proc));
+ return mrb_exec_irep(mrb, self, proc);
}
-mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self);
-
#define CI_ACC_SKIP -1
static mrb_value
@@ -250,7 +246,8 @@ f_instance_eval(mrb_state *mrb, mrb_value self)
c->ci->target_class = mrb_class_ptr(cv);
proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line);
mrb->c->ci->env = NULL;
- return mrb_vm_run(mrb, proc, mrb->c->stack[0], 0);
+ mrb_assert(!MRB_PROC_CFUNC_P(proc));
+ return mrb_exec_irep(mrb, self, proc);
}
else {
mrb_get_args(mrb, "&", &b);