/*
* call-seq:
* class.add_method(id, node or iseq, noex) #=> nil
*
* Adds the method as an instance method to the given class.
*
* To add a singleton method to a class, add the method to its singleton
* class.
*/
static VALUE module_add_method(VALUE klass, VALUE id, VALUE node, VALUE noex)
{
NODE * n = 0;
if(ruby_safe_level >= 2)
{
/* adding a method with the wrong node type can cause a crash */
rb_raise(rb_eSecurityError, "Insecure: can't add method");
}
#ifdef RUBY_HAS_YARV
if(rb_obj_is_kind_of(node, rb_cISeq))
{
rb_iseq_t *iseqdat = iseq_check(node);
/* TODO: any restrictions on what kinds of iseqs we can add here?
*/
set_cref_stack(iseqdat, klass, noex);
iseqdat->klass = klass;
iseqdat->defined_method_id = SYM2ID(id);
n = NEW_METHOD(iseqdat->self, klass, NUM2INT(noex));
goto add_node;
}
#endif
if(!rb_obj_is_kind_of(node, rb_cNode))
{
rb_raise(
rb_eTypeError,
"Expected Node for 2nd parameter, got %s",
rb_class2name(CLASS_OF(n)));
}
Data_Get_Struct(node, NODE, n);
#ifdef RUBY_HAS_YARV
if(nd_type(n) != NODE_METHOD)
{
rb_raise(
rb_eTypeError,
"Expected METHOD node, got %s",
rb_class2name(CLASS_OF(n)));
}
rb_iseq_t *iseqdat = iseq_check((VALUE)n->nd_body);
set_cref_stack(iseqdat, klass, noex);
iseqdat->klass = klass;
iseqdat->defined_method_id = SYM2ID(id);
n = NEW_METHOD(iseqdat->self, klass, NUM2INT(noex));
add_node:
#endif
/* TODO: if noex is NOEX_MODFUNC, add this method as a module function
* (that is, both as an instance and singleton method)
*/
rb_add_method(klass, SYM2ID(id), n, NUM2INT(noex));
return Qnil;
}