diff options
| author | dearblue <[email protected]> | 2021-02-22 23:32:18 +0900 |
|---|---|---|
| committer | dearblue <[email protected]> | 2021-02-22 23:32:18 +0900 |
| commit | 792f6ac6700469ddf9be8f87ca3376082f9af7f3 (patch) | |
| tree | f04a5ffe00d4f442286a833b06d472941b20c93c /mrbgems/mruby-eval | |
| parent | 935ffa46a3a89a5f1662e5a4111ca0ed19566698 (diff) | |
| download | mruby-792f6ac6700469ddf9be8f87ca3376082f9af7f3.tar.gz mruby-792f6ac6700469ddf9be8f87ca3376082f9af7f3.zip | |
Adjustment of the current HEAD and bindings, and separation
Make changes to make `Binding` work.
At the same time, it separates `Binding#eval`, which depends on `mruby-eval`, from `mruby-binding-core`.
Diffstat (limited to 'mrbgems/mruby-eval')
| -rw-r--r-- | mrbgems/mruby-eval/src/eval.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index 89a2b3b10..8cc37904a 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -19,24 +19,37 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi { mrbc_context *cxt; struct mrb_parser_state *p; - struct RProc *proc, *scope; + struct RProc *proc; + const struct RProc *scope; struct REnv *e; mrb_callinfo *ci; /* callinfo of eval caller */ struct RClass *target_class = NULL; struct mrb_context *c = mrb->c; - mrb_bool is_binding = FALSE; if (!mrb_nil_p(binding)) { + mrb_value scope_obj; if (!mrb_class_defined(mrb, "Binding") || !mrb_obj_is_kind_of(mrb, binding, mrb_class_get(mrb, "Binding"))) { - mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected binding)", - mrb_obj_value(mrb_obj_class(mrb, binding))); + mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %C (expected binding)", + mrb_obj_class(mrb, binding)); + } + scope_obj = mrb_iv_get(mrb, binding, MRB_SYM(proc)); + mrb_assert(mrb_proc_p(scope_obj)); + scope = mrb_proc_ptr(scope_obj); + if (MRB_PROC_CFUNC_P(scope)) { + e = NULL; + } + else { + mrb_value env = mrb_iv_get(mrb, binding, MRB_SYM(env)); + mrb_assert(mrb_env_p(env)); + e = (struct REnv *)mrb_obj_ptr(env); + mrb_assert(e != NULL); } - scope = mrb_proc_ptr(mrb_iv_get(mrb, binding, mrb_intern_lit(mrb, "proc"))); - is_binding = TRUE; } else { - scope = c->ci[-1].proc; + ci = (c->ci > c->cibase) ? c->ci - 1 : c->cibase; + scope = ci->proc; + e = NULL; } cxt = mrbc_context_new(mrb); @@ -45,8 +58,7 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi mrbc_filename(mrb, cxt, file ? file : "(eval)"); cxt->capture_errors = TRUE; cxt->no_optimize = TRUE; - ci = (c->ci > c->cibase) ? c->ci - 1 : c->cibase; - cxt->upper = ci->proc && MRB_PROC_CFUNC_P(ci->proc) ? NULL : ci->proc; + cxt->upper = scope && MRB_PROC_CFUNC_P(scope) ? NULL : scope; p = mrb_parse_nstring(mrb, s, len, cxt); @@ -90,18 +102,19 @@ create_proc_from_string(mrb_state *mrb, const char *s, mrb_int len, mrb_value bi } if (scope) { target_class = MRB_PROC_TARGET_CLASS(scope); - } - if (scope && !MRB_PROC_CFUNC_P(scope)) { - if ((e = mrb_vm_ci_env(ci)) != NULL) { - /* do nothing, because e is assigned already */ - } - else { - e = mrb_env_new(mrb, c, ci, scope->body.irep->nlocals, ci->stack, target_class); - ci->u.env = e; + if (!MRB_PROC_CFUNC_P(scope)) { + if (e == NULL) { + /* when `binding` is nil */ + e = mrb_vm_ci_env(ci); + if (e == NULL) { + e = mrb_env_new(mrb, c, ci, ci->proc->body.irep->nlocals, ci->stack, target_class); + ci->u.env = e; + } + } + proc->e.env = e; + proc->flags |= MRB_PROC_ENVSET; + mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e); } - proc->e.env = e; - proc->flags |= MRB_PROC_ENVSET; - mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e); } proc->upper = scope; mrb_vm_ci_target_class_set(mrb->c->ci, target_class); @@ -146,7 +159,7 @@ f_eval(mrb_state *mrb, mrb_value self) proc = create_proc_from_string(mrb, s, len, binding, file, line); if (!mrb_nil_p(binding)) { - self = mrb_iv_get(mrb, binding, mrb_intern_lit(mrb, "recv")); + self = mrb_iv_get(mrb, binding, MRB_SYM(recv)); } mrb_assert(!MRB_PROC_CFUNC_P(proc)); return exec_irep(mrb, self, proc); |
