summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-proc-binding/src/proc-binding.c
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems/mruby-proc-binding/src/proc-binding.c')
-rw-r--r--mrbgems/mruby-proc-binding/src/proc-binding.c52
1 files changed, 52 insertions, 0 deletions
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 <mruby.h>
+#include <mruby/presym.h>
+#include <mruby/proc.h>
+#include <mruby/variable.h>
+
+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)
+{
+}