[macruby-changes] [2960] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Nov 4 19:45:36 PST 2009


Revision: 2960
          http://trac.macosforge.org/projects/ruby/changeset/2960
Author:   lsansonetti at apple.com
Date:     2009-11-04 19:45:33 -0800 (Wed, 04 Nov 2009)
Log Message:
-----------
moved the removed_method code to the VM + fixed undef_method callbacks

Modified Paths:
--------------
    MacRuby/trunk/id.c
    MacRuby/trunk/id.h
    MacRuby/trunk/vm.cpp
    MacRuby/trunk/vm.h
    MacRuby/trunk/vm_method.c

Modified: MacRuby/trunk/id.c
===================================================================
--- MacRuby/trunk/id.c	2009-11-05 02:08:58 UTC (rev 2959)
+++ MacRuby/trunk/id.c	2009-11-05 03:45:33 UTC (rev 2960)
@@ -97,6 +97,10 @@
     selBackquote = sel_registerName("`:");
     selMethodAdded = sel_registerName("method_added:");
     selSingletonMethodAdded = sel_registerName("singleton_method_added:");
+    selMethodRemoved = sel_registerName("method_removed:");
+    selSingletonMethodRemoved = sel_registerName("singleton_method_removed:");
+    selMethodUndefined = sel_registerName("method_undefined:");
+    selSingletonMethodUndefined = sel_registerName("singleton_method_undefined:");
     selIsEqual = sel_registerName("isEqual:");
     selWrite = sel_registerName("write:");
     selInherited = sel_registerName("inherited:");

Modified: MacRuby/trunk/id.h
===================================================================
--- MacRuby/trunk/id.h	2009-11-05 02:08:58 UTC (rev 2959)
+++ MacRuby/trunk/id.h	2009-11-05 03:45:33 UTC (rev 2960)
@@ -106,6 +106,10 @@
 extern SEL selBackquote;
 extern SEL selMethodAdded;
 extern SEL selSingletonMethodAdded;
+extern SEL selMethodRemoved;
+extern SEL selSingletonMethodRemoved;
+extern SEL selMethodUndefined;
+extern SEL selSingletonMethodUndefined;
 extern SEL selIsEqual;
 extern SEL selWrite;
 extern SEL selInherited;

Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp	2009-11-05 02:08:58 UTC (rev 2959)
+++ MacRuby/trunk/vm.cpp	2009-11-05 03:45:33 UTC (rev 2960)
@@ -2311,16 +2311,14 @@
     ruby_methods.erase(iter);
 #endif
 
-#if 0
-    // TODO call undefined
+    VALUE sym = ID2SYM(rb_intern(sel_getName(sel)));
     if (RCLASS_SINGLETON(klass)) {
-	rb_funcall(rb_iv_get(klass, "__attached__"),
-		   singleton_undefined, 1, ID2SYM(id));
+	VALUE sk = rb_iv_get((VALUE)klass, "__attached__");
+	rb_vm_call(sk, selSingletonMethodUndefined, 1, &sym, false);
     }
     else {
-	rb_funcall(klass, undefined, 1, ID2SYM(id));
+	rb_vm_call((VALUE)klass, selMethodUndefined, 1, &sym, false);
     }
-#endif
 }
 
 extern "C"
@@ -2352,7 +2350,57 @@
     }
 }
 
+void
+RoxorCore::remove_method(Class klass, SEL sel)
+{
+#if ROXOR_VM_DEBUG
+    printf("remove %c[%s %s]\n",
+	    class_isMetaClass(klass) ? '+' : '-',
+	    class_getName(klass),
+	    sel_getName(sel));
+#endif
+
+    Method m = class_getInstanceMethod(klass, sel);
+    assert(m != NULL);
+    method_setImplementation(m, (IMP)rb_vm_removed_imp);
+    invalidate_respond_to_cache();
+
+    VALUE sym = ID2SYM(rb_intern(sel_getName(sel)));
+    if (RCLASS_SINGLETON(klass)) {
+	VALUE sk = rb_iv_get((VALUE)klass, "__attached__");
+	rb_vm_call(sk, selSingletonMethodRemoved, 1, &sym, false);
+    }
+    else {
+	rb_vm_call((VALUE)klass, selMethodRemoved, 1, &sym, false);
+    }
+}
+
 extern "C"
