diff options
Diffstat (limited to 'src/proc.c')
| -rw-r--r-- | src/proc.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/proc.c b/src/proc.c new file mode 100644 index 000000000..aae9b1932 --- /dev/null +++ b/src/proc.c @@ -0,0 +1,92 @@ +#include "mruby.h" +#include "mruby/proc.h" +#include "mruby/array.h" +#include "mruby/class.h" +#include "opcode.h" + +struct RProc * +mrb_proc_new(mrb_state *mrb, mrb_irep *irep) +{ + struct RProc *p; + + p = mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); + p->body.irep = irep; + p->target_class = (mrb->ci) ? mrb->ci->target_class : 0; + p->env = 0; + + return p; +} + +struct RProc * +mrb_closure_new(mrb_state *mrb, mrb_irep *irep) +{ + struct RProc *p = mrb_proc_new(mrb, irep); + struct REnv *e; + + if (!mrb->ci->env) { + e = mrb_obj_alloc(mrb, MRB_TT_ENV, mrb->ci->proc->env); + e->flags= (unsigned int)irep->nlocals; + e->mid = mrb->ci->mid; + e->cioff = mrb->ci - mrb->cibase; + e->stack = mrb->stack; + mrb->ci->env = e; + } + else { + e = mrb->ci->env; + } + p->env = e; + return p; +} + +struct RProc * +mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func) +{ + struct RProc *p; + + p = mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); + p->body.func = func; + p->flags |= MRB_PROC_CFUNC; + + return p; +} + +int +mrb_proc_cfunc_p(struct RProc *p) +{ + return MRB_PROC_CFUNC_P(p); +} + +mrb_value +mrb_proc_call_cfunc(mrb_state *mrb, struct RProc *p, mrb_value self) +{ + return (p->body.func)(mrb, self); +} + +mrb_code* +mrb_proc_iseq(mrb_state *mrb, struct RProc *p) +{ + return p->body.irep->iseq; +} + +void +mrb_init_proc(mrb_state *mrb) +{ + struct RProc *m; + mrb_code *call_iseq = mrb_malloc(mrb, sizeof(mrb_code)); + mrb_irep *call_irep = mrb_calloc(mrb, sizeof(mrb_irep), 1); + + if ( call_iseq == NULL || call_irep == NULL ) + return; + + *call_iseq = MKOP_A(OP_CALL, 0); + call_irep->idx = -1; + call_irep->flags = MRB_IREP_NOFREE; + call_irep->iseq = call_iseq; + call_irep->ilen = 1; + + mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class); + + m = mrb_proc_new(mrb, call_irep); + mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "call"), m); + mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "[]"), m); +} |
