From 927615e1f072d8fff3d9b84660cdce15a239e36c Mon Sep 17 00:00:00 2001 From: dearblue Date: Mon, 22 Feb 2021 23:32:43 +0900 Subject: Added other methods for `Binding` - Added to `mruby-binding-core` - `Binding#local_variable_defined?` - `Binding#local_variable_get` - `Binding#local_variable_set` - `Binding#local_variables` - `Binding#receiver` - `Binding#source_location` - `Binding#inspect` - Added to `mruby-proc-binding` - `Proc#binding` The reason for separating `Proc#binding` is that core-mrbgems has a method that returns a closure object to minimize possible problems with being able to manipulate internal variables. By separating it as different mrbgem, each user can judge this problem and incorporate it arbitrarily. --- mrbgems/mruby-proc-binding/src/proc-binding.c | 52 +++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 mrbgems/mruby-proc-binding/src/proc-binding.c (limited to 'mrbgems/mruby-proc-binding/src') diff --git a/mrbgems/mruby-proc-binding/src/proc-binding.c b/mrbgems/mruby-proc-binding/src/proc-binding.c new file mode 100644 index 000000000..82d9d1d51 --- /dev/null +++ b/mrbgems/mruby-proc-binding/src/proc-binding.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include + +void mrb_proc_merge_lvar(mrb_state *mrb, mrb_irep *irep, struct REnv *env, int num, const mrb_sym *lv, const mrb_value *stack); + +/* provided by mruby-proc-ext */ +mrb_value mrb_proc_source_location(mrb_state *mrb, struct RProc *p); + +/* provided by mruby-binding-core */ +mrb_value mrb_binding_alloc(mrb_state *mrb); +struct RProc *mrb_binding_wrap_lvspace(mrb_state *mrb, const struct RProc *proc, struct REnv **envp); + +static mrb_value +mrb_proc_binding(mrb_state *mrb, mrb_value procval) +{ + mrb_value binding = mrb_binding_alloc(mrb); + const struct RProc *proc = mrb_proc_ptr(procval); + struct REnv *env; + + mrb_value receiver; + if (!proc || MRB_PROC_CFUNC_P(proc) || !proc->upper || MRB_PROC_CFUNC_P(proc->upper)) { + env = NULL; + proc = NULL; + receiver = mrb_nil_value(); + } + else { + env = MRB_PROC_ENV(proc); + mrb_assert(env); + proc = proc->upper; + receiver = MRB_ENV_LEN(env) > 0 ? env->stack[0] : mrb_nil_value(); + } + + proc = mrb_binding_wrap_lvspace(mrb, proc, &env); + mrb_iv_set(mrb, binding, MRB_SYM(proc), mrb_obj_value((void *)proc)); + mrb_iv_set(mrb, binding, MRB_SYM(recv), receiver); + mrb_iv_set(mrb, binding, MRB_SYM(env), mrb_obj_value(env)); + mrb_iv_set(mrb, binding, MRB_SYM(source_location), mrb_proc_source_location(mrb, mrb_proc_ptr(procval))); + return binding; +} + +void +mrb_mruby_proc_binding_gem_init(mrb_state *mrb) +{ + mrb_define_method(mrb, mrb->proc_class, "binding", mrb_proc_binding, MRB_ARGS_NONE()); +} + +void +mrb_mruby_proc_binding_gem_final(mrb_state *mrb) +{ +} -- cgit v1.2.3