1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* eval.c (rb_proc_arity, rb_node_arity, rb_mod_method_arity,

rb_obj_method_arity): new functions to obtain method arity.
  [ruby-dev:25143]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7583 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2004-12-16 15:01:49 +00:00
parent 326ebac3db
commit 7910c3fd56
3 changed files with 106 additions and 62 deletions

164
eval.c
View file

@ -4581,7 +4581,7 @@ break_jump(retval)
}
static VALUE bmcall _((VALUE, VALUE));
static VALUE method_arity _((VALUE));
static int method_arity _((VALUE));
static VALUE
kk()
@ -8275,6 +8275,45 @@ proc_call(proc, args)
return proc_invoke(proc, args, Qundef, 0);
}
int
rb_proc_arity(proc)
VALUE proc;
{
struct BLOCK *data;
NODE *var, *list;
int n;
Data_Get_Struct(proc, struct BLOCK, data);
var = data->var;
if (var == 0) {
if (data->body && nd_type(data->body) == NODE_IFUNC &&
data->body->nd_cfnc == bmcall) {
return method_arity(data->body->nd_tval);
}
return 0;
}
if (var == (NODE*)1) return 0;
if (var == (NODE*)2) return 0;
if (nd_type(var) == NODE_BLOCK_ARG) {
var = var->nd_args;
if (var == (NODE*)1) return 0;
if (var == (NODE*)2) return 0;
}
switch (nd_type(var)) {
default:
return 1;
case NODE_MASGN:
list = var->nd_head;
n = 0;
while (list) {
n++;
list = list->nd_next;
}
if (var->nd_args) return -n-1;
return n;
}
}
/*
* call-seq:
* prc.arity -> fixnum
@ -8299,39 +8338,8 @@ static VALUE
proc_arity(proc)
VALUE proc;
{
struct BLOCK *data;
NODE *var, *list;
int n;
Data_Get_Struct(proc, struct BLOCK, data);
var = data->var;
if (var == 0) {
if (data->body && nd_type(data->body) == NODE_IFUNC &&
data->body->nd_cfnc == bmcall) {
return method_arity(data->body->nd_tval);
}
return INT2FIX(0);
}
if (var == (NODE*)1) return INT2FIX(0);
if (var == (NODE*)2) return INT2FIX(0);
if (nd_type(var) == NODE_BLOCK_ARG) {
var = var->nd_args;
if (var == (NODE*)1) return INT2FIX(0);
if (var == (NODE*)2) return INT2FIX(0);
}
switch (nd_type(var)) {
default:
return INT2FIX(1);
case NODE_MASGN:
list = var->nd_head;
n = 0;
while (list) {
n++;
list = list->nd_next;
}
if (var->nd_args) return INT2FIX(-n-1);
return INT2FIX(n);
}
int arity = rb_proc_arity(proc);
return INT2FIX(arity);
}
/*
@ -8612,7 +8620,7 @@ mnew(klass, obj, id, mklass)
rklass = RCLASS(rklass)->super;
}
if (TYPE(klass) == T_ICLASS) klass = RBASIC(klass)->klass;
method = Data_Make_Struct(mklass, struct METHOD, bm_mark, free, data);
method = Data_Make_Struct(mklass, struct METHOD, bm_mark, -1, data);
data->klass = klass;
data->recv = obj;
data->id = id;
@ -8986,6 +8994,38 @@ umethod_bind(method, recv)
return method;
}
int
rb_node_arity(body)
NODE *body;
{
int n;
switch (nd_type(body)) {
case NODE_CFUNC:
if (body->nd_argc < 0) return -1;
return body->nd_argc;
case NODE_ZSUPER:
return -1;
case NODE_ATTRSET:
return 1;
case NODE_IVAR:
return 0;
case NODE_BMETHOD:
return rb_proc_arity(body->nd_cval);
case NODE_SCOPE:
body = body->nd_next; /* skip NODE_SCOPE */
if (nd_type(body) == NODE_BLOCK)
body = body->nd_head;
if (!body) return 0;
n = body->nd_cnt;
if (body->nd_opt || body->nd_rest != -1)
n = -n-1;
return n;
default:
rb_raise(rb_eArgError, "invalid node 0x%x", nd_type(body));
}
}
/*
* call-seq:
* meth.arity => fixnum
@ -9020,38 +9060,38 @@ umethod_bind(method, recv)
*/
static VALUE
method_arity_m(method)
VALUE method;
{
int n = method_arity(method);
return INT2FIX(n);
}
static int
method_arity(method)
VALUE method;
{
struct METHOD *data;
NODE *body;
int n;
Data_Get_Struct(method, struct METHOD, data);
return rb_node_arity(data->body);
}
body = data->body;
switch (nd_type(body)) {
case NODE_CFUNC:
if (body->nd_argc < 0) return INT2FIX(-1);
return INT2FIX(body->nd_argc);
case NODE_ZSUPER:
return INT2FIX(-1);
case NODE_ATTRSET:
return INT2FIX(1);
case NODE_IVAR:
return INT2FIX(0);
case NODE_BMETHOD:
return proc_arity(body->nd_cval);
default:
body = body->nd_next; /* skip NODE_SCOPE */
if (nd_type(body) == NODE_BLOCK)
body = body->nd_head;
if (!body) return INT2FIX(0);
n = body->nd_cnt;
if (body->nd_opt || body->nd_rest != -1)
n = -n-1;
return INT2FIX(n);
}
int
rb_mod_method_arity(mod, id)
VALUE mod;
ID id;
{
NODE *node = rb_method_node(mod, id);
return rb_node_arity(node);
}
int
rb_obj_method_arity(obj, id)
VALUE obj;
ID id;
{
return rb_mod_method_arity(CLASS_OF(obj), id);
}
/*
@ -9360,7 +9400,7 @@ Init_Proc()
rb_define_method(rb_cMethod, "clone", method_clone, 0);
rb_define_method(rb_cMethod, "call", method_call, -1);
rb_define_method(rb_cMethod, "[]", method_call, -1);
rb_define_method(rb_cMethod, "arity", method_arity, 0);
rb_define_method(rb_cMethod, "arity", method_arity_m, 0);
rb_define_method(rb_cMethod, "inspect", method_inspect, 0);
rb_define_method(rb_cMethod, "to_s", method_inspect, 0);
rb_define_method(rb_cMethod, "to_proc", method_proc, 0);
@ -9374,7 +9414,7 @@ Init_Proc()
rb_define_method(rb_cUnboundMethod, "eql?", method_eq, 1);
rb_define_method(rb_cUnboundMethod, "hash", method_hash, 0);
rb_define_method(rb_cUnboundMethod, "clone", method_clone, 0);
rb_define_method(rb_cUnboundMethod, "arity", method_arity, 0);
rb_define_method(rb_cUnboundMethod, "arity", method_arity_m, 0);
rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0);
rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0);
rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);

View file

@ -190,6 +190,9 @@ VALUE rb_class_new_instance _((int, VALUE*, VALUE));
VALUE rb_block_proc _((void));
VALUE rb_f_lambda _((void));
VALUE rb_proc_new _((VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE));
int rb_proc_arity _((VALUE));
int rb_mod_method_arity _((VALUE, ID));
int rb_obj_method_arity _((VALUE, ID));
VALUE rb_protect _((VALUE (*)(VALUE), VALUE, int*));
void rb_set_end_proc _((void (*)(VALUE), VALUE));
void rb_mark_end_proc _((void));

1
node.h
View file

@ -357,6 +357,7 @@ void rb_add_method _((VALUE, ID, NODE *, int));
NODE *rb_node_newnode _((enum node_type,VALUE,VALUE,VALUE));
NODE* rb_method_node _((VALUE klass, ID id));
int rb_node_arity _((NODE* node));
struct global_entry *rb_global_entry _((ID));
VALUE rb_gvar_get _((struct global_entry *));