+void
+rb_vm_remove_method(Class klass, ID name)
+{
+    rb_vm_method_node_t *node = NULL;
+
+    if (!rb_vm_lookup_method2((Class)klass, name, NULL, NULL, &node)) {
+	rb_raise(rb_eNameError, "undefined method `%s' for %s `%s'",
+		rb_id2name(name),
+		TYPE(klass) == T_MODULE ? "module" : "class",
+		rb_class2name((VALUE)klass));
+    }
+    if (node == NULL) {
+	rb_raise(rb_eRuntimeError,
+		"cannot remove method `%s' because it is a native method",
+		rb_id2name(name));
+    }
+    if (node->klass != klass) {
+	rb_raise(rb_eNameError, "method `%s' not defined in %s",
+		rb_id2name(name), rb_class2name((VALUE)klass));
+    }
+
+    GET_CORE()->remove_method(klass, node->sel);
+}
+
+extern "C"
 VALUE
 rb_vm_masgn_get_elem_before_splat(VALUE ary, int offset)
 {

Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h	2009-11-05 02:08:58 UTC (rev 2959)
+++ MacRuby/trunk/vm.h	2009-11-05 03:45:33 UTC (rev 2960)
@@ -289,6 +289,7 @@
      || imp == (IMP)rb_vm_removed_imp)
 void rb_vm_define_attr(Class klass, const char *name, bool read, bool write);
 void rb_vm_undef_method(Class klass, ID name, bool must_exist);
+void rb_vm_remove_method(Class klass, ID name);
 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);
@@ -744,6 +745,7 @@
 	rb_vm_method_node_t *retype_method(Class klass,
 		rb_vm_method_node_t *node, const char *types);
 	void undef_method(Class klass, SEL sel);
+	void remove_method(Class klass, SEL sel);
 	bool resolve_methods(std::map<Class, rb_vm_method_source_t *> *map,
 		Class klass, SEL sel);
 	void copy_methods(Class from_class, Class to_class);

Modified: MacRuby/trunk/vm_method.c
===================================================================
--- MacRuby/trunk/vm_method.c	2009-11-05 02:08:58 UTC (rev 2959)
+++ MacRuby/trunk/vm_method.c	2009-11-05 03:45:33 UTC (rev 2960)
@@ -120,43 +120,14 @@
     if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
 	rb_raise(rb_eSecurityError, "Insecure: can't remove method");
     }
-    if (OBJ_FROZEN(klass))
+    if (OBJ_FROZEN(klass)) {
 	rb_error_frozen("class/module");
+    }
     if (mid == object_id || mid == __send__ || mid == idInitialize) {
 	rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
     }
-    SEL sel;
-    Method m;
 
-    sel = sel_registerName(rb_id2name(mid));
-    m = class_getInstanceMethod((Class)klass, sel);
-    if (m == NULL) {
-	char buf[100];
-	size_t len = strlen((char *)sel);
-	if (((char *)sel)[len - 1] != ':') {
-	    snprintf(buf, sizeof buf, "%s:", (char *)sel);
-	    sel = sel_registerName(buf);
-	    m = class_getInstanceMethod((Class)klass, sel);
-	}
-    }
-    if (m == NULL
-        || class_getInstanceMethod((Class)RCLASS_SUPER(klass), sel) == m) {
-	rb_name_error(mid, "method `%s' not defined in %s",
-		      rb_id2name(mid), rb_class2name(klass));
-    }
-    if (!rb_vm_is_ruby_method(m)) {
-	rb_warn("removing pure Objective-C method `%s' may cause serious " \
-		"problem", rb_id2name(mid));
-    }
-    method_setImplementation(m, (IMP)rb_vm_removed_imp);
-
-    if (RCLASS_SINGLETON(klass)) {
-	rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1,
-		   ID2SYM(mid));
-    }
-    else {
-	rb_funcall(klass, removed, 1, ID2SYM(mid));
-    }
+    rb_vm_remove_method((Class)klass, mid);
 }
 
 void
@@ -176,9 +147,7 @@
 static VALUE
 rb_mod_remove_method(VALUE mod, SEL sel, int argc, VALUE *argv)
 {
-    int i;
-
-    for (i = 0; i < argc; i++) {
+    for (int i = 0; i < argc; i++) {
 	remove_method(mod, rb_to_id(argv[i]));
     }
     return mod;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091104/e69226b1/attachment.html>


More information about the macruby-changes mailing list