[macruby-changes] [1734] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Thu Jun 4 17:04:00 PDT 2009


Revision: 1734
          http://trac.macosforge.org/projects/ruby/changeset/1734
Author:   lsansonetti at apple.com
Date:     2009-06-04 17:03:59 -0700 (Thu, 04 Jun 2009)
Log Message:
-----------
implemented method undefinition (still experimental but it seems to work)

Modified Paths:
--------------
    MacRuby/branches/experimental/class.c
    MacRuby/branches/experimental/vm.cpp
    MacRuby/branches/experimental/vm.h

Modified: MacRuby/branches/experimental/class.c
===================================================================
--- MacRuby/branches/experimental/class.c	2009-06-05 00:03:17 UTC (rev 1733)
+++ MacRuby/branches/experimental/class.c	2009-06-05 00:03:59 UTC (rev 1734)
@@ -944,7 +944,8 @@
     NODE *body = NEW_FBODY(NEW_METHOD(node, klass, noex), 0);
     rb_objc_retain(body);
 
-    rb_vm_define_method((Class)klass, name_to_sel(name, arity), (IMP)imp,				body, direct);
+    rb_vm_define_method((Class)klass, name_to_sel(name, arity), (IMP)imp,
+	    body, direct);
 }
 
 void
@@ -968,12 +969,6 @@
 }
 
 void
-rb_objc_undef_method(VALUE klass, const char *name)
-{
-    // TODO
-}
-
-void
 rb_define_method_id(VALUE klass, ID name, VALUE (*func)(ANYARGS), int argc)
 {
     rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC);
@@ -1000,8 +995,7 @@
 void
 rb_undef_method(VALUE klass, const char *name)
 {
-    rb_objc_undef_method(klass, name);
-    //rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);
+    rb_vm_undef_method((Class)klass, name, false);
 }
 
 #define SPECIAL_SINGLETON(x,c) do {\

Modified: MacRuby/branches/experimental/vm.cpp
===================================================================
--- MacRuby/branches/experimental/vm.cpp	2009-06-05 00:03:17 UTC (rev 1733)
+++ MacRuby/branches/experimental/vm.cpp	2009-06-05 00:03:59 UTC (rev 1734)
@@ -1682,6 +1682,38 @@
 }
 
 extern "C"
+void
+rb_vm_undef_method(Class klass, const char *name, bool must_exist)
+{
+    rb_vm_method_node_t *node = NULL;
+    SEL sel = sel_registerName(name);
+
+    if (!rb_vm_lookup_method((Class)klass, sel, NULL, &node)) {
+	if (must_exist) {
+	    rb_raise(rb_eNameError, "undefined method `%s' for %s `%s'",
+		    name, TYPE(klass) == T_MODULE ? "module" : "class",
+		    name);
+	}
+	assert(name[strlen(name) - 1] != ':');
+	class_replaceMethod((Class)klass, sel, NULL, "@@:");
+    }
+
+    if (node == NULL) {
+	if (must_exist) {
+	    rb_raise(rb_eRuntimeError,
+		    "cannot undefine method `%s' because it is a native method",
+		    name);
+	}
+	return; // Do nothing.
+    }
+
+    Method m = class_getInstanceMethod((Class)klass, node->sel);
+    assert(m != NULL);
+    class_replaceMethod((Class)klass, node->sel, NULL,
+	    method_getTypeEncoding(m));
+}
+
+extern "C"
 VALUE
 rb_vm_masgn_get_elem_before_splat(VALUE ary, int offset)
 {
@@ -1850,7 +1882,7 @@
     abort();
 }
 
-static /*inline*/ Method
+static inline Method
 rb_vm_super_lookup(VALUE klass, SEL sel, VALUE *klassp)
 {
     VALUE k, ary;
@@ -2199,6 +2231,12 @@
 	if (method != NULL) {
 recache2:
 	    IMP imp = method_getImplementation(method);
+
+	    if (imp == NULL) {
+		// Method was undefined.
+		return method_missing((VALUE)self, sel, argc, argv, opt);
+	    }
+
 	    rb_vm_method_node_t *node = GET_VM()->method_node_get(imp);
 
 	    if (node != NULL) {
@@ -3225,7 +3263,8 @@
 	    }
 	}
 	IMP obj_imp = method_getImplementation(m);
-	rb_vm_method_node_t *node = GET_VM()->method_node_get(obj_imp);
+	rb_vm_method_node_t *node = obj_imp == NULL
+	    ? NULL : GET_VM()->method_node_get(obj_imp);
 
 	if (node != NULL
 		&& (reject_pure_ruby_methods

Modified: MacRuby/branches/experimental/vm.h
===================================================================
--- MacRuby/branches/experimental/vm.h	2009-06-05 00:03:17 UTC (rev 1733)
+++ MacRuby/branches/experimental/vm.h	2009-06-05 00:03:59 UTC (rev 1734)
@@ -219,6 +219,7 @@
 	bool direct);
 void rb_vm_define_attr(Class klass, const char *name, bool read, bool write,
 	int noex);
+void rb_vm_undef_method(Class klass, const char *name, bool must_exist);
 void rb_vm_alias(VALUE klass, ID name, ID def);
 void rb_vm_copy_methods(Class from_class, Class to_class);
 VALUE rb_vm_call(VALUE self, SEL sel, int argc, const VALUE *args, bool super);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090604/01ba236d/attachment-0001.html>


More information about the macruby-changes mailing list