Unverified Commit d26f03b4 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto Committed by GitHub

Merge pull request #4358 from shuujii/use-mrb_proc_arity-instead-of-Proc-arity-call-in-Method-arity

Use `mrb_proc_arity` instead of `Proc#arity` call in `Method#arity`
parents dd1c100b ed41bbb1
......@@ -86,6 +86,7 @@ struct RProc *mrb_closure_new(mrb_state*, mrb_irep*);
MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t);
MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals);
void mrb_proc_copy(struct RProc *a, struct RProc *b);
mrb_int mrb_proc_arity(const struct RProc *p);
/* implementation of #send method */
mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
......
......@@ -212,19 +212,8 @@ static mrb_value
method_arity(mrb_state *mrb, mrb_value self)
{
mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "proc"));
struct RProc *rproc;
struct RClass *orig;
mrb_value ret;
if (mrb_nil_p(proc))
return mrb_fixnum_value(-1);
rproc = mrb_proc_ptr(proc);
orig = rproc->c;
rproc->c = mrb->proc_class;
ret = mrb_funcall(mrb, proc, "arity", 0);
rproc->c = orig;
return ret;
mrb_int arity = mrb_nil_p(proc) ? -1 : mrb_proc_arity(mrb_proc_ptr(proc));
return mrb_fixnum_value(arity);
}
static mrb_value
......
......@@ -221,38 +221,9 @@ mrb_proc_cfunc_p(struct RProc *p)
/* 15.2.17.4.2 */
static mrb_value
mrb_proc_arity(mrb_state *mrb, mrb_value self)
proc_arity(mrb_state *mrb, mrb_value self)
{
struct RProc *p = mrb_proc_ptr(self);
struct mrb_irep *irep;
mrb_code *pc;
mrb_aspec aspec;
int ma, op, ra, pa, arity;
if (MRB_PROC_CFUNC_P(p)) {
/* TODO cfunc aspec not implemented yet */
return mrb_fixnum_value(-1);
}
irep = p->body.irep;
if (!irep) {
return mrb_fixnum_value(0);
}
pc = irep->iseq;
/* arity is depend on OP_ENTER */
if (*pc != OP_ENTER) {
return mrb_fixnum_value(0);
}
aspec = PEEK_W(pc+1);
ma = MRB_ASPEC_REQ(aspec);
op = MRB_ASPEC_OPT(aspec);
ra = MRB_ASPEC_REST(aspec);
pa = MRB_ASPEC_POST(aspec);
arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa;
return mrb_fixnum_value(arity);
return mrb_fixnum_value(mrb_proc_arity(mrb_proc_ptr(self)));
}
/* 15.3.1.2.6 */
......@@ -287,6 +258,40 @@ proc_lambda(mrb_state *mrb, mrb_value self)
return blk;
}
mrb_int
mrb_proc_arity(const struct RProc *p)
{
struct mrb_irep *irep;
mrb_code *pc;
mrb_aspec aspec;
int ma, op, ra, pa, arity;
if (MRB_PROC_CFUNC_P(p)) {
/* TODO cfunc aspec not implemented yet */
return -1;
}
irep = p->body.irep;
if (!irep) {
return 0;
}
pc = irep->iseq;
/* arity is depend on OP_ENTER */
if (*pc != OP_ENTER) {
return 0;
}
aspec = PEEK_W(pc+1);
ma = MRB_ASPEC_REQ(aspec);
op = MRB_ASPEC_OPT(aspec);
ra = MRB_ASPEC_REST(aspec);
pa = MRB_ASPEC_POST(aspec);
arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa;
return arity;
}
void
mrb_init_proc(mrb_state *mrb)
{
......@@ -303,7 +308,7 @@ mrb_init_proc(mrb_state *mrb)
mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1));
mrb_define_method(mrb, mrb->proc_class, "arity", mrb_proc_arity, MRB_ARGS_NONE());
mrb_define_method(mrb, mrb->proc_class, "arity", proc_arity, MRB_ARGS_NONE());
p = mrb_proc_new(mrb, call_irep);
MRB_METHOD_FROM_PROC(m, p);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment