diff options
| author | Yukihiro Matsumoto <[email protected]> | 2012-06-20 15:26:10 +0900 |
|---|---|---|
| committer | Yukihiro Matsumoto <[email protected]> | 2012-06-20 15:26:10 +0900 |
| commit | e9231bca7a5fafa67e0a15aa657e727e46a1363a (patch) | |
| tree | 0da18886d14b2f7ca655c68a87b83a05c19fb1d5 /src | |
| parent | 88db589e7f965e5b16b82eca76f2e1febd82d124 (diff) | |
| download | mruby-e9231bca7a5fafa67e0a15aa657e727e46a1363a.tar.gz mruby-e9231bca7a5fafa67e0a15aa657e727e46a1363a.zip | |
allow lambda duplication
Diffstat (limited to 'src')
| -rw-r--r-- | src/proc.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/src/proc.c b/src/proc.c index 21c462493..c64bb88ac 100644 --- a/src/proc.c +++ b/src/proc.c @@ -56,20 +56,40 @@ mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func) return p; } +static inline void +proc_copy(struct RProc *a, struct RProc *b) +{ + a->body = b->body; + a->target_class = b->target_class; + a->env = b->env; +} + static mrb_value mrb_proc_initialize(mrb_state *mrb, mrb_value self) { mrb_value blk; mrb_get_args(mrb, "&", &blk); - if (!mrb_nil_p(blk)) { - *mrb_proc_ptr(self) = *mrb_proc_ptr(blk); - } - else { + if (mrb_nil_p(blk)) { /* Calling Proc.new without a block is not implemented yet */ mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block"); } + else { + proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(blk)); + } + return self; +} + +static mrb_value +mrb_proc_init_copy(mrb_state *mrb, mrb_value self) +{ + mrb_value proc; + mrb_get_args(mrb, "o", &proc); + if (mrb_type(proc) != MRB_TT_PROC) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc"); + } + proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(proc)); return self; } @@ -108,8 +128,10 @@ mrb_init_proc(mrb_state *mrb) call_irep->ilen = 1; mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class); + MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC); mrb_define_method(mrb, mrb->proc_class, "initialize", mrb_proc_initialize, ARGS_NONE()); + mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, ARGS_REQ(1)); m = mrb_proc_new(mrb, call_irep); mrb_define_method_raw(mrb, mrb->proc_class, mrb_intern(mrb, "call"), m); |
