summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-binding
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems/mruby-binding')
-rw-r--r--mrbgems/mruby-binding/src/binding.c47
1 files changed, 22 insertions, 25 deletions
diff --git a/mrbgems/mruby-binding/src/binding.c b/mrbgems/mruby-binding/src/binding.c
index 67692e2b9..eb44f0e90 100644
--- a/mrbgems/mruby-binding/src/binding.c
+++ b/mrbgems/mruby-binding/src/binding.c
@@ -16,24 +16,6 @@ typedef mrb_bool mrb_parser_foreach_top_variable_func(mrb_state *mrb, mrb_sym sy
void mrb_parser_foreach_top_variable(mrb_state *mrb, struct mrb_parser_state *p, mrb_parser_foreach_top_variable_func *func, void *user);
static void
-insert_args(mrb_state *mrb, size_t offset, mrb_value obj)
-{
- mrb_callinfo *ci = mrb->c->ci;
- mrb_value *argp = ci->stack + 1 /* recv */;
-
- if (ci->argc < 0) {
- mrb_ary_splice(mrb, *argp, offset, 0, obj);
- }
- else {
- argp += offset;
- mrb_stack_extend(mrb, ci->argc + offset + 2 /* recv + block */);
- memmove(argp + 1 /* obj */, argp, sizeof(mrb_value) * (ci->argc - offset + 1 /* block */));
- *argp = obj;
- ci->argc++;
- }
-}
-
-static void
binding_eval_error_check(mrb_state *mrb, struct mrb_parser_state *p, const char *file)
{
if (!p) {
@@ -133,6 +115,8 @@ binding_eval_prepare(mrb_state *mrb, mrb_value binding)
mrb_value *argv;
mrb_get_args(mrb, "s|z*!", &d.expr, &d.exprlen, &d.file, &argv, &argc);
+ /* `eval` should take (string[, file, line]) */
+ if (argc > 3) mrb_argnum_error(mrb, argc, 1, 3);
mrb_bool error;
mrb_value ret = mrb_protect_error(mrb, binding_eval_prepare_body, &d, &error);
if (d.pstate) mrb_parser_free(d.pstate);
@@ -147,16 +131,29 @@ mrb_binding_eval(mrb_state *mrb, mrb_value binding)
struct RClass *c = mrb->kernel_module;
mrb_method_t m = mrb_method_search_vm(mrb, &c, MRB_SYM(eval));
+ mrb_callinfo *ci = mrb->c->ci;
+ int argc = ci->n;
+ mrb_value *argv = ci->stack + 1;
+ struct RProc *proc;
+
+ if (argc < 15) {
+ argv[0] = mrb_ary_new_from_values(mrb, argc, argv);
+ argv[1] = argv[argc]; /* copy block */
+ ci->n = 15;
+ }
if (MRB_METHOD_UNDEF_P(m)) {
- int argc = mrb->c->ci->argc;
- mrb_value *argv = mrb->c->ci->stack + 1;
- mrb_value args = (argc < 0) ? argv[0] : mrb_ary_new_from_values(mrb, argc, argv);
- mrb_method_missing(mrb, MRB_SYM(eval), binding, args);
+ mrb_method_missing(mrb, MRB_SYM(eval), binding, argv[0]);
}
- insert_args(mrb, 1, binding);
- struct RProc *proc = MRB_METHOD_PROC_P(m) ? MRB_METHOD_PROC(m) : mrb_proc_new_cfunc(mrb, MRB_METHOD_FUNC(m));
- mrb->c->ci->u.target_class = c;
+ mrb_ary_splice(mrb, argv[0], 1, 0, binding); /* insert binding as 2nd argument */
+ if (MRB_METHOD_FUNC_P(m)) {
+ proc = mrb_proc_new_cfunc(mrb, MRB_METHOD_FUNC(m));
+ MRB_PROC_SET_TARGET_CLASS(proc, c);
+ }
+ else {
+ proc = MRB_METHOD_PROC(m);
+ }
+ ci->u.target_class = c;
return mrb_exec_irep(mrb, binding, proc);
}