From: Paul Brannan Date: 2008-02-26T00:54:13+09:00 Subject: [PATCH] Re: defining a method with attached data --jRHKVT23PllUwdXP Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Attached is a patch to add this feature directly into YARV without a hack. Usage: [pbrannan@zaphod md]$ cat md.c #include VALUE foo(VALUE self) { rb_p(rb_method_data()); } void Init_md() { rb_define_method_with_data(rb_mKernel, "foo", foo, 0, INT2NUM(42)); } [pbrannan@zaphod md]$ ruby1.9 -rmd -e foo 42 Paul --jRHKVT23PllUwdXP Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="method_data.patch" Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 15196) +++ include/ruby/ruby.h (working copy) @@ -700,9 +700,12 @@ #define RUBY_METHOD_FUNC(func) ((VALUE (*)(ANYARGS))func) void rb_define_method(VALUE,const char*,VALUE(*)(ANYARGS),int); +void rb_define_method_with_data(VALUE,const char*,VALUE(*)(ANYARGS),int,VALUE); void rb_define_module_function(VALUE,const char*,VALUE(*)(ANYARGS),int); void rb_define_global_function(const char*,VALUE(*)(ANYARGS),int); +VALUE rb_method_data(void); + void rb_undef_method(VALUE,const char*); void rb_define_alias(VALUE,const char*,const char*); void rb_define_attr(VALUE,const char*,int,int); Index: vm_core.h =================================================================== --- vm_core.h (revision 15196) +++ vm_core.h (working copy) @@ -326,6 +326,7 @@ VALUE method_class; /* cfp[11] saved in special case */ VALUE prof_time_self; /* cfp[12] */ VALUE prof_time_chld; /* cfp[13] */ + VALUE method_data; /* cfp[14] */ } rb_control_frame_t; typedef struct { Index: gc.c =================================================================== --- gc.c (revision 15196) +++ gc.c (working copy) @@ -920,6 +920,7 @@ case NODE_FCALL: case NODE_DEFN: case NODE_ARGS_AUX: + case NODE_CFUNC: ptr = (VALUE)obj->as.node.u3.node; goto again; @@ -985,7 +986,6 @@ case NODE_ZARRAY: /* - */ case NODE_ZSUPER: - case NODE_CFUNC: case NODE_VCALL: case NODE_GVAR: case NODE_LVAR: Index: class.c =================================================================== --- class.c (revision 15196) +++ class.c (working copy) @@ -13,6 +13,7 @@ #include "ruby/signal.h" #include "ruby/node.h" #include "ruby/st.h" +#include "vm_core.h" #include extern st_table *rb_class_tbl; @@ -767,6 +768,19 @@ } void +rb_define_method_with_data(VALUE klass, char const * name, VALUE (*func)(ANYARGS), int argc, VALUE data) +{ + rb_add_method(klass, rb_intern(name), NEW_NODE(NODE_CFUNC,func,argc,data), NOEX_PUBLIC); +} + +VALUE +rb_method_data(void) +{ + rb_control_frame_t *cfp = ruby_current_thread->cfp; + return cfp->method_data; +} + +void rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) { rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PROTECTED); Index: vm.c =================================================================== --- vm.c (revision 15196) +++ vm.c (working copy) @@ -453,6 +453,7 @@ cfp->method_id = id; cfp->method_class = klass; + cfp->method_data = body->nd_cval; val = call_cfunc(body->nd_cfnc, recv, body->nd_argc, argc, argv); Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 15196) +++ vm_insnhelper.c (working copy) @@ -366,6 +366,7 @@ cfp->method_id = id; cfp->method_class = klass; + cfp->method_data = mn->nd_cval; reg_cfp->sp -= num + 1; --jRHKVT23PllUwdXP--