diff options
Diffstat (limited to 'mrbgems/mruby-eval/src')
| -rw-r--r-- | mrbgems/mruby-eval/src/eval.c | 102 |
1 files changed, 51 insertions, 51 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index 508f5ffcb..13dd3ea4c 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -9,10 +9,10 @@ #include <mruby/variable.h> struct REnv *mrb_env_new(mrb_state *mrb, struct mrb_context *c, mrb_callinfo *ci, int nstacks, mrb_value *stack, struct RClass *tc); -mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook); +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); +mrb_value mrb_mod_module_eval(mrb_state*, mrb_value); void mrb_codedump_all(mrb_state*, struct RProc*); -void mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack); static struct RProc* create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line) @@ -52,10 +52,19 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi e = NULL; } + if (file) { + if (strlen(file) >= UINT16_MAX) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "filename too long"); + } + } + else { + file = "(eval)"; + } + cxt = mrbc_context_new(mrb); cxt->lineno = (uint16_t)line; - mrbc_filename(mrb, cxt, file ? file : "(eval)"); + mrbc_filename(mrb, cxt, file); cxt->capture_errors = TRUE; cxt->no_optimize = TRUE; cxt->upper = scope && MRB_PROC_CFUNC_P(scope) ? NULL : scope; @@ -64,6 +73,7 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi /* only occur when memory ran out */ if (!p) { + mrbc_context_free(mrb, cxt); mrb_raise(mrb, E_RUNTIME_ERROR, "Failed to create parser state (out of memory)"); } @@ -71,6 +81,11 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi /* parse error */ mrb_value str; + mrbc_context_free(mrb, cxt); + if (!p->error_buffer[0].message) { + mrb_parser_free(p); + mrb_raise(mrb, E_SYNTAX_ERROR, "compile error"); + } if (file) { str = mrb_format(mrb, "file %s line %d: %s", file, @@ -83,7 +98,6 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi p->error_buffer[0].message); } mrb_parser_free(p); - mrbc_context_free(mrb, cxt); mrb_exc_raise(mrb, mrb_exc_new_str(mrb, E_SYNTAX_ERROR, str)); } @@ -127,44 +141,14 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi } static mrb_value -exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc, mrb_func_t posthook) +exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc) { /* no argument passed from eval() */ - mrb->c->ci->argc = 0; + mrb->c->ci->n = 0; + mrb->c->ci->nk = 0; /* clear block */ mrb->c->ci->stack[1] = mrb_nil_value(); - return mrb_exec_irep(mrb, self, proc, posthook); -} - -static void -eval_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack) -{ - mrb_assert(mrb->c->stend >= stack + num); - mrb_proc_merge_lvar(mrb, irep, env, num, lv, stack); -} - -static mrb_value -eval_merge_lvar_hook(mrb_state *mrb, mrb_value dummy_self) -{ - const mrb_callinfo *orig_ci = &mrb->c->ci[1]; - const struct RProc *orig_proc = orig_ci->proc; - const mrb_irep *orig_irep = orig_proc->body.irep; - int orig_nlocals = orig_irep->nlocals; - - if (orig_nlocals > 1) { - struct RProc *proc = (struct RProc *)orig_proc->upper; - struct REnv *env = MRB_PROC_ENV(orig_proc); - eval_merge_lvar(mrb, (mrb_irep *)proc->body.irep, env, - orig_nlocals - 1, orig_irep->lv, - mrb->c->ci->stack + 3 /* hook proc + exc + ret val */); - } - - mrb_value exc = mrb->c->ci->stack[1]; - if (!mrb_nil_p(exc)) { - mrb_exc_raise(mrb, exc); - } - - return mrb->c->ci->stack[2]; + return mrb_exec_irep(mrb, self, proc); } static mrb_value @@ -176,30 +160,21 @@ f_eval(mrb_state *mrb, mrb_value self) const char *file = NULL; mrb_int line = 1; struct RProc *proc; - mrb_func_t posthook = NULL; mrb_get_args(mrb, "s|ozi", &s, &len, &binding, &file, &line); proc = create_proc_from_string(mrb, s, len, binding, file, line); if (!mrb_nil_p(binding)) { self = mrb_iv_get(mrb, binding, MRB_SYM(recv)); - if (mrb_env_p(mrb_iv_get(mrb, binding, MRB_SYM(env)))) { - posthook = eval_merge_lvar_hook; - } } mrb_assert(!MRB_PROC_CFUNC_P(proc)); - return exec_irep(mrb, self, proc, posthook); + return exec_irep(mrb, self, proc); } static mrb_value f_instance_eval(mrb_state *mrb, mrb_value self) { - mrb_value b; - mrb_int argc; const mrb_value *argv; - - mrb_get_args(mrb, "*!&", &argv, &argc, &b); - - if (mrb_nil_p(b)) { + if (!mrb_block_given_p(mrb)) { const char *s; mrb_int len; const char *file = NULL; @@ -213,19 +188,44 @@ f_instance_eval(mrb_state *mrb, mrb_value self) MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(cv)); mrb_assert(!MRB_PROC_CFUNC_P(proc)); mrb_vm_ci_target_class_set(mrb->c->ci, mrb_class_ptr(cv)); - return exec_irep(mrb, self, proc, NULL); + return exec_irep(mrb, self, proc); } else { - mrb_get_args(mrb, "&", &b); + mrb_get_args(mrb, ""); return mrb_obj_instance_eval(mrb, self); } } +static mrb_value +f_class_eval(mrb_state *mrb, mrb_value self) +{ + if (!mrb_block_given_p(mrb)) { + const char *s; + mrb_int len; + const char *file = NULL; + mrb_int line = 1; + struct RProc *proc; + + mrb_get_args(mrb, "s|zi", &s, &len, &file, &line); + proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line); + MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(self)); + mrb_assert(!MRB_PROC_CFUNC_P(proc)); + mrb_vm_ci_target_class_set(mrb->c->ci, mrb_class_ptr(self)); + return exec_irep(mrb, self, proc); + } + else { + mrb_get_args(mrb, ""); + return mrb_mod_module_eval(mrb, self); + } +} + void mrb_mruby_eval_gem_init(mrb_state* mrb) { mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3)); mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(BasicObject)), MRB_SYM(instance_eval), f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); + mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Module)), MRB_SYM(module_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); + mrb_define_method_id(mrb, mrb_class_get_id(mrb, MRB_SYM(Module)), MRB_SYM(class_eval), f_class_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); } void |
