On Tue, Feb 26, 2008 at 03:11:05AM +0900, Paul Brannan wrote:
> On Tue, Feb 26, 2008 at 12:54:13AM +0900, Paul Brannan wrote:
> > Attached is a patch to add this feature directly into YARV without a
> > hack.
> 
> And another one for the Ruby 1.8 branch.

Oops, forgot the attachment.

Paul

Index: class.c
===================================================================
--- class.c	(revision 15603)
+++ class.c	(working copy)
@@ -14,6 +14,7 @@
 #include "rubysig.h"
 #include "node.h"
 #include "st.h"
+#include "env.h"
 #include <ctype.h>
 
 extern st_table *rb_class_tbl;
@@ -817,6 +818,27 @@
 }
 
 void
+rb_define_method_with_data(klass, name, func, argc, data)
+    VALUE klass;
+    const char *name;
+    VALUE (*func)();
+    int argc;
+    VALUE data;
+{
+    ID id = rb_intern(name);
+    int ex = NOEX_PUBLIC;
+
+
+    rb_add_method(klass, id, NEW_NODE(NODE_CFUNC, func, argc, data), ex);
+}
+
+VALUE
+rb_method_data()
+{
+    return ruby_frame->method_data;
+}
+
+void
 rb_define_protected_method(klass, name, func, argc)
     VALUE klass;
     const char *name;
Index: ruby.h
===================================================================
--- ruby.h	(revision 15603)
+++ ruby.h	(working copy)
@@ -524,9 +524,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: env.h
===================================================================
--- env.h	(revision 15603)
+++ env.h	(working copy)
@@ -25,6 +25,7 @@
     int iter;
     int flags;
     unsigned long uniq;
+    VALUE method_data;
 } *ruby_frame;
 
 void rb_gc_mark_frame _((struct FRAME *));
Index: eval.c
===================================================================
--- eval.c	(revision 15603)
+++ eval.c	(working copy)
@@ -5855,6 +5855,7 @@
 		if (state) JUMP_TAG(state);
 	    }
 	    else {
+		ruby_frame->method_data = body->nd_cval;
 		result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);
 	    }
 	}
Index: gc.c
===================================================================
--- gc.c	(revision 15603)
+++ gc.c	(working copy)
@@ -801,6 +801,7 @@
 	  case NODE_FCALL:
 	  case NODE_DEFN:
 	  case NODE_NEWLINE:
+	  case NODE_CFUNC:
 	    ptr = (VALUE)obj->as.node.u3.node;
 	    goto again;
 
@@ -866,7 +867,6 @@
 
 	  case NODE_ZARRAY:	/* - */
 	  case NODE_ZSUPER:
-	  case NODE_CFUNC:
 	  case NODE_VCALL:
 	  case NODE_GVAR:
 	  case NODE_LVAR: