[macruby-changes] [382] MacRuby/branches/lrz_unstable

source_changes at macosforge.org source_changes at macosforge.org
Tue Jul 29 19:27:07 PDT 2008


Revision: 382
          http://trac.macosforge.org/projects/ruby/changeset/382
Author:   lsansonetti at apple.com
Date:     2008-07-29 19:27:07 -0700 (Tue, 29 Jul 2008)
Log Message:
-----------
new dispatcher, work still in progress

Modified Paths:
--------------
    MacRuby/branches/lrz_unstable/Rakefile
    MacRuby/branches/lrz_unstable/array.c
    MacRuby/branches/lrz_unstable/class.c
    MacRuby/branches/lrz_unstable/compile.c
    MacRuby/branches/lrz_unstable/debug.h
    MacRuby/branches/lrz_unstable/eval.c
    MacRuby/branches/lrz_unstable/gc.c
    MacRuby/branches/lrz_unstable/hash.c
    MacRuby/branches/lrz_unstable/id.c
    MacRuby/branches/lrz_unstable/id.h
    MacRuby/branches/lrz_unstable/include/ruby/intern.h
    MacRuby/branches/lrz_unstable/include/ruby/node.h
    MacRuby/branches/lrz_unstable/include/ruby/ruby.h
    MacRuby/branches/lrz_unstable/insnhelper.h
    MacRuby/branches/lrz_unstable/insns.def
    MacRuby/branches/lrz_unstable/io.c
    MacRuby/branches/lrz_unstable/marshal.c
    MacRuby/branches/lrz_unstable/numeric.c
    MacRuby/branches/lrz_unstable/objc.m
    MacRuby/branches/lrz_unstable/object.c
    MacRuby/branches/lrz_unstable/parse.y
    MacRuby/branches/lrz_unstable/proc.c
    MacRuby/branches/lrz_unstable/string.c
    MacRuby/branches/lrz_unstable/thread.c
    MacRuby/branches/lrz_unstable/variable.c
    MacRuby/branches/lrz_unstable/vm.c
    MacRuby/branches/lrz_unstable/vm_eval.c
    MacRuby/branches/lrz_unstable/vm_insnhelper.c
    MacRuby/branches/lrz_unstable/vm_method.c

Modified: MacRuby/branches/lrz_unstable/Rakefile
===================================================================
--- MacRuby/branches/lrz_unstable/Rakefile	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/Rakefile	2008-07-30 02:27:07 UTC (rev 382)
@@ -21,6 +21,7 @@
 NO_WARN_BUILD = !do_option('allow_build_warnings', false)
 BUILD_AS_EMBEDDABLE = do_option('build_as_embeddable', false)
 ENABLE_STATIC_LIBRARY = do_option('enable_static_library', 'no') { 'yes' }
+ENABLE_DEBUG_LOGGING = do_option('enable_debug_logging', false)
 
 # TODO: we should find a way to document these options in rake's --help
 
@@ -208,31 +209,28 @@
 desc "Create config.h"
 task :config_h do
   config_h = 'include/ruby/config.h'
-  if !File.exist?(config_h) \
-  or File.mtime(config_h) < File.mtime(config_h + '.in') \
-  or File.mtime(config_h) < File.mtime(__FILE__)
-    new_config_h = File.read(config_h + '.in') << "\n"
-    flag = ['/System/Library/Frameworks', '/Library/Frameworks'].any? do |p|
-      File.exist?(File.join(p, 'BridgeSupport.framework'))
-    end 
-    new_config_h << "#define HAVE_BRIDGESUPPORT_FRAMEWORK #{flag ? 1 : 0}\n"
-    flag = File.exist?('/usr/include/auto_zone.h')
-    new_config_h << "#define HAVE_AUTO_ZONE_H #{flag ? 1 : 0}\n"
-    new_config_h << "#define RUBY_PLATFORM \"#{NEW_RUBY_PLATFORM}\"\n"
-    new_config_h << "#define RUBY_LIB \"#{RUBY_LIB}\"\n"
-    new_config_h << "#define RUBY_ARCHLIB \"#{RUBY_ARCHLIB}\"\n"
-    new_config_h << "#define RUBY_SITE_LIB \"#{RUBY_SITE_LIB}\"\n"
-    new_config_h << "#define RUBY_SITE_LIB2 \"#{RUBY_SITE_LIB2}\"\n"
-    new_config_h << "#define RUBY_SITE_ARCHLIB \"#{RUBY_SITE_ARCHLIB}\"\n"
-    new_config_h << "#define RUBY_VENDOR_LIB \"#{RUBY_VENDOR_LIB}\"\n"
-    new_config_h << "#define RUBY_VENDOR_LIB2 \"#{RUBY_VENDOR_LIB2}\"\n"
-    new_config_h << "#define RUBY_VENDOR_ARCHLIB \"#{RUBY_VENDOR_ARCHLIB}\"\n"
-    if !File.exist?(config_h) or File.read(config_h) != new_config_h
-      File.open(config_h, 'w') { |io| io.print new_config_h }
-      ext_dir = ".ext/include/#{NEW_RUBY_PLATFORM}/ruby"
-      mkdir_p(ext_dir)
-      cp(config_h, ext_dir)
-    end
+  new_config_h = File.read(config_h + '.in') << "\n"
+  flag = ['/System/Library/Frameworks', '/Library/Frameworks'].any? do |p|
+    File.exist?(File.join(p, 'BridgeSupport.framework'))
+  end 
+  new_config_h << "#define HAVE_BRIDGESUPPORT_FRAMEWORK #{flag ? 1 : 0}\n"
+  flag = File.exist?('/usr/include/auto_zone.h')
+  new_config_h << "#define HAVE_AUTO_ZONE_H #{flag ? 1 : 0}\n"
+  new_config_h << "#define ENABLE_DEBUG_LOGGING 1\n" if ENABLE_DEBUG_LOGGING
+  new_config_h << "#define RUBY_PLATFORM \"#{NEW_RUBY_PLATFORM}\"\n"
+  new_config_h << "#define RUBY_LIB \"#{RUBY_LIB}\"\n"
+  new_config_h << "#define RUBY_ARCHLIB \"#{RUBY_ARCHLIB}\"\n"
+  new_config_h << "#define RUBY_SITE_LIB \"#{RUBY_SITE_LIB}\"\n"
+  new_config_h << "#define RUBY_SITE_LIB2 \"#{RUBY_SITE_LIB2}\"\n"
+  new_config_h << "#define RUBY_SITE_ARCHLIB \"#{RUBY_SITE_ARCHLIB}\"\n"
+  new_config_h << "#define RUBY_VENDOR_LIB \"#{RUBY_VENDOR_LIB}\"\n"
+  new_config_h << "#define RUBY_VENDOR_LIB2 \"#{RUBY_VENDOR_LIB2}\"\n"
+  new_config_h << "#define RUBY_VENDOR_ARCHLIB \"#{RUBY_VENDOR_ARCHLIB}\"\n"
+  if !File.exist?(config_h) or File.read(config_h) != new_config_h
+    File.open(config_h, 'w') { |io| io.print new_config_h }
+    ext_dir = ".ext/include/#{NEW_RUBY_PLATFORM}/ruby"
+    mkdir_p(ext_dir)
+    cp(config_h, ext_dir)
   end
 end
 
@@ -261,7 +259,7 @@
     cp('lex.c.blt', 'lex.c')
   end
   inc_to_gen = %w{opt_sc.inc optinsn.inc optunifs.inc insns.inc insns_info.inc vmtc.inc vm.inc}.select { |inc| !File.exist?(inc) or File.mtime("template/#{inc}.tmpl") > File.mtime(inc) }
-  unless inc_to_gen.empty?
+  if !inc_to_gen.empty? or File.mtime('insns.def') > File.mtime('vm.inc')
     sh("/usr/bin/ruby -Ks tool/insns2vm.rb #{inc_to_gen.join(' ')}")
   end
   if !File.exist?('node_name.inc') or File.mtime('include/ruby/node.h') > File.mtime('node_name.inc')

Modified: MacRuby/branches/lrz_unstable/array.c
===================================================================
--- MacRuby/branches/lrz_unstable/array.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/array.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -191,7 +191,7 @@
 
     ary = (VALUE)CFArrayCreateMutable(NULL, 0, &cb);
     if (klass != 0 && klass != rb_cArray && klass != rb_cArrayRuby)
-        *(Class *)ary = RCLASS_OCID(klass);
+        *(Class *)ary = (Class)klass;
 
     CFMakeCollectable((CFTypeRef)ary);
     rb_gc_malloc_increase(sizeof(void *));
@@ -3992,11 +3992,9 @@
 
 #if WITH_OBJC
 
-#define NSCFARRAY() RCLASS_OCID(rb_cCFArray)
-
 #define PREPARE_RCV(x) \
     Class old = *(Class *)x; \
-    *(Class *)x = NSCFARRAY();
+    *(Class *)x = (Class)rb_cCFArray;
 
 #define RESTORE_RCV(x) \
       *(Class *)x = old;
@@ -4004,7 +4002,7 @@
 bool
 rb_objc_ary_is_pure(VALUE ary)
 {
-    return *(Class *)ary == NSCFARRAY();
+    return *(Class *)ary == (Class)rb_cCFArray;
 }
 
 static CFIndex
@@ -4135,7 +4133,6 @@
     rb_cArray = rb_objc_import_class((Class)objc_getClass("NSArray"));
     rb_cArrayRuby = 
 	rb_objc_import_class((Class)objc_getClass("NSMutableArray"));
-    FL_UNSET(rb_cArrayRuby, RCLASS_OBJC_IMPORTED);
     rb_const_set(rb_cObject, rb_intern("Array"), rb_cArrayRuby);
 #else
     rb_cArray  = rb_define_class("Array", rb_cObject);

Modified: MacRuby/branches/lrz_unstable/class.c
===================================================================
--- MacRuby/branches/lrz_unstable/class.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/class.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -13,6 +13,8 @@
 #include "ruby/signal.h"
 #include "ruby/node.h"
 #include "ruby/st.h"
+#include "debug.h"
+#include "id.h"
 #include <ctype.h>
 
 extern st_table *rb_class_tbl;
@@ -20,37 +22,19 @@
 #define VISI(x) ((x)&NOEX_MASK)
 #define VISI_CHECK(x,f) (VISI(x) == (f))
 
-static VALUE
-class_init(VALUE obj)
-{
-    GC_WB(&RCLASS(obj)->ptr, ALLOC(rb_classext_t));
-    RCLASS_IV_TBL(obj) = 0;
-    RCLASS_M_TBL(obj) = 0;
-    RCLASS_SUPER(obj) = 0;
-    RCLASS_IV_INDEX_TBL(obj) = 0;
-    return obj;
-}
-
 #if WITH_OBJC
 
-extern st_table *rb_objc_class_tbl;
-
 VALUE
 rb_objc_import_class(Class ocklass)
 {
+#if 0
     VALUE rbklass;
     ID nameid;
     VALUE super;
 
     assert(ocklass != NULL);
     assert(class_isMetaClass(ocklass) == 0);
-    assert(rb_objc_class_tbl != NULL);
 
-    if (st_lookup(rb_objc_class_tbl, (st_data_t)ocklass, (st_data_t *)&rbklass))
-	return rbklass;
-
-//printf("import %s (%p)\n", class_getName(ocklass), ocklass);
-
     {
 	NEWOBJ(obj, struct RClass);
 	OBJSETUP(obj, rb_cClass, T_CLASS);
@@ -60,8 +44,6 @@
     RBASIC(rbklass)->isa = ocklass->isa;
     RCLASS(rbklass)->ocklass = ocklass;
 
-    class_init(rbklass);
-
     RCLASS_M_TBL(rbklass) = st_init_numtable();
 
     nameid = rb_intern(class_getName(ocklass));
@@ -72,7 +54,6 @@
 
     /* FIXME do we need to maintain rb_class_tbl anymore? */
     st_insert(rb_class_tbl, (st_data_t)nameid, (st_data_t)rbklass);
-    st_insert(rb_objc_class_tbl, (st_data_t)ocklass, (st_data_t)rbklass);
 
     ocklass = class_getSuperclass(ocklass);
 
@@ -99,6 +80,8 @@
 	rb_make_metaclass(rbklass, RBASIC(super)->klass);
 
     return rbklass;
+#endif
+    return (VALUE)ocklass;
 }
 
 void rb_objc_install_array_primitives(Class);
@@ -110,15 +93,15 @@
 {
     if (rb_cArray != 0 && rb_cHash != 0 && rb_cString != 0) {
 	do {
-	    if (ocsuper == RCLASS_OCID(rb_cArray)) {
+	    if (ocsuper == (Class)rb_cArray) {
 		rb_objc_install_array_primitives(ocklass);
 		return true;
 	    }
-	    if (ocsuper == RCLASS_OCID(rb_cHash)) {
+	    if (ocsuper == (Class)rb_cHash) {
 		rb_objc_install_hash_primitives(ocklass);
 		return true;
 	    }
-	    if (ocsuper == RCLASS_OCID(rb_cString)) {
+	    if (ocsuper == (Class)rb_cString) {
 		rb_objc_install_string_primitives(ocklass);
 		return true;
 	    }
@@ -130,14 +113,11 @@
 }
 
 static VALUE
-rb_objc_alloc_class(const char *name, VALUE *psuper, VALUE flags, VALUE klass)
+rb_objc_alloc_class(const char *name, VALUE super, VALUE flags, VALUE klass)
 {
-    VALUE super, obj;
-    Class ocklass, ocsuper;
+    Class ocsuper, ocklass;
     char ocname[128];
 
-    super = psuper == NULL ? 0 : *psuper;
-
     if (name == NULL) {
 	static long anon_count = 1;
     	snprintf(ocname, sizeof ocname, "RBAnonymous%ld", ++anon_count);
@@ -146,7 +126,7 @@
 	if (super == rb_cBasicObject && strcmp(name, "Object") != 0) {
 	    rb_warn("Do not subclass NSObject directly, please subclass " \
 		    "Object instead.");
-	    super = *psuper = rb_cObject; 
+	    super = rb_cObject; 
 	}
 	if (objc_getClass(name) != NULL) {
 	    long count = 1;
@@ -161,28 +141,26 @@
 	}
     }
 
-    ocsuper = super == 0 ? NULL : RCLASS_OCID(super);
-    ocklass = objc_allocateClassPair(ocsuper, ocname, 0);
+    ocsuper = super == 0 ? (Class)rb_cBasicObject : (Class)super;
+    ocklass = objc_allocateClassPair(ocsuper, ocname, sizeof(id));
     assert(ocklass != NULL);
 
-    {
-	NEWOBJ(obj2, struct RClass);
-	OBJSETUP(obj2, klass, flags);
-	obj = (VALUE)obj2;
-    }
+    int version_flag;
 
-    RBASIC(obj)->isa = ocklass->isa;
-    RCLASS(obj)->ocklass = ocklass;
+    version_flag = RCLASS_IS_RUBY_CLASS;
+    if (flags == T_MODULE)
+	version_flag |= RCLASS_IS_MODULE;
+    if ((RCLASS_VERSION(ocsuper) & RCLASS_IS_OBJECT_SUBCLASS) == RCLASS_IS_OBJECT_SUBCLASS)
+	version_flag |= RCLASS_IS_OBJECT_SUBCLASS;
 
-    rb_objc_retain((const void *)obj); /* classes should never be released */
+    class_setVersion(ocklass, version_flag);
 
-    if (name == NULL)
-	FL_SET(obj, RCLASS_ANONYMOUS);
+    DLOG("DEFC", "%s < %s (version=%d)", ocname, class_getName(class_getSuperclass((Class)ocklass)), version_flag);
 
     if (klass != 0)
 	rb_objc_install_primitives(ocklass, ocsuper);
 
-    return obj;
+    return (VALUE)ocklass;
 }
 
 VALUE
@@ -190,76 +168,48 @@
 {
     VALUE klass;
     
-    klass = rb_objc_alloc_class(name, &super, T_CLASS, rb_cClass);
+    klass = rb_objc_alloc_class(name, super, T_CLASS, rb_cClass);
  
-    class_init(klass);
-
-    objc_registerClassPair(RCLASS_OCID(klass));
+    objc_registerClassPair((Class)klass);
    
     if (name != NULL) 
 	st_insert(rb_class_tbl, (st_data_t)rb_intern(name), (st_data_t)klass);
-    st_insert(rb_objc_class_tbl, (st_data_t)RCLASS_OCID(klass), 
-	      (st_data_t)klass);
 
-    RCLASS_M_TBL(klass) = st_init_numtable();
-    RCLASS_SUPER(klass) = super;
-    
-    OBJ_INFECT(klass, super);
-
     return klass;
 }
 
 VALUE
 rb_objc_rename_class(VALUE klass, const char *name)
 {
-#if 0
-    Class ocorig;
-    Class ocnew;
-    char *ocname;
-    unsigned i, count;
+    /* TODO */
+    return klass;
+}
 
-    count = strlen(name);
-    ocname = (char *)alloca(count + 3);
-    ocname[0] = 'R';
-    ocname[1] = 'B';
-    for (i = 0; i < count; i++) {
-	char c = name[i];
-	if (c == ':')
-	    c = '_';
-	ocname[i + 2] = c;
-    }
-    ocname[count + 2] = '\0';
+#else /* WITH_OBJC */
 
-    ocorig = RCLASS_OCID(klass);
+static VALUE
+class_init(VALUE obj)
+{
+    GC_WB(&RCLASS(obj)->ptr, ALLOC(rb_classext_t));
+    RCLASS_IV_TBL(obj) = 0;
+    RCLASS_M_TBL(obj) = 0;
+    RCLASS_SUPER(obj) = 0;
+    RCLASS_IV_INDEX_TBL(obj) = 0;
+    return obj;
+}
 
-    //printf("renamed class %p %s to %s\n", klass, class_getName(ocorig), ocname);
-
-    ocnew = objc_duplicateClass(ocorig, ocname, 0);
-
-    RBASIC(klass)->isa = ocnew->isa;
-    RCLASS(klass)->ocklass = ocnew;   
-
-    //printf("old %p new %p\n", ocorig, ocnew);
-
-    //objc_disposeClassPair(ocorig);
-
-    return klass;
 #endif
-    return klass;
-}
 
-#endif /* WITH_OBJC */
-
 static VALUE
 class_alloc(VALUE flags, VALUE klass)
 {
 #if WITH_OBJC
-    VALUE obj = rb_objc_alloc_class(NULL, NULL, flags, klass);
+    return rb_objc_alloc_class(NULL, 0, flags, klass);
 #else
     NEWOBJ(obj, struct RClass);
     OBJSETUP(obj, klass, flags);
+    return class_init((VALUE)obj);
 #endif
-    return class_init((VALUE)obj);
 }
 
 VALUE
@@ -272,8 +222,8 @@
 
     RCLASS_SUPER(klass) = super;
     RCLASS_M_TBL(klass) = st_init_numtable();
+    OBJ_INFECT(klass, super);
 #endif
-    OBJ_INFECT(klass, super);
     return (VALUE)klass;
 }
 
@@ -284,7 +234,7 @@
 	rb_raise(rb_eTypeError, "superclass must be a Class (%s given)",
 		 rb_obj_classname(super));
     }
-    if (RBASIC(super)->flags & FL_SINGLETON) {
+    if (RCLASS_SINGLETON(super)) {
 	rb_raise(rb_eTypeError, "can't make subclass of singleton class");
     }
 }
@@ -300,6 +250,7 @@
     return rb_class_boot(super);
 }
 
+#if !WITH_OBJC
 struct clone_method_data {
     st_table *tbl;
     VALUE klass;
@@ -322,6 +273,7 @@
     }
     return ST_CONTINUE;
 }
+#endif
 
 /* :nodoc: */
 VALUE
@@ -331,26 +283,26 @@
     if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
 	RBASIC(clone)->klass = rb_singleton_class_clone(orig);
     }
+#if !WITH_OBJC
     RCLASS_SUPER(clone) = RCLASS_SUPER(orig);
+#endif
 #if WITH_OBJC
     {
 	Class ocsuper;
-	extern VALUE rb_cStringRuby;
-	extern VALUE rb_cArrayRuby;
-	extern VALUE rb_cHashRuby;
 	if (orig == rb_cStringRuby
 	    || orig == rb_cArrayRuby
 	    || orig == rb_cHashRuby) {
-	    ocsuper = RCLASS_OCID(orig);
+	    ocsuper = (Class)orig;
 	    rb_warn("cloning class `%s' is not supported, creating a " \
 		    "subclass instead", rb_class2name(orig));
 	}
 	else {
-	    ocsuper = class_getSuperclass(RCLASS_OCID(orig));
+	    ocsuper = class_getSuperclass((Class)orig);
 	}
-	class_setSuperclass(RCLASS(clone)->ocklass, ocsuper);
+	class_setSuperclass((Class)clone, ocsuper);
     }
 #endif
+#if 0 // TODO
     if (RCLASS_IV_TBL(orig)) {
 	ID id;
 
@@ -368,6 +320,7 @@
 	st_foreach(RCLASS_M_TBL(orig), clone_method,
 	  (st_data_t)&data);
     }
+#endif
 
     return clone;
 }
@@ -384,7 +337,7 @@
     }
     clone =  rb_mod_init_copy(clone, orig);
 #if WITH_OBJC 
-    rb_objc_install_primitives(RCLASS_OCID(clone), RCLASS_OCID(orig)); 
+    rb_objc_install_primitives((Class)clone, (Class)orig);
 #endif
     return clone;
 }
@@ -393,7 +346,9 @@
 rb_singleton_class_clone(VALUE obj)
 {
     VALUE klass = RBASIC(obj)->klass;
-
+#if WITH_OBJC
+    return klass;
+#else
     if (!FL_TEST(klass, FL_SINGLETON))
 	return klass;
     else {
@@ -419,22 +374,29 @@
 	  (st_data_t)&data);
 	rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
 	FL_SET(clone, FL_SINGLETON);
-#if WITH_OBJC
-    	objc_registerClassPair(RCLASS_OCID(clone));
-#endif
 	return (VALUE)clone;
     }
+#endif
 }
 
 void
 rb_singleton_class_attached(VALUE klass, VALUE obj)
 {
+#if WITH_OBJC
+    if (RCLASS_SINGLETON(klass)) {
+	static ID attachedId = 0;
+	if (attachedId == 0)
+	    attachedId = rb_intern("__attached__");
+	rb_ivar_set(klass, attachedId, obj);
+    }
+#else
     if (FL_TEST(klass, FL_SINGLETON)) {
 	if (!RCLASS_IV_TBL(klass)) {
 	    GC_WB(&RCLASS_IV_TBL(klass), st_init_numtable());
 	}
 	st_insert(RCLASS_IV_TBL(klass), rb_intern("__attached__"), obj);
     }
+#endif
 }
 
 VALUE
@@ -443,50 +405,40 @@
     bool pure;
 
 #if WITH_OBJC
-    pure = rb_objc_is_non_native(obj);
+    pure = NATIVE(obj);
 #else
     pure = false;
 #endif
 
+#if WITH_OBJC
+    if (!pure && TYPE(obj) == T_CLASS && RCLASS_SINGLETON(obj)) {
+#else
     if (!pure && BUILTIN_TYPE(obj) == T_CLASS && FL_TEST(obj, FL_SINGLETON)) {
-	return RBASIC(obj)->klass = rb_cClass;
+#endif
+	RBASIC(obj)->klass = rb_cClass;
+	return rb_cClass;
     }
     else {
-	VALUE metasuper;
+//	VALUE metasuper;
 	VALUE klass;
 
+	klass = rb_class_boot(super);
+	RBASIC(obj)->klass = klass;
 #if WITH_OBJC
-	if (!pure && BUILTIN_TYPE(obj) == T_CLASS) {
-	    NEWOBJ(obj2, struct RClass); 
-	    OBJSETUP(obj2, rb_cClass, T_CLASS); 
-	    klass = (VALUE)obj2; 
-	    rb_objc_retain((const void *)klass); 
-	    class_init(klass); 
-	    OBJ_INFECT(klass, super); 
-	    RCLASS_SUPER(klass) = super; 
-	    RCLASS_M_TBL(klass) = st_init_numtable(); 
-	    RCLASS(klass)->ocklass = RBASIC(super)->isa; 
-	    RBASIC(obj)->klass = klass;
-	}
-	else {
-	    klass = rb_class_boot(super);
-	    *(Class *)obj = RCLASS_OCID(klass);
-	    if (!pure)
-		RBASIC(obj)->klass = klass;
-	}
+	//RCLASS_SET_SINGLETON(klass);
 #else
-	klass = rb_class_boot(super);
-	RBASIC(obj)->klass = klass;
+	FL_SET(klass, FL_SINGLETON);
 #endif
-	FL_SET(klass, FL_SINGLETON);
 
 	rb_singleton_class_attached(klass, obj);
 
+#if 0
 	metasuper = RBASIC(rb_class_real(super))->klass;
 	/* metaclass of a superclass may be NULL at boot time */
 	if (metasuper) {
 	    RBASIC(klass)->klass = metasuper;
 	}
+#endif
 	return klass;
     }
 }
@@ -501,8 +453,8 @@
     klass = rb_objc_create_class(rb_id2name(id), super);
 #else
     klass = rb_class_new(super);
+    rb_make_metaclass(klass, RBASIC(super)->klass);
 #endif
-    rb_make_metaclass(klass, RBASIC(super)->klass);
 
     return klass;
 }
@@ -577,7 +529,9 @@
 {
     VALUE mdl = class_alloc(T_MODULE, rb_cModule);
 
+#if !WITH_OBJC
     RCLASS_M_TBL(mdl) = st_init_numtable();
+#endif
 
     return (VALUE)mdl;
 }
@@ -588,9 +542,8 @@
     VALUE mdl;
 
 #if WITH_OBJC
-    mdl = rb_objc_create_class(rb_id2name(id), 0);
-    RBASIC(mdl)->flags = T_MODULE;
-    RBASIC(mdl)->klass = rb_cModule; /* necessary? */
+    mdl = rb_objc_alloc_class(rb_id2name(id), 0, T_MODULE, rb_cModule);
+    objc_registerClassPair((Class)mdl);
 #else
     mdl = rb_module_new();
     rb_name_class(mdl, id);
@@ -640,6 +593,7 @@
     return module;
 }
 
+#if !WITH_OBJC
 static VALUE
 include_class_new(VALUE module, VALUE super)
 {
@@ -648,31 +602,71 @@
     if (BUILTIN_TYPE(module) == T_ICLASS) {
 	module = RBASIC(module)->klass;
     }
+#if !WITH_OBJC
     if (!RCLASS_IV_TBL(module)) {
 	GC_WB(&RCLASS_IV_TBL(module), st_init_numtable());
     }
     RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
     RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
     RCLASS_SUPER(klass) = super;
+#else
+    class_setSuperclass((Class)klass, (Class)super);
+#endif
     if (TYPE(module) == T_ICLASS) {
 	RBASIC(klass)->klass = RBASIC(module)->klass;
     }
     else {
 	RBASIC(klass)->klass = module;
     }
-#if WITH_OBJC
-    class_setSuperclass(RCLASS(klass)->ocklass, 
-	    		RCLASS(RBASIC(klass)->klass)->ocklass);
-#endif
     OBJ_INFECT(klass, module);
     OBJ_INFECT(klass, super);
 
     return (VALUE)klass;
 }
+#endif
 
 void
 rb_include_module(VALUE klass, VALUE module)
 {
+#if WITH_OBJC
+    VALUE ary;
+
+    rb_frozen_class_p(klass);
+
+    if (!OBJ_TAINTED(klass))
+	rb_secure(4);
+
+    Check_Type(module, T_MODULE);
+
+    ary = rb_ivar_get(klass, idIncludedModules);
+    if (ary == Qnil) {
+	ary = rb_ary_new();
+	rb_ivar_set(klass, idIncludedModules, ary);
+    }
+    rb_ary_push(ary, module);
+
+    ary = rb_ivar_get(module, idIncludedInClasses);
+    if (ary == Qnil) {
+	ary = rb_ary_new();
+	rb_ivar_set(module, idIncludedInClasses, ary);
+    }
+    rb_ary_push(ary, klass);
+
+    DLOG("INCM", "%s <- %s", class_getName((Class)klass), class_getName((Class)module));
+
+    Method *methods;
+    unsigned int i, methods_count;
+
+    methods = class_copyMethodList((Class)module, &methods_count);
+    for (i = 0; i < methods_count; i++) {
+	Method method = methods[i];
+	DLOG("DEFI", "-[%s %s]", class_getName((Class)klass), (char *)method_getName(method));
+	assert(class_addMethod((Class)klass, 
+		method_getName(method), 
+		method_getImplementation(method), 
+		method_getTypeEncoding(method)));
+    }
+#else
     VALUE p, c;
     int changed = 0;
 
@@ -708,15 +702,13 @@
 		    break;
 	    }
 	}
-#if WITH_OBJC
-	rb_objc_sync_ruby_methods(module, klass);
-#endif
 	c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
 	changed = 1;
       skip:
 	module = RCLASS_SUPER(module);
     }
     if (changed) rb_clear_cache();
+#endif
 }
 
 /*
@@ -805,7 +797,10 @@
     VALUE p, ary = rb_ary_new();
 
     for (p = mod; p; p = RCLASS_SUPER(p)) {
-	if (FL_TEST(p, FL_SINGLETON))
+#if WITH_OBJC
+	rb_ary_push(ary, p);
+#else
+	if (RCLASS_SINGLETON(p))
 	    continue;
 	if (BUILTIN_TYPE(p) == T_ICLASS) {
 	    rb_ary_push(ary, RBASIC(p)->klass);
@@ -813,6 +808,7 @@
 	else {
 	    rb_ary_push(ary, p);
 	}
+#endif
     }
     return ary;
 }
@@ -862,6 +858,7 @@
     return ins_methods_push(name, type, ary, NOEX_PUBLIC);
 }
 
+#if !WITH_OBJC
 static int
 method_entry(ID key, NODE *body, st_table *list)
 {
@@ -882,11 +879,60 @@
     }
     return ST_CONTINUE;
 }
+#endif
 
+#if WITH_OBJC
+static inline bool
+is_ignored_selector(SEL sel)
+{
+#if defined(__ppc__)
+    return sel == (SEL)0xfffef000;
+#elif defined(__i386__)
+    return sel == (SEL)0xfffeb010;
+#else
+# error Unsupported arch
+#endif
+}
+#endif
+
 static VALUE
 class_instance_method_list(int argc, VALUE *argv, VALUE mod, int (*func) (ID, long, VALUE))
 {
+#if WITH_OBJC
     VALUE ary;
+    bool recur;
+
+    ary = rb_ary_new();
+
+    if (argc == 0) {
+	recur = true;
+    }
+    else {
+	VALUE r;
+	rb_scan_args(argc, argv, "01", &r);
+	recur = RTEST(r);
+    }
+
+    while (mod != 0) {
+	unsigned i, count; 
+	Method *methods; 
+
+	methods = class_copyMethodList((Class)mod, &count); 
+	if (methods != NULL) {  
+	    for (i = 0; i < count; i++) { 
+		SEL sel = method_getName(methods[i]); 
+		if (is_ignored_selector(sel)) 
+		    continue; 
+		rb_ary_push(ary, ID2SYM(rb_intern(sel_getName(sel)))); 
+	    } 
+	    free(methods); 
+	}
+	if (!recur)
+	   break;	   
+	mod = (VALUE)class_getSuperclass((Class)mod); 
+    } 
+#else
+    VALUE ary;
     int recur;
     st_table *list;
     VALUE mod_orig = mod;
@@ -910,9 +956,6 @@
     ary = rb_ary_new();
     st_foreach(list, func, ary);
     st_free_table(list);
-
-#if WITH_OBJC
-    rb_objc_methods(ary, RCLASS(mod_orig)->ocklass);
 #endif
 
     return ary;
@@ -1039,6 +1082,9 @@
 VALUE
 rb_obj_singleton_methods(int argc, VALUE *argv, VALUE obj)
 {
+#if WITH_OBJC // TODO
+    return Qnil;
+#else
     VALUE recur, ary, klass;
     st_table *list;
 
@@ -1065,6 +1111,7 @@
     st_free_table(list);
 
     return ary;
+#endif
 }
 
 void
@@ -1120,35 +1167,38 @@
 
     DEFER_INTS;
 #if WITH_OBJC
-    if (rb_objc_is_non_native(obj)) {
+    if (NATIVE(obj)) {
 	Class ocklass;
 
 	ocklass = *(Class *)obj;
-	klass = rb_objc_import_class(ocklass);
+	klass = (VALUE)ocklass;
 	if (class_isMetaClass(ocklass))
 	    return klass;
 
-	if (!FL_TEST(klass, FL_SINGLETON))
-	    klass = rb_make_metaclass(obj, klass);
+	if (!RCLASS_SINGLETON(ocklass))
+	    klass = rb_make_metaclass(obj, (VALUE)ocklass);
+
 	return klass;
     }
+    if (TYPE(obj) == T_CLASS)
+	return obj;
 #endif
-    if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) &&
+    if (RCLASS_SINGLETON(RBASIC(obj)->klass) &&
 	rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) {
 	klass = RBASIC(obj)->klass;
     }
     else {
 	klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
     }
-#if !WITH_OBJC
+#if 0
     if (OBJ_TAINTED(obj)) {
 	OBJ_TAINT(klass);
     }
     else {
-	FL_UNSET(klass, FL_TAINT);
+	OBJ_UNTAINT(klass);
     }
+#endif
     if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass);
-#endif
     ALLOW_INTS;
 
     return klass;

Modified: MacRuby/branches/lrz_unstable/compile.c
===================================================================
--- MacRuby/branches/lrz_unstable/compile.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/compile.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -338,9 +338,9 @@
 	    alloc_size *= 2;
 	    goto retry;
 	}
-	storage->next = (void *)ALLOC_N(char, alloc_size +
+	GC_WB(&storage->next, (void *)ALLOC_N(char, alloc_size +
 					sizeof(struct
-					       iseq_compile_data_storage));
+					       iseq_compile_data_storage)));
 	storage = iseq->compile_data->storage_current = storage->next;
 	storage->next = 0;
 	storage->pos = 0;
@@ -687,13 +687,15 @@
 {
     INSN *iobj = 0;
     VALUE *operands =
-      (VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * 5);
+      (VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * 7);
     operands[0] = id;
     operands[1] = argc;
     operands[2] = block;
     operands[3] = flag;
     operands[4] = 0;
-    iobj = new_insn_core(iseq, line_no, BIN(send), 5, operands);
+    operands[5] = (VALUE)sel_registerName(rb_id2name(SYM2ID(id)));
+    operands[6] = 0;
+    iobj = new_insn_core(iseq, line_no, BIN(send), 6, operands);
     return iobj;
 }
 

Modified: MacRuby/branches/lrz_unstable/debug.h
===================================================================
--- MacRuby/branches/lrz_unstable/debug.h	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/debug.h	2008-07-30 02:27:07 UTC (rev 382)
@@ -29,4 +29,25 @@
 void  ruby_debug_breakpoint(void);
 void  ruby_debug_gc_check_func(void);
 
+#if ENABLE_DEBUG_LOGGING 
+static inline bool dlog_enabled(void) {
+    static int flag = -1;
+    if (flag == -1) {
+        flag = getenv("MACRUBY_DEBUG") != NULL;
+    }
+    return (bool)flag;
+}
+# define DLOG(mod, fmt, args...)        \
+  do {                                  \
+    if (dlog_enabled()) {               \
+        printf("%10s   ", mod);         \
+        printf(fmt, ##args);            \
+        printf("\n");                   \
+    }                                   \
+  }                                     \
+  while (0)
+#else
+# define DLOG(mod, fmt, args...)
+#endif
+
 #endif /* RUBY_DEBUG_H */

Modified: MacRuby/branches/lrz_unstable/eval.c
===================================================================
--- MacRuby/branches/lrz_unstable/eval.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/eval.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -336,7 +336,7 @@
     const char *desc = "something(?!)";
 
     if (OBJ_FROZEN(klass)) {
-	if (FL_TEST(klass, FL_SINGLETON))
+	if (RCLASS_SINGLETON(klass))
 	    desc = "object";
 	else {
 	    switch (TYPE(klass)) {

Modified: MacRuby/branches/lrz_unstable/gc.c
===================================================================
--- MacRuby/branches/lrz_unstable/gc.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/gc.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -1029,7 +1029,7 @@
 #endif
     if (__nsobject == NULL)
 	__nsobject = (void *)objc_getClass("NSObject");
-    RBASIC(obj)->isa = __nsobject;
+    RBASIC(obj)->klass = (VALUE)__nsobject;
     return obj;
 }
 
@@ -2267,9 +2267,10 @@
 	if (type != AUTO_OBJECT_SCANNED && type != AUTO_OBJECT_UNSCANNED)
 	    continue;
 	if (ctx->class_of != 0) {
+#if 0
 	    if (ctx->class_of == rb_cClass || ctx->class_of == rb_cModule) {
 		/* Class/Module are a special case. */
-		if (rb_objc_is_non_native(r->address)
+		if (NATIVE(r->address)
 		    || FL_TEST(r->address, FL_SINGLETON))
 		    continue;
 		if (ctx->class_of == rb_cClass) {
@@ -2284,11 +2285,13 @@
 			continue;
 		}
 	    }
-	    else {
+	    else
+#endif
+	    {
 	    	unsigned ok = 0;
 	    	for (c = *(Class *)r->address; c != NULL; 
 		     c = class_getSuperclass(c)) {
-		    if (c == RCLASS(ctx->class_of)->ocklass) {
+		    if (c ==(Class)ctx->class_of) {
 		        ok = 1;
 		        break;
 		    }
@@ -2297,14 +2300,14 @@
 		    continue;
 	    }
 	}
-	if (!rb_objc_is_non_native((VALUE)r->address)) {
+	if (!NATIVE((VALUE)r->address)) {
 	    switch (BUILTIN_TYPE(r->address)) {
 		case T_NONE: 
 		case T_ICLASS: 
 		case T_NODE:
 		    continue;
 		case T_CLASS:
-		    if (FL_TEST(r->address, FL_SINGLETON))
+		    if (RCLASS_SINGLETON(r->address))
 			continue;
 	    }
 	}
@@ -2437,7 +2440,7 @@
     if (__os_finalizers != NULL)
 	CFDictionaryRemoveValue(__os_finalizers, (const void *)obj);
     
-    if (rb_objc_is_non_native(obj)) {
+    if (NATIVE(obj)) {
 	rb_objc_flag_set((void *)obj, FL_FINALIZE, false);
     }
     else {
@@ -2491,7 +2494,7 @@
 
     rb_ary_push(table, block);
     
-    if (rb_objc_is_non_native(obj)) {
+    if (NATIVE(obj)) {
 	rb_objc_flag_set((void *)obj, FL_FINALIZE, true);
     }
     else {
@@ -2536,7 +2539,7 @@
     if (__os_finalizers == NULL)
 	return;
 
-    if (rb_objc_is_non_native(obj)) {
+    if (NATIVE(obj)) {
 	if (!rb_objc_flag_check((void *)obj, FL_FINALIZE))
 	    return;
     }
@@ -2802,7 +2805,7 @@
 	    auto_zone_get_layout_type_no_lock(__auto_zone, p0);
 	if ((type == AUTO_OBJECT_SCANNED || type == AUTO_OBJECT_UNSCANNED)
 	    && !rb_objc_is_placeholder(p0)
-	    && (rb_objc_is_non_native((VALUE)p0)
+	    && (NATIVE((VALUE)p0)
 		|| (BUILTIN_TYPE(p0) < T_FIXNUM && BUILTIN_TYPE(p0) != T_ICLASS)))
 	    return (VALUE)p0;
     }
@@ -3076,7 +3079,7 @@
 __rb_objc_finalize(void *obj, void *data)
 {
     //printf("finalize %p <%s>\n",obj, class_getName(*(Class *)obj));
-    if (rb_objc_is_non_native((VALUE)obj)) {
+    if (NATIVE((VALUE)obj)) {
 	static SEL sel = NULL;
 	long flag;
 	flag = rb_objc_remove_flags(obj);

Modified: MacRuby/branches/lrz_unstable/hash.c
===================================================================
--- MacRuby/branches/lrz_unstable/hash.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/hash.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -339,7 +339,7 @@
 
     hash = (VALUE)CFDictionaryCreateMutable(NULL, 0, &keys_cb, &values_cb);
     if (klass != 0 && klass != rb_cHash && klass != rb_cHashRuby)
-	*(Class *)hash = RCLASS_OCID(klass);
+	*(Class *)hash = (Class)klass;
 
     CFMakeCollectable((CFTypeRef)hash);
     rb_gc_malloc_increase(sizeof(void *));
@@ -2918,11 +2918,9 @@
 
 #if WITH_OBJC
 
-#define NSCFDICTIONARY() RCLASS_OCID(rb_cCFHash)
-
 #define PREPARE_RCV(x) \
     Class old = *(Class *)x; \
-    *(Class *)x = NSCFDICTIONARY();
+    *(Class *)x = (Class)rb_cCFHash;
 
 #define RESTORE_RCV(x) \
     *(Class *)x = old;
@@ -2930,7 +2928,7 @@
 bool
 rb_objc_hash_is_pure(VALUE ary)
 {
-    return *(Class *)ary == NSCFDICTIONARY();
+    return *(Class *)ary == (Class)rb_cCFHash;
 }
 
 static CFIndex
@@ -3061,7 +3059,6 @@
     rb_cCFHash = rb_objc_import_class((Class)objc_getClass("NSCFDictionary"));
     rb_cHash = rb_objc_import_class((Class)objc_getClass("NSDictionary"));
     rb_cHashRuby = rb_objc_import_class((Class)objc_getClass("NSMutableDictionary"));
-    FL_UNSET(rb_cHashRuby, RCLASS_OBJC_IMPORTED);
     rb_const_set(rb_cObject, rb_intern("Hash"), rb_cHashRuby);
 #else
     rb_cHash = rb_define_class("Hash", rb_cObject);

Modified: MacRuby/branches/lrz_unstable/id.c
===================================================================
--- MacRuby/branches/lrz_unstable/id.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/id.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -66,4 +66,7 @@
 
     idRespond_to = rb_intern("respond_to?");
     idInitialize = rb_intern("initialize");
+
+    idIncludedModules = rb_intern("__included_modules__");
+    idIncludedInClasses = rb_intern("__included_in_classes__");
 }

Modified: MacRuby/branches/lrz_unstable/id.h
===================================================================
--- MacRuby/branches/lrz_unstable/id.h	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/id.h	2008-07-30 02:27:07 UTC (rev 382)
@@ -52,4 +52,8 @@
 extern ID id__send__;
 extern ID idRespond_to;
 extern ID idInitialize;
+#if WITH_OBJC
+extern ID idIncludedModules;
+extern ID idIncludedInClasses;
+#endif
 #endif /* RUBY_ID_H */

Modified: MacRuby/branches/lrz_unstable/include/ruby/intern.h
===================================================================
--- MacRuby/branches/lrz_unstable/include/ruby/intern.h	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/include/ruby/intern.h	2008-07-30 02:27:07 UTC (rev 382)
@@ -691,6 +691,7 @@
 VALUE rb_mod_remove_cvar(VALUE, VALUE);
 /* objc.m */
 #if WITH_OBJC
+void rb_objc_alias(VALUE, ID, ID);
 VALUE rb_mod_objc_ancestors(VALUE);
 VALUE rb_mod_objc_ib_outlet(int, VALUE *, VALUE);
 VALUE rb_require_framework(int, VALUE *, VALUE);
@@ -700,7 +701,6 @@
 void rb_objc_flag_set(const void *, int, bool);
 bool rb_objc_flag_check(const void *, int);
 long rb_objc_remove_flags(const void *obj);
-void rb_objc_sync_ruby_methods(VALUE, VALUE);
 void rb_objc_methods(VALUE, Class);
 bool rb_objc_is_immutable(VALUE);
 #endif

Modified: MacRuby/branches/lrz_unstable/include/ruby/node.h
===================================================================
--- MacRuby/branches/lrz_unstable/include/ruby/node.h	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/include/ruby/node.h	2008-07-30 02:27:07 UTC (rev 382)
@@ -507,7 +507,8 @@
 void rb_add_method(VALUE, ID, NODE *, int);
 void rb_add_method_direct(VALUE, ID, NODE *);
 #if WITH_OBJC
-NODE *rb_objc_define_objc_mid_closure(VALUE, ID, ID);
+void rb_objc_register_ruby_method(VALUE, ID, NODE *);
+NODE *rb_objc_method_node(VALUE, ID, IMP *, SEL *);
 #endif
 NODE *rb_node_newnode(enum node_type,VALUE,VALUE,VALUE);
 

Modified: MacRuby/branches/lrz_unstable/include/ruby/ruby.h
===================================================================
--- MacRuby/branches/lrz_unstable/include/ruby/ruby.h	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/include/ruby/ruby.h	2008-07-30 02:27:07 UTC (rev 382)
@@ -416,20 +416,11 @@
 #else
 # define NEWOBJ(obj,type) type *obj = (type*)rb_newobj()
 #endif
-#define __OBJSETUP(obj,c,t) do {\
+#define OBJSETUP(obj,c,t) do {\
     RBASIC(obj)->flags = (t);\
     RBASIC(obj)->klass = (c);\
     if (rb_safe_level() >= 3) FL_SET(obj, FL_TAINT);\
 } while (0)
-#if WITH_OBJC
-# define OBJSETUP(obj,c,t) do {\
-    __OBJSETUP(obj,c,t);\
-    if (c != 0) \
-	RBASIC(obj)->isa = (void *)RCLASS_OCID(c); \
-} while (0)
-#else
-# define OBJSETUP(obj,c,t) __OBJSETUP(obj,c,t)
-#endif
 #define CLONESETUP(clone,obj) do {\
     OBJSETUP(clone,rb_singleton_class_clone((VALUE)obj),RBASIC(obj)->flags);\
     rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);\
@@ -441,37 +432,34 @@
 } while (0)
 
 struct RBasic {
-    void *isa;
+    VALUE klass; /* isa */
     VALUE flags;
-    VALUE klass;
 };
 
-#define ROBJECT_EMBED_LEN_MAX 3
-struct RObject {
-    struct RBasic basic;
+struct rb_ivars {
+#define RB_IVAR_ARY 0 
+#define RB_IVAR_TBL 1
+#define RB_IVAR_TYPE(ivars) (ivars.type & 0x1)
+#define RB_IVAR_SET_TYPE(ivars, t) (ivars.type |= t)
+#define RB_IVAR_ARY_LEN(ivars) (ivars.type >> 1)
+#define RB_IVAR_ARY_SET_LEN(ivars, len) (ivars.type = (len << 1) | (ivars.type & 0x1))
+#define RB_IVAR_ARY_MAX 10
+    short type;
     union {
-	struct {
-	    long numiv;
-	    VALUE *ivptr;
-            struct st_table *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
-	} heap;
-	VALUE ary[ROBJECT_EMBED_LEN_MAX];
+	struct rb_ivar_ary_entry {
+	    ID name;
+	    VALUE value;
+	} *ary;
+	CFMutableDictionaryRef tbl;
     } as;
 };
-#define ROBJECT_EMBED FL_USER1
-#define ROBJECT_NUMIV(o) \
-    ((RBASIC(o)->flags & ROBJECT_EMBED) ? \
-     ROBJECT_EMBED_LEN_MAX : \
-     ROBJECT(o)->as.heap.numiv)
-#define ROBJECT_IVPTR(o) \
-    ((RBASIC(o)->flags & ROBJECT_EMBED) ? \
-     ROBJECT(o)->as.ary : \
-     ROBJECT(o)->as.heap.ivptr)
-#define ROBJECT_IV_INDEX_TBL(o) \
-    ((RBASIC(o)->flags & ROBJECT_EMBED) ? \
-     RCLASS_IV_INDEX_TBL(rb_obj_class(o)) : \
-     ROBJECT(o)->as.heap.iv_index_tbl)
 
+struct RObject {
+    struct RBasic basic;
+    struct rb_ivars ivars;
+};
+
+#if !WITH_OBJC
 typedef struct {
     VALUE super;
     struct st_table *iv_tbl;
@@ -484,17 +472,38 @@
     struct st_table *m_tbl;
     struct st_table *iv_index_tbl;
 };
-#define RCLASS_IV_TBL(c) (RCLASS(c)->ptr->iv_tbl)
-#define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
-#define RCLASS_SUPER(c) (RCLASS(c)->ptr->super)
-#define RCLASS_IV_INDEX_TBL(c) (RCLASS(c)->iv_index_tbl)
-#define RMODULE_IV_TBL(m) RCLASS_IV_TBL(m)
-#define RMODULE_M_TBL(m) RCLASS_M_TBL(m)
-#define RMODULE_SUPER(m) RCLASS_SUPER(m)
-#if WITH_OBJC
-# define RCLASS_ANONYMOUS FL_USER1
-# define RCLASS_OBJC_IMPORTED FL_USER2
-# define RCLASS_OCID(obj) ((Class)RCLASS(obj)->ocklass)
+# define RCLASS_IV_TBL(c) (RCLASS(c)->ptr->iv_tbl)
+# define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
+# define RCLASS_SUPER(c) (RCLASS(c)->ptr->super)
+# define RCLASS_IV_INDEX_TBL(c) (RCLASS(c)->iv_index_tbl)
+# define RMODULE_IV_TBL(m) RCLASS_IV_TBL(m)
+# define RMODULE_M_TBL(m) RCLASS_M_TBL(m)
+# define RMODULE_SUPER(m) RCLASS_SUPER(m)
+#else
+# define RCLASS_IS_OBJECT_SUBCLASS    0x100   /* class is a true RBObject subclass */
+# define RCLASS_IS_RUBY_CLASS         0x200   /* class was created from Ruby */
+# define RCLASS_IS_MODULE             0x400   /* class represents a Ruby Module */
+# define RCLASS_IS_SINGLETON	      0x800   /* class represents a singleton/metaclass */
+# define RCLASS_IS_FROZEN	      0x1000  /* class is frozen */
+# define RCLASS_IS_TAINTED	      0x2000  /* class is tainted */
+# if __OBJC2__
+#  define RCLASS_VERSION(m) (class_getVersion((Class)m))
+#  define RCLASS_SET_VERSION_FLAG(m,f) (class_setVersion((Class)m, (RCLASS_VERSION(m) | f)))
+#  define RCLASS_SUPER(m) (class_getSuperclass((Class)m))
+#  define RCLASS_SINGLETON(m) (class_isMetaclass((Class)m))
+# else
+#  define RCLASS_VERSION(m) (*(long *)((void *)m + (sizeof(void *) * 3)))
+#  define RCLASS_SET_VERSION_FLAG(m,f) (RCLASS_VERSION(m) |= f)
+#  define RCLASS_SUPER(m) (*(VALUE *)((void *)m + (sizeof(void *) * 1)))
+#  define _RCLASS_INFO(m) (*(long *)((void *)m + (sizeof(void *) * 4)))
+#  define RCLASS_SINGLETON(m) (_RCLASS_INFO(m) & CLS_META)
+# endif
+# define NATIVE(obj) (*(Class *)obj != NULL && (RCLASS_VERSION(*(Class *)obj) & RCLASS_IS_OBJECT_SUBCLASS) != RCLASS_IS_OBJECT_SUBCLASS)
+# define RCLASS_RUBY(m) ((RCLASS_VERSION(m) & RCLASS_IS_RUBY_CLASS) == RCLASS_IS_RUBY_CLASS)
+# define RCLASS_MODULE(m) ((RCLASS_VERSION(m) & RCLASS_IS_MODULE) == RCLASS_IS_MODULE)
+CFMutableDictionaryRef rb_class_ivar_dict(VALUE);
+CFMutableDictionaryRef rb_class_ivar_dict_or_create(VALUE);
+void rb_class_ivar_set_dict(VALUE, CFMutableDictionaryRef);
 #endif
 
 struct RFloat {
@@ -710,12 +719,12 @@
 #define R_CAST(st)   (struct st*)
 #define RBASIC(obj)  (R_CAST(RBasic)(obj))
 #define ROBJECT(obj) (R_CAST(RObject)(obj))
-#define RCLASS(obj)  (R_CAST(RClass)(obj))
-#define RMODULE(obj) RCLASS(obj)
 #define RFLOAT(obj)  (R_CAST(RFloat)(obj))
 #define RSTRING(obj) (R_CAST(RString)(obj))
 #define RREGEXP(obj) (R_CAST(RRegexp)(obj))
 #if !WITH_OBJC
+# define RCLASS(obj)  (R_CAST(RClass)(obj))
+# define RMODULE(obj) RCLASS(obj)
 # define RSTRING(obj) (R_CAST(RString)(obj))
 # define RARRAY(obj)  (R_CAST(RArray)(obj))
 # define RHASH(obj)   (R_CAST(RHash)(obj))
@@ -984,6 +993,15 @@
 RUBY_EXTERN VALUE rb_cVM;
 RUBY_EXTERN VALUE rb_cEnv;
 
+#if WITH_OBJC
+RUBY_EXTERN VALUE rb_cCFString;
+RUBY_EXTERN VALUE rb_cStringRuby;
+RUBY_EXTERN VALUE rb_cCFArray;
+RUBY_EXTERN VALUE rb_cArrayRuby;
+RUBY_EXTERN VALUE rb_cCFHash;
+RUBY_EXTERN VALUE rb_cHashRuby;
+#endif
+
 RUBY_EXTERN VALUE rb_eException;
 RUBY_EXTERN VALUE rb_eStandardError;
 RUBY_EXTERN VALUE rb_eSystemExit;
@@ -1018,22 +1036,6 @@
 
 RUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr;
 
-#if WITH_OBJC
-static inline unsigned
-rb_objc_is_non_native(VALUE obj)
-{
-    void *isa = RBASIC(obj)->isa;
-    if (isa == NULL || class_isMetaClass(isa))
-	return 0;
-    while (isa != NULL) {
-	if (rb_cObject != 0 && isa == RCLASS_OCID(rb_cObject))
-	    return 0;
-	isa = (void *)class_getSuperclass(isa);
-    }
-    return 1;
-}
-#endif
-
 static inline VALUE
 rb_class_of(VALUE obj)
 {
@@ -1046,20 +1048,6 @@
 	if (obj == Qnil)   return rb_cNilClass;
 	if (obj == Qfalse) return rb_cFalseClass;
     }
-#if WITH_OBJC
-    extern VALUE rb_cCFString;
-    extern VALUE rb_cCFArray;
-    extern VALUE rb_cCFHash;
-    if (rb_cCFString != 0 && *(Class *)obj == RCLASS_OCID(rb_cCFString))
-	return rb_cCFString;
-    if (rb_cCFArray != 0 && *(Class *)obj == RCLASS_OCID(rb_cCFArray))
-	return rb_cCFArray;
-    if (rb_cCFHash != 0 && *(Class *)obj == RCLASS_OCID(rb_cCFHash))
-	return rb_cCFHash;
-    VALUE rb_objc_import_class(Class);
-    if (rb_objc_is_non_native(obj))
-	return rb_objc_import_class(RBASIC(obj)->isa);
-#endif
     return RBASIC(obj)->klass;
 }
 
@@ -1077,20 +1065,14 @@
 	if (obj == Qfalse) return T_FALSE;
     }
 #if WITH_OBJC
-    /* FIXME this is super slow */
-    else if (rb_cHash != 0 
-	     && rb_cArray != 0
-	     && rb_cString != 0) {
-	Class k = *(Class *)obj;
-	while (k != NULL) {
-	    if (k == RCLASS_OCID(rb_cHash))
-		return T_HASH;
-	    if (k == RCLASS_OCID(rb_cArray))
-		return T_ARRAY;
-	    if (k == RCLASS_OCID(rb_cString))
-		return T_STRING;
-	    k = class_getSuperclass(k);
+    else if (*(Class *)obj != NULL) {
+	if (RCLASS_SINGLETON(*(Class *)obj)) {
+	    if (RCLASS_MODULE(obj)) return T_MODULE;
+	    else return T_CLASS;
 	}
+	if (*(Class *)obj == (Class)rb_cCFString) return T_STRING;
+	if (*(Class *)obj == (Class)rb_cCFArray) return T_ARRAY;
+	if (*(Class *)obj == (Class)rb_cCFHash) return T_HASH;
     }
 #endif
     return BUILTIN_TYPE(obj);

Modified: MacRuby/branches/lrz_unstable/insnhelper.h
===================================================================
--- MacRuby/branches/lrz_unstable/insnhelper.h	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/insnhelper.h	2008-07-30 02:27:07 UTC (rev 382)
@@ -112,8 +112,8 @@
   c1->nd_next = __tmp_c2->nd_next; \
 } while (0)
 
-#define CALL_METHOD(num, blockptr, flag, id, mn, recv, klass) do { \
-    VALUE v = vm_call_method(th, GET_CFP(), num, blockptr, flag, id, mn, recv, klass); \
+#define CALL_METHOD(num, blockptr, flag, id, mn, recv, klass, sel) do { \
+    VALUE v = vm_call_method(th, GET_CFP(), num, blockptr, flag, id, mn, recv, klass, sel); \
     if (v == Qundef) { \
 	RESTORE_REGS(); \
 	NEXT_INSN(); \
@@ -142,7 +142,7 @@
 
 #define CALL_SIMPLE_METHOD(num, id, recv) do { \
     VALUE klass = CLASS_OF(recv); \
-    CALL_METHOD(num, 0, 0, id, rb_method_node(klass, id), recv, CLASS_OF(recv)); \
+    CALL_METHOD(num, 0, 0, id, rb_method_node(klass, id), recv, CLASS_OF(recv), (SEL)0); \
 } while (0)
 
 #endif /* RUBY_INSNHELPER_H */

Modified: MacRuby/branches/lrz_unstable/insns.def
===================================================================
--- MacRuby/branches/lrz_unstable/insns.def	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/insns.def	2008-07-30 02:27:07 UTC (rev 382)
@@ -1023,7 +1023,7 @@
  */
 DEFINE_INSN
 send
-(ID op_id, rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag, IC ic)
+(ID op_id, rb_num_t op_argc, ISEQ blockiseq, rb_num_t op_flag, IC ic, VALUE sel)
 (...)
 (VALUE val) // inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
 {
@@ -1038,17 +1038,19 @@
     /* get receiver */
     recv = (flag & VM_CALL_FCALL_BIT) ? GET_SELF() : TOPN(num);
     klass = CLASS_OF(recv);
+#if WITH_OBJC
+    ic = 0;
+    mn = NULL;
+#else
     mn = vm_method_search(id, klass, ic);
-#if WITH_OBJC
-    vm_method_process_named_args(&id, &mn, recv, &num, GET_CFP());
-#endif
 
     /* send/funcall optimization */
     if (flag & VM_CALL_SEND_BIT) {
 	vm_send_optimize(GET_CFP(), &mn, &flag, &num, &id, klass);
     }
+#endif
 
-    CALL_METHOD(num, blockptr, flag, id, mn, recv, klass);
+    CALL_METHOD(num, blockptr, flag, id, mn, recv, klass, (SEL)sel);
 }
 
 /**
@@ -1073,12 +1075,13 @@
 
     recv = GET_SELF();
     vm_search_superclass(GET_CFP(), GET_ISEQ(), recv, TOPN(num), &id, &klass);
+#if WITH_OBJC
+    mn = NULL;
+#else
     mn = rb_method_node(klass, id);
-#if WITH_OBJC
-    vm_method_process_named_args(&id, &mn, recv, (rb_num_t *)&num, GET_CFP());
 #endif
 
-    CALL_METHOD(num, blockptr, flag, id, mn, recv, klass);
+    CALL_METHOD(num, blockptr, flag, id, mn, recv, klass, (SEL)0);
 }
 
 /**
@@ -1405,7 +1408,11 @@
       INSN_LABEL(normal_dispatch):
 	PUSH(recv);
 	PUSH(obj);
-	CALL_SIMPLE_METHOD(1, idPLUS, recv);
+
+	static SEL selPLUS=0;
+	if (selPLUS==0) { selPLUS = sel_registerName("+:"); }
+	CALL_METHOD(1, 0, 0, idPLUS, NULL, recv, CLASS_OF(recv), (SEL)selPLUS);
+	//CALL_SIMPLE_METHOD(1, idPLUS, recv);
     }
 }
 
@@ -1716,6 +1723,8 @@
     else {
 	PUSH(recv);
 	PUSH(obj);
+	//static SEL selPLUS=0;
+	//if (selPLUS==0) { selPLUS = sel_registerName("+:"); }
 	CALL_SIMPLE_METHOD(1, idLT, recv);
     }
 }

Modified: MacRuby/branches/lrz_unstable/io.c
===================================================================
--- MacRuby/branches/lrz_unstable/io.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/io.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -5209,7 +5209,7 @@
     p->filename = Qnil;
     p->current_file = Qnil;
     p->lineno = Qnil;
-    p->argv = v;
+    GC_WB(&p->argv, v);
 }
 
 static VALUE
@@ -5248,11 +5248,11 @@
 argf_initialize_copy(VALUE argf, VALUE orig)
 {
     ARGF = argf_of(orig);
-    rb_argv = rb_obj_dup(rb_argv);
+    GC_WB(&rb_argv, rb_obj_dup(rb_argv));
     if (ARGF.inplace) {
 	const char *inplace = ARGF.inplace;
 	ARGF.inplace = 0;
-	ARGF.inplace = ruby_strdup(inplace);
+	GC_WB(&ARGF.inplace, ruby_strdup(inplace));
     }
     return argf;
 }
@@ -7812,7 +7812,7 @@
 
     rb_define_hooked_variable("$.", &argf, argf_lineno_getter, argf_lineno_setter);
     rb_define_hooked_variable("$FILENAME", &argf, argf_filename_getter, 0);
-    filename = rb_str_new2("-");
+    GC_WB(&filename, rb_str_new2("-"));
 
     rb_define_hooked_variable("$-i", &argf, opt_i_get, opt_i_set);
     rb_define_hooked_variable("$*", &argf, argf_argv_getter, 0);

Modified: MacRuby/branches/lrz_unstable/marshal.c
===================================================================
--- MacRuby/branches/lrz_unstable/marshal.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/marshal.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -420,14 +420,16 @@
 {
     const char *path;
 
-    if (check && FL_TEST(klass, FL_SINGLETON)) {
+    if (check && RCLASS_SINGLETON(klass)) {
+#if !WITH_OBJC // TODO
 	if (RCLASS_M_TBL(klass)->num_entries ||
 	    (RCLASS_IV_TBL(klass) && RCLASS_IV_TBL(klass)->num_entries > 1)) {
 	    rb_raise(rb_eTypeError, "singleton can't be dumped");
 	}
+#endif
 	klass = RCLASS_SUPER(klass);
     }
-    while (BUILTIN_TYPE(klass) == T_ICLASS) {
+    while (TYPE(klass) == T_ICLASS) {
 	path = rb_class2name(RBASIC(klass)->klass);
 	w_byte(TYPE_EXTENDED_R, arg);
 	w_unique(path, arg);
@@ -534,6 +536,7 @@
 static void
 w_objivar(VALUE obj, struct dump_call_arg *arg)
 {
+#if !WITH_OBJC /* TODO */
     VALUE *ptr;
     long i, len, num;
 
@@ -548,6 +551,7 @@
     if (num != 0) {
         rb_ivar_foreach(obj, w_obj_each, (st_data_t)arg);
     }
+#endif
 }
 
 static void
@@ -650,7 +654,7 @@
         st_add_direct(arg->data, obj, arg->data->num_entries);
 
 #if WITH_OBJC
-	if (!rb_objc_is_non_native(obj))
+	if (!NATIVE(obj))
 #endif
         {
             st_data_t compat_data;
@@ -667,7 +671,7 @@
 
 	switch (/*BUILTIN_*/TYPE(obj)) {
 	  case T_CLASS:
-	    if (FL_TEST(obj, FL_SINGLETON)) {
+	    if (RCLASS_SINGLETON(obj)) {
 		rb_raise(rb_eTypeError, "singleton class can't be dumped");
 	    }
 	    w_byte(TYPE_CLASS, arg);
@@ -1279,28 +1283,20 @@
 	{
 	    VALUE c = path2class(r_unique(arg));
 
-	    if (FL_TEST(c, FL_SINGLETON)) {
+	    if (RCLASS_SINGLETON(c)) {
 		rb_raise(rb_eTypeError, "singleton can't be loaded");
 	    }
 	    v = r_object0(arg, 0, extmod);
-#if WITH_OBJC
-	    if (rb_objc_is_non_native(v)) {
-		*(Class *)v = RCLASS_OCID(c);	
-	    }
-	    else
-#endif
-	    {
-		if (rb_special_const_p(v) || TYPE(v) == T_OBJECT || TYPE(v) == T_CLASS) {
+	    if (rb_special_const_p(v) || TYPE(v) == T_OBJECT || TYPE(v) == T_CLASS) {
 format_error:
-		    rb_raise(rb_eArgError, "dump format error (user class)");
-		}
-		if (TYPE(v) == T_MODULE || !RTEST(rb_class_inherited_p(c, RBASIC(v)->klass))) {
-		    VALUE tmp = rb_obj_alloc(c);
+		rb_raise(rb_eArgError, "dump format error (user class)");
+	    }
+	    if (TYPE(v) == T_MODULE || !RTEST(rb_class_inherited_p(c, RBASIC(v)->klass))) {
+		VALUE tmp = rb_obj_alloc(c);
 
-		    if (TYPE(v) != TYPE(tmp)) goto format_error;
-		}
-		RBASIC(v)->klass = c;
+		if (TYPE(v) != TYPE(tmp)) goto format_error;
 	    }
+	    RBASIC(v)->klass = c;
 	}
 	break;
 

Modified: MacRuby/branches/lrz_unstable/numeric.c
===================================================================
--- MacRuby/branches/lrz_unstable/numeric.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/numeric.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -3148,7 +3148,7 @@
 static void
 rb_install_nsnumber_float_primitives(void)
 {
-    Class klass = RCLASS_OCID(rb_cFloat);
+    Class klass = (Class)rb_cFloat;
     rb_objc_install_method(klass, sel_registerName("objCType"),
 	    (IMP)imp_rb_float_objCType);
     rb_objc_install_method(klass, sel_registerName("getValue:"), 
@@ -3160,7 +3160,7 @@
 static void
 rb_install_nsnumber_integer_primitives(void)
 {
-    Class klass = RCLASS_OCID(rb_cNumeric);
+    Class klass = (Class)rb_cNumeric;
     rb_objc_install_method(klass, sel_registerName("objCType"),
 	    (IMP)imp_rb_integer_objCType);
     rb_objc_install_method(klass, sel_registerName("getValue:"), 

Modified: MacRuby/branches/lrz_unstable/objc.m
===================================================================
--- MacRuby/branches/lrz_unstable/objc.m	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/objc.m	2008-07-30 02:27:07 UTC (rev 382)
@@ -40,6 +40,7 @@
 #endif
 #include "vm_core.h"
 #include "vm.h"
+#include "eval_intern.h"
 
 typedef struct {
     bs_element_type_t type;
@@ -442,9 +443,6 @@
 	    *(id *)ocval = (id)number;
 	}
     }
-    else if (class_isMetaClass(*(Class *)rval)) {
-	*(id *)ocval = (id)RCLASS_OCID(rval);
-    }
     else {
 	*(id *)ocval = (id)rval;
     }
@@ -697,7 +695,8 @@
     if (*octype == _C_VOID)
 	return;
 
-    if (st_lookup(bs_boxeds, (st_data_t)octype, (st_data_t *)&bs_boxed)) {
+    if (bs_boxeds != NULL
+	&& st_lookup(bs_boxeds, (st_data_t)octype, (st_data_t *)&bs_boxed)) {
 	void *data;
 
 	data = rb_objc_rval_to_boxed_data(rval, bs_boxed, &ok);
@@ -712,7 +711,7 @@
 	goto bails; 
     }
 
-    if (st_lookup(bs_cftypes, (st_data_t)octype, NULL))
+    if (bs_cftypes != NULL && st_lookup(bs_cftypes, (st_data_t)octype, NULL))
 	octype = "@";
 
     if (*octype != _C_BOOL && *octype != _C_ID) {
@@ -854,7 +853,7 @@
 VALUE
 rb_objc_boot_ocid(id ocid)
 {
-    if (rb_objc_is_non_native((VALUE)ocid)) {
+    if (NATIVE((VALUE)ocid)) {
         /* Make sure the ObjC class is imported in Ruby. */ 
         rb_objc_import_class(object_getClass(ocid)); 
     }
@@ -909,13 +908,15 @@
     {
 	bs_element_boxed_t *bs_boxed;
 
-	if (st_lookup(bs_boxeds, (st_data_t)octype, 
+	if (bs_boxeds != NULL
+	    && st_lookup(bs_boxeds, (st_data_t)octype, 
 		      (st_data_t *)&bs_boxed)) {
 	    *rbval = rb_bs_boxed_new_from_ocdata(bs_boxed, ocval);
 	    goto bails; 
 	}
 
-	if (st_lookup(bs_cftypes, (st_data_t)octype, NULL))
+	if (bs_cftypes != NULL 
+	    && st_lookup(bs_cftypes, (st_data_t)octype, NULL))
 	    octype = "@";
     }
     
@@ -1024,6 +1025,7 @@
     rb_raise(rb_eRuntimeError, "%s: %s", name, desc);
 }
 
+#if 0
 static bs_element_method_t *
 rb_bs_find_method(Class klass, SEL sel)
 {
@@ -1046,6 +1048,7 @@
 
     return NULL;
 }
+#endif
 
 static const char *
 rb_objc_method_get_type(Method method, unsigned count, 
@@ -1077,8 +1080,6 @@
     return type;
 }
 
-extern NODE *rb_current_cfunc_node;
-
 struct objc_ruby_closure_context {
     SEL selector;
     bs_element_method_t *bs_method;
@@ -1100,6 +1101,8 @@
     char buf[128];
     void *imp;
 
+    DLOG("OCALL", "[%p %s] argc=%d", ocrcv, (char *)ctx->selector, argc);
+
     count = method_getNumberOfArguments(ctx->method);
     assert(count >= 2);
 
@@ -1231,6 +1234,7 @@
     }
 }
 
+#if 0
 static VALUE
 rb_objc_to_ruby_closure(int argc, VALUE *argv, VALUE rcv)
 {
@@ -1296,7 +1300,93 @@
 
     return rb_objc_call_objc(argc, argv, ocrcv, klass, super_call, ctx);
 }
+#endif
 
+VALUE
+rb_objc_call(VALUE recv, ID mid, int argc, VALUE *argv)
+{
+    VALUE klass;
+    SEL sel;
+    IMP imp;
+    NODE *node;
+
+    klass = CLASS_OF(recv);
+    node = rb_objc_method_node(klass, mid, &imp, &sel);
+
+    if (imp == NULL) {
+	// TODO
+	printf("METHOD_MISSING!");
+	assert(1 == 0);
+	return Qnil;
+    }
+    else if (node != NULL) {
+	assert(node->nd_body != NULL);
+
+	DLOG("RCALL", "[<%s %p> %s] node=%p argc=%d", class_getName((Class)klass), (void *)recv, (char *)sel, node->nd_body, argc);
+
+	VALUE rb_vm_call(rb_thread_t * th, VALUE klass, VALUE recv, VALUE id, 
+		ID oid, int argc, const VALUE *argv, const NODE *body, 
+		int nosuper);
+
+	return rb_vm_call(GET_THREAD(), klass, recv, mid, Qnil,
+		argc, argv, node->nd_body, 0);
+    }
+    else {
+	id ocrcv;
+	struct objc_ruby_closure_context fake_ctx;
+
+	rb_objc_rval_to_ocid(recv, (void **)&ocrcv, true);
+
+	fake_ctx.selector = sel;
+	fake_ctx.method = class_getInstanceMethod((Class)klass, fake_ctx.selector); 
+	assert(fake_ctx.method != NULL);
+	fake_ctx.bs_method = NULL;
+	fake_ctx.cif = NULL;
+	fake_ctx.imp = imp;
+	fake_ctx.klass = NULL;
+
+	return rb_objc_call_objc(argc, argv, ocrcv, (Class)klass, true, &fake_ctx);
+    }
+}
+
+void
+rb_objc_alias(VALUE klass, ID name, ID def)
+{
+    const char *name_str, *def_str;
+    SEL name_sel, def_sel;
+    Method method;
+
+    name_str = rb_id2name(name);
+    def_str = rb_id2name(def);
+
+    name_sel = sel_registerName(name_str);
+    def_sel = sel_registerName(def_str);
+
+    method = class_getInstanceMethod((Class)klass, def_sel);
+    if (method == NULL) {
+	if (def_str[strlen(def_str) - 1] != ':') {
+	    char buf[512];
+	    strlcpy(buf, def_str, sizeof buf);
+	    strlcat(buf, ":", sizeof buf);
+	    def_sel = sel_registerName(buf);
+	    method = class_getInstanceMethod((Class)klass, def_sel);
+	    if (method == NULL)
+		rb_print_undef(klass, def, 0);
+	    if (name_str[strlen(name_str) - 1] != ':') {
+		strlcpy(buf, name_str, sizeof buf);
+		strlcat(buf, ":", sizeof buf);
+		name_sel = sel_registerName(buf);
+	    }
+	}
+    }
+
+    DLOG("ALIAS", "[%s %s -> %s]", class_getName((Class)klass), (char *)name_sel, (char *)def_sel);
+
+    assert(class_addMethod((Class)klass, name_sel, 
+			   method_getImplementation(method), 
+			   method_getTypeEncoding(method)));
+}
+
 static VALUE
 rb_super_objc_send(int argc, VALUE *argv, VALUE rcv)
 {
@@ -1340,11 +1430,12 @@
     char type[128];
     long i, argc;
     VALUE *argv;
-    NODE *body;
+    NODE *body, *node;
 
     rcv = (*(id **)args)[0];
     sel = (*(SEL **)args)[1];
     body = (NODE *)userdata;
+    node = body->nd_body;
 
     method = class_getInstanceMethod(*(Class *)rcv, sel);
     assert(method != NULL);
@@ -1363,14 +1454,14 @@
 
     mid = rb_intern((const char *)sel);
 
-//NSLog(@"ObjC -> Ruby [%@ mid=%s]\n", rrcv, rb_id2name(mid));
+    DLOG("RCALL", "[%p %s] node=%p argc=%ld", (void *)rrcv, (char *)sel, body, argc);
 
     VALUE rb_vm_call(rb_thread_t * th, VALUE klass, VALUE recv, VALUE id, 
 		     ID oid, int argc, const VALUE *argv, const NODE *body, 
 		     int nosuper);
 
     ret = rb_vm_call(GET_THREAD(), CLASS_OF(rrcv), rrcv, mid, Qnil,
-		     argc, argv, body, 0);
+		     argc, argv, node, 0);
 
     method_getReturnType(method, type, sizeof type);
     rb_objc_rval_to_ocval(ret, type, resp);
@@ -1407,289 +1498,257 @@
 	!= FFI_OK)
 	rb_fatal("can't prepare ruby to objc closure");
 
+    rb_objc_retain(node);
+
     return closure;
 }
 
+NODE *
+rb_objc_method_node2(VALUE mod, SEL sel, IMP *pimp)
+{
+    IMP imp;
+
+    if (pimp != NULL)
+	*pimp = NULL;
+
+    imp = class_getMethodImplementation((Class)mod, sel);
+    extern void *_objc_msgForward;
+    if (imp == (IMP)&_objc_msgForward)
+	imp = NULL;
+
+    if (pimp != NULL)
+	*pimp = imp;
+
+    if (imp == NULL || ((ffi_closure *)imp)->fun != rb_ruby_to_objc_closure_handler)
+	return NULL;
+
+    return ((ffi_closure *)imp)->user_data;
+}
+
+NODE *
+rb_objc_method_node(VALUE mod, ID mid, IMP *pimp, SEL *psel)
+{
+    SEL sel;
+    IMP imp;
+    NODE *node;
+
+    if (mid == ID_ALLOCATOR)
+	sel = @selector(alloc);
+    else
+	sel = sel_registerName(rb_id2name(mid));
+
+    if (psel != NULL)
+	*psel = sel;
+
+    node = rb_objc_method_node2(mod, sel, &imp);
+
+    if (pimp != NULL)
+	*pimp = imp;
+
+    if (imp == NULL) {
+    	char buf[512];
+	strlcpy(buf, (char *)sel, sizeof buf);
+	if (buf[strlen(buf) - 1] == ':')
+	    return NULL;
+	strlcat(buf, ":", sizeof buf);
+	return rb_objc_method_node2(mod, sel_registerName(buf), pimp);
+    }
+
+    return node;
+}
+
 void
-rb_objc_sync_ruby_method(VALUE mod, ID mid, NODE *node, unsigned override)
+rb_objc_register_ruby_method(VALUE mod, ID mid, NODE *body)
 {
     SEL sel;
-    Class ocklass;
     Method method;
     char *types;
-    int arity;
+    int arity, oc_arity;
     char *mid_str;
     IMP imp;
     bool direct_override;
+    NODE *node;
+    VALUE included_in_classes;
+    int included_in_classes_count = - 1;
 
-    /* Do not expose C functions. */
-    if (bs_functions != NULL
-	&& mod == CLASS_OF(rb_mKernel)
-	&& st_lookup(bs_functions, (st_data_t)mid, NULL))
-	return;
+#define forward_method_definition(ary,sel,imp,types) \
+    do { \
+	if (included_in_classes != Qnil) { \
+	    int i; \
+	    if (included_in_classes_count == -1) \
+	        included_in_classes_count = RARRAY_LEN(included_in_classes); \
+	    for (i = 0; i < included_in_classes_count; i++) { \
+		VALUE k = RARRAY_AT(included_in_classes, i); \
+		Method m = class_getInstanceMethod((Class)k, sel); \
+		DLOG("DEFI", "-[%s %s]", class_getName((Class)k), (char *)sel); \
+		if (m != NULL) { \
+		    Method m2 = class_getInstanceMethod((Class)RCLASS_SUPER(k), sel); \
+		    if (m != m2) { \
+		        method_setImplementation(m, imp); \
+		        break; \
+		    } \
+	        } \
+	        assert(class_addMethod((Class)k, sel, imp, types)); \
+	    } \
+	} \
+    } \
+    while (0)
 
-    arity = rb_node_arity(node);
-    mid_str = (char *)rb_id2name(mid);
+    if (body != NULL) {
+	if (nd_type(body) != NODE_METHOD) 
+	    rb_bug("non-method node (%d)", nd_type(body));
 
-    if (arity < 0) {
-	//printf("mid %s has negative arity %d\n", mid_str, arity);
-	return;
+	node = body->nd_body;
+	arity = oc_arity = rb_node_arity(node);
     }
+    else {
+	node = NULL;
+	arity = oc_arity = 0;
+    }
 
-    if (arity == 1 && mid_str[strlen(mid_str) - 1] != ':') {
+    if (mid == ID_ALLOCATOR) {
+	mid_str = "alloc";	
+    }
+    else {
+	mid_str = (char *)rb_id2name(mid);
+    }
+
+    included_in_classes = RCLASS_MODULE(mod) ? rb_ivar_get(mod, idIncludedInClasses) : Qnil;
+
+    if ((arity < 0 || arity > 0) && mid_str[strlen(mid_str) - 1] != ':') {
 	char buf[100];
 	snprintf(buf, sizeof buf, "%s:", mid_str);
 	sel = sel_registerName(buf);
+	oc_arity = 1;
     }
     else {
 	sel = sel_registerName(mid_str);
     }
 
-    ocklass = RCLASS_OCID(mod);
     direct_override = false;
-    method = class_getInstanceMethod(ocklass, sel);
+    method = class_getInstanceMethod((Class)mod, sel);
 
     if (method != NULL) {
-	void *klass;
-	if (!override)
-	    return;
+	Class klass;
 
         /* Do not override certain NSObject selectors. */
         if (sel == @selector(superclass)
 	    || sel == @selector(hash)
 	    || sel == @selector(zone)) {
- 	    klass = RCLASS_OCID(rb_cBasicObject);
-	    if (class_getInstanceMethod(klass, sel) == method)
+	    if (class_getInstanceMethod((Class)rb_cBasicObject, sel) == method)
 		return;
 	}
 
-	if (arity >= 0 && arity + 2 != method_getNumberOfArguments(method)) {
-	    rb_warning("cannot override Objective-C method `%s' in " \
+	if (oc_arity + 2 != method_getNumberOfArguments(method)) {
+printf("method %p\n",method);
+	    rb_warn("cannot override Objective-C method `%s' in " \
 		       "class `%s' because of an arity mismatch (%d for %d)", 
-		       (char *)sel, 
-		       class_getName(ocklass), 
-		       arity + 2, 
+		       (char *)method_getName(method),
+		       class_getName((Class)mod), 
+		       oc_arity + 2, 
 		       method_getNumberOfArguments(method));
 	    return;
 	}
 	types = (char *)method_getTypeEncoding(method);
-	klass = class_getSuperclass(ocklass);
+	klass = (Class)RCLASS_SUPER(mod);
 	direct_override = 
 	    klass == NULL || class_getInstanceMethod(klass, sel) != method;
     }
     else {
-	struct st_table *t = class_isMetaClass(ocklass)
+	struct st_table *t = class_isMetaClass((Class)mod)
 	    ? bs_inf_prot_cmethods
 	    : bs_inf_prot_imethods;
 
 	if (t == NULL || !st_lookup(t, (st_data_t)sel, (st_data_t *)&types)) {
-	    types = (char *)alloca((arity + 4) * sizeof(char));
-	    types[0] = '@';
-	    types[1] = '@';
-	    types[2] = ':';
-	    memset(&types[3], '@', arity);
-	    types[arity + 3] = '\0';
+	    if (oc_arity == 0) {
+		types = "@@:";
+	    }
+	    else if (oc_arity == 1) {
+		types = "@@:@";
+	    }
+	    else {
+		int i;
+		types = alloca(3 + oc_arity + 1);
+		types[0] = '@';
+		types[1] = '@';
+		types[2] = ':';
+		for (i = 0; i < oc_arity; i++)
+		    types[3 + i] = '@'; 
+		types[3 + oc_arity] = '\0';
+	    }
 	}
     }
 
-//    printf("registering sel %s of types %s arity %d to class %s\n",
-//	   (char *)sel, types, arity, class_getName(ocklass));
+    DLOG("DEFM", "%c[%s %s] types=%s arity=%d body=%p override=%d direct_override=%d",
+	   class_isMetaClass((Class)mod) ? '+' : '-', class_getName((Class)mod), (char *)sel, types, arity, body, method != NULL, direct_override);
 
-    imp = rb_ruby_to_objc_closure(types, arity, node);
-
-    if (method != NULL && direct_override) {
-	method_setImplementation(method, imp);
+    if (node == NULL) {
+	assert(class_addMethod((Class)mod, sel, NULL, types));
+	forward_method_definition(included_in_classes, sel, NULL, types);
     }
     else {
-	assert(class_addMethod(ocklass, sel, imp, types));	
-    }
-}
+	const char *sel_str = (const char *)sel;
+	const size_t sel_len = strlen(sel_str);
+	SEL new_sel;
+	char *new_types;
+	bool override;
 
-static int
-__rb_objc_add_ruby_method(ID mid, NODE *body, VALUE mod)
-{
-    if (mid == ID_ALLOCATOR)
-	return ST_CONTINUE;
-    
-    if (body == NULL || body->nd_body->nd_body == NULL)
-	return ST_CONTINUE;
+	imp = rb_ruby_to_objc_closure(types, oc_arity, body);
 
-    if ((body->nd_body->nd_noex & NOEX_MASK) != NOEX_PUBLIC)
-	return ST_CONTINUE;
+	if (method != NULL && direct_override) {
+	    method_setImplementation(method, imp);
+	}
+	else {
+	    assert(class_addMethod((Class)mod, sel, imp, types));
+	}
+	forward_method_definition(included_in_classes, sel, imp, types);
 
-    rb_objc_sync_ruby_method(mod, mid, body->nd_body->nd_body, 0);
+	if (sel_str[sel_len - 1] == ':') {
+	    char buf[512];
+	    strlcpy(buf, sel_str, sizeof buf);
+	    assert(sizeof buf > sel_len);
+	    buf[sel_len - 1] = '\0';
+	    new_sel = sel_registerName(buf);
+	    new_types = "@@:";
+	    override = arity == -1;
+	    arity = 0;
+	}
+	else {
+	    char buf[512];
+	    strlcpy(buf, sel_str, sizeof buf);
+	    strlcat(buf, ":", sizeof buf);	
+	    new_sel = sel_registerName(buf);
+	    new_types = "@@:@";
+	    override = false;
+	    arity = -1;
+	}
 
-    return ST_CONTINUE;
-}
-
-void
-rb_objc_sync_ruby_methods(VALUE mod, VALUE klass)
-{
-    for (;;) {
-	st_foreach(RCLASS_M_TBL(mod), __rb_objc_add_ruby_method, 
-		   (st_data_t)klass);
-	mod = RCLASS_SUPER(mod);
-	if (mod == 0 || BUILTIN_TYPE(mod) != T_ICLASS)
-	    break;
+	method = class_getInstanceMethod((Class)mod, new_sel);
+	direct_override = false;
+	if (method != NULL || override) {
+	    direct_override = method != NULL && class_getInstanceMethod((Class)RCLASS_SUPER(mod), new_sel) != method;
+	    DLOG("DEFM", "%c[%s %s] types=%s arity=%d body=%p override=%d direct_override=%d",
+		class_isMetaClass((Class)mod) ? '+' : '-', class_getName((Class)mod), (char *)new_sel, new_types, arity, body, method != NULL, direct_override);
+	    if (method != NULL && direct_override) {
+	 	method_setImplementation(method, imp);	
+	    }
+	    else { 
+		assert(class_addMethod((Class)mod, new_sel, imp, new_types));
+	    }
+	    forward_method_definition(included_in_classes, new_sel, imp, new_types);
+	}
     }
 }
 
-static inline unsigned
-is_ignored_selector(SEL sel)
-{
-#if defined(__ppc__)
-    return sel == (SEL)0xfffef000;
-#elif defined(__i386__)
-    return sel == (SEL)0xfffeb010;
-#else
-# error Unsupported arch
-#endif
-}
-
-#if 0
-static void
-__rb_objc_sync_methods(VALUE mod, Class ocklass)
-{
-    Method *methods;
-    unsigned int i, count;
-    char buffer[128];
-    VALUE imod;
-
-    methods = class_copyMethodList(ocklass, &count);
-
-    imod = mod;
-#if 0
-    for (;;) {
-	st_foreach(RCLASS_M_TBL(imod), __rb_objc_add_ruby_method, 
-		   (st_data_t)mod);
-	imod = RCLASS_SUPER(imod);
-	if (imod == 0 || BUILTIN_TYPE(imod) != T_ICLASS)
-	    break;
-    }
-#endif
-
-    for (i = 0; i < count; i++) {
-	SEL sel;
-	ID mid;
-	st_data_t data;
-	NODE *node;
-
-	sel = method_getName(methods[i]);
-	if (is_ignored_selector(sel))
-	    continue;
-#if IGNORE_PRIVATE_OBJC_METHODS
-	if (*(char *)sel == '_')
-	    continue;
-#endif
-
-	rb_objc_sel_to_mid(sel, buffer, sizeof buffer);
-	mid = rb_intern(buffer);
-
-	if (rb_method_boundp(mod, mid, 1) == Qtrue)
-	    continue;
-
-	node = NEW_CFUNC(rb_objc_to_ruby_closure(methods[i]), -2); 
-	data = (st_data_t)NEW_FBODY(NEW_METHOD(node, mod, 
-		    			       NOEX_WITH_SAFE(NOEX_PUBLIC)), 0);
-
-	st_insert(RCLASS_M_TBL(mod), mid, data);
-    }
-
-    free(methods);
-}
-#endif
-
-NODE *
-rb_objc_define_objc_mid_closure(VALUE recv, ID mid, ID alias_mid)
-{
-    SEL sel;
-    Class ocklass;
-    Method method;
-    VALUE mod;
-    NODE *node, *data;
-    Method (*getMethod)(Class, SEL);
-
-    assert(mid > 1);
-
-    sel = sel_registerName(rb_id2name(mid));
-
-    if (!rb_special_const_p(recv) && !rb_objc_is_non_native(recv) 
-	&& TYPE(recv) == T_CLASS) {
-	mod = recv;
-	getMethod = class_getClassMethod;
-    }
-    else {
-	mod = CLASS_OF(recv);
-	getMethod = class_getInstanceMethod;
-    }
-
-    ocklass = RCLASS_OCID(mod);
-
-    if (class_isMetaClass(ocklass))
-	return NULL;
-
-    method = (*getMethod)(ocklass, sel);
-    if (method == NULL || method_getImplementation(method) == NULL)
-	return NULL;	/* recv doesn't respond to this selector */
-
-    do {
-	Class ocsuper = class_getSuperclass(ocklass);
-	if ((*getMethod)(ocsuper, sel) == NULL) /* != method */
-	    break;
-	ocklass = ocsuper;
-    }
-    while (1);
-
-    if (RCLASS(mod)->ocklass != ocklass) {
-	mod = rb_objc_import_class(ocklass);
-	if (TYPE(recv) == T_CLASS)
-	    mod = CLASS_OF(mod);
-    }
-
-    /* Already defined. */
-    node = rb_method_node(mod, mid);
-    if (node != NULL)
-	return node;
-
-    node = NEW_CFUNC(rb_objc_to_ruby_closure, -1);
-    data = NEW_FBODY(NEW_METHOD(node, mod, 
-				NOEX_WITH_SAFE(NOEX_PUBLIC)), 0);
-
-    rb_add_method_direct(mod, mid, data);
-
-    if (alias_mid != 0)
-	rb_add_method_direct(mod, alias_mid, data);
-
-    return data->nd_body;
-}
-
-#if 0
-rb_objc_sync_objc_methods_into(VALUE mod, Class ocklass)
-{
-    /* Load instance methods */
-    __rb_objc_sync_methods(mod, ocklass);
-
-    /* Load class methods */
-    __rb_objc_sync_methods(rb_singleton_class(mod), 
-			   object_getClass((id)ocklass));
-}
-
-void
-rb_objc_sync_objc_methods(VALUE mod)
-{
-    rb_objc_sync_objc_methods_into(mod, RCLASS_OCID(mod));
-}
-#endif
-
 VALUE
 rb_mod_objc_ancestors(VALUE recv)
 {
-    void *klass;
+    Class klass;
     VALUE ary;
 
     ary = rb_ary_new();
 
-    for (klass = RCLASS(recv)->ocklass; klass != NULL; 
+    for (klass = (Class)recv; klass != NULL; 
 	 klass = class_getSuperclass(klass)) {
 	rb_ary_push(ary, rb_str_new2(class_getName(klass)));		
     }
@@ -1697,29 +1756,6 @@
     return ary;
 }
 
-void 
-rb_objc_methods(VALUE ary, Class ocklass)
-{
-    while (ocklass != NULL) {
-	unsigned i, count;
-	Method *methods;
-
- 	methods = class_copyMethodList(ocklass, &count);
- 	if (methods != NULL) { 
-	    for (i = 0; i < count; i++) {
-		SEL sel = method_getName(methods[i]);
-		if (is_ignored_selector(sel))
-		    continue;
-		rb_ary_push(ary, ID2SYM(rb_intern(sel_getName(sel))));
-	    }
-	    free(methods);
-    	}
-	ocklass = class_getSuperclass(ocklass);
-    }
-
-    rb_funcall(ary, rb_intern("uniq!"), 0);
-}
-
 static bool
 rb_objc_resourceful(VALUE obj)
 {
@@ -1833,15 +1869,10 @@
 		    "constant `%s'", bs_const->name);
 
 	rb_objc_ocval_to_rbval(sym, bs_const->type, &v);
-    
-	/* To avoid a runtime warning when re-defining the constant, we remove
-	 * its entry from the table before.
-	 */
-	klass = rb_cObject;
-	assert(RCLASS_IV_TBL(klass) != NULL);
-	assert(st_delete(RCLASS_IV_TBL(klass), (st_data_t*)&id, NULL));
 
-	rb_const_set(klass, id, v); 
+	CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(rb_cObject);
+	assert(iv_dict != NULL);
+	CFDictionarySetValue(iv_dict, (const void *)id, (const void *)v);
     }
 
     return v;
@@ -2592,18 +2623,19 @@
 }
 
 static void
-rb_install_objc_primitives(void)
+rb_install_boxed_primitives(void)
 {
     Class klass;
 
     /* Boxed */
-    klass = RCLASS_OCID(rb_cBoxed);
+    klass = (Class)rb_cBoxed;
     rb_objc_install_method(klass, @selector(objCType), 
 	(IMP)imp_rb_boxed_objCType);
     rb_objc_install_method(klass, @selector(getValue:), 
 	(IMP)imp_rb_boxed_getValue);
 }
 
+#if 0
 static void *
 rb_objc_allocate(void *klass)
 {
@@ -2640,6 +2672,7 @@
     rb_objc_install_method(RCLASS_OCID(rb_cObject), @selector(init), 
 	(IMP)imp_rb_obj_init);
 }
+#endif
 
 ID
 rb_objc_missing_sel(ID mid, int arity)
@@ -2686,8 +2719,6 @@
 	return mid;
     }
 
-    //printf("new sel %s for %s\n", buf, name);
-
     return rb_intern(buf);	
 }
 
@@ -2787,7 +2818,7 @@
 	strlcat(buf, &symname[1], sizeof buf);
 	strlcat(buf, ":", sizeof buf);
 
-	if (!class_addMethod(RCLASS_OCID(recv), sel_registerName(buf), 
+	if (!class_addMethod((Class)recv, sel_registerName(buf), 
 			     (IMP)rb_objc_ib_outlet_imp, "v@:@"))
 	    rb_raise(rb_eArgError, 
 		     "can't register `%s' (method %s) as an IB outlet",
@@ -3084,6 +3115,7 @@
     rb_define_singleton_method(rb_cBoxed, "objc_type", rb_boxed_objc_type, 0);
     rb_define_singleton_method(rb_cBoxed, "opaque?", rb_boxed_is_opaque, 0);
     rb_define_singleton_method(rb_cBoxed, "fields", rb_boxed_fields, 0);
+    rb_install_boxed_primitives();
 
     rb_cPointer = rb_define_class("Pointer", rb_cObject);
     rb_undef_alloc_func(rb_cPointer);
@@ -3091,8 +3123,7 @@
 
     rb_ivar_type = rb_intern("@__objc_type__");
 
-    rb_install_objc_primitives();
-    rb_install_alloc_methods();
+    //rb_install_alloc_methods();
 
     rb_define_global_function("load_bridge_support_file", rb_objc_load_bs, 1);
 
@@ -3106,6 +3137,9 @@
     rb_define_method(rb_cBasicObject, "__super_objc_send__", rb_super_objc_send, -1);
 }
 
+// for debug in gdb
+int __rb_type(VALUE v) { return TYPE(v); }
+
 @interface Protocol
 @end
 

Modified: MacRuby/branches/lrz_unstable/object.c
===================================================================
--- MacRuby/branches/lrz_unstable/object.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/object.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -126,12 +126,16 @@
 VALUE
 rb_class_real(VALUE cl)
 {
+#if WITH_OBJC
+    return cl;
+#else
     if (cl == 0)
         return 0;
     while ((RBASIC(cl)->flags & FL_SINGLETON) || BUILTIN_TYPE(cl) == T_ICLASS) {
 	cl = RCLASS_SUPER(cl);
     }
     return cl;
+#endif
 }
 
 /*
@@ -158,7 +162,7 @@
 init_copy(VALUE dest, VALUE obj)
 {
 #if WITH_OBJC
-    if (rb_objc_is_non_native(obj)) {
+    if (NATIVE(obj)) {
 	if (rb_objc_flag_check((const void *)obj, FL_TAINT))
 	    rb_objc_flag_set((const void *)dest, FL_TAINT, true);
 	goto call_init_copy;
@@ -173,6 +177,35 @@
     rb_gc_copy_finalizer(dest, obj);
     switch (TYPE(obj)) {
       case T_OBJECT:
+#if WITH_OBJC
+	ROBJECT(dest)->ivars.type = ROBJECT(obj)->ivars.type;
+	switch (RB_IVAR_TYPE(ROBJECT(obj)->ivars)) {
+	    case RB_IVAR_ARY:
+	    {
+		int i;
+		GC_WB(&ROBJECT(dest)->ivars.as.ary,
+		    (struct rb_ivar_ary_entry *)xmalloc(
+			sizeof(struct rb_ivar_ary_entry)
+			    * RB_IVAR_ARY_LEN(ROBJECT(obj)->ivars)));
+		for (i = 0; i < RB_IVAR_ARY_LEN(ROBJECT(obj)->ivars); i++) {
+		    ROBJECT(dest)->ivars.as.ary[i].name = ROBJECT(obj)->ivars.as.ary[i].name;
+		    GC_WB(&ROBJECT(dest)->ivars.as.ary[i].value, ROBJECT(obj)->ivars.as.ary[i].value);
+		}
+	    }
+	    break;
+
+	    case RB_IVAR_TBL:
+	    {
+		CFMutableDictionaryRef new_tbl;
+		new_tbl = CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef)ROBJECT(obj)->ivars.as.tbl);
+		assert(new_tbl != NULL);
+		GC_WB(&ROBJECT(dest)->ivars.as.tbl, new_tbl);
+		CFMakeCollectable(new_tbl);
+	    }
+	    break;
+	}
+	break;
+#else
         if (!(RBASIC(dest)->flags & ROBJECT_EMBED) && ROBJECT_IVPTR(dest)) {
             xfree(ROBJECT_IVPTR(dest));
             ROBJECT(dest)->as.heap.ivptr = 0;
@@ -192,9 +225,29 @@
             ROBJECT(dest)->as.heap.iv_index_tbl = ROBJECT(obj)->as.heap.iv_index_tbl;
             RBASIC(dest)->flags &= ~ROBJECT_EMBED;
         }
+#endif
         break;
       case T_CLASS:
       case T_MODULE:
+#if WITH_OBJC
+	{
+	    CFMutableDictionaryRef dest_dict, obj_dict;
+	    
+	    obj_dict = rb_class_ivar_dict(obj);
+	    dest_dict = rb_class_ivar_dict(dest);
+	    if (dest_dict != NULL)
+		CFDictionaryRemoveAllValues(dest_dict);
+	    if (obj_dict != NULL) {
+		dest_dict = CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef)obj_dict);
+		CFMakeCollectable(dest_dict);
+		rb_class_ivar_set_dict(dest, dest_dict);
+	    }
+	    else {
+		if (dest_dict)
+		    rb_class_ivar_set_dict(dest, NULL);
+	    }
+	}
+#else
 	if (RCLASS_IV_TBL(dest)) {
 	    st_free_table(RCLASS_IV_TBL(dest));
 	    RCLASS_IV_TBL(dest) = 0;
@@ -202,6 +255,7 @@
 	if (RCLASS_IV_TBL(obj)) {
 	    RCLASS_IV_TBL(dest) = st_copy(RCLASS_IV_TBL(obj));
 	}
+#endif
         break;
     }
 call_init_copy:
@@ -241,7 +295,7 @@
         rb_raise(rb_eTypeError, "can't clone %s", rb_obj_classname(obj));
     }
 #if WITH_OBJC
-    if (rb_objc_is_non_native(obj)) {
+    if (NATIVE(obj)) {
         clone = rb_obj_alloc(rb_obj_class(obj));
         init_copy(clone, obj);
 	if (OBJ_FROZEN(obj))
@@ -250,9 +304,6 @@
     }
 #endif
     clone = rb_obj_alloc(rb_obj_class(obj));
-#if WITH_OBJC
-    RBASIC(clone)->isa = RBASIC(obj)->isa;
-#endif
     RBASIC(clone)->klass = rb_singleton_class_clone(obj);
     RBASIC(clone)->flags = (RBASIC(obj)->flags | FL_TEST(clone, FL_TAINT)) & ~(FL_FREEZE|FL_FINALIZE);
     init_copy(clone, obj);
@@ -406,6 +457,30 @@
 
     if (TYPE(obj) == T_OBJECT) {
         int has_ivar = 0;
+#if WITH_OBJC
+	switch (RB_IVAR_TYPE(ROBJECT(obj)->ivars)) {
+	    case RB_IVAR_ARY:
+	    {
+		int i, len = RB_IVAR_ARY_LEN(ROBJECT(obj)->ivars);
+		if (len == 0)
+		    break;
+		for (i = 0; i < len; i++) {
+		    if (ROBJECT(obj)->ivars.as.ary[i].value != Qundef) {
+			has_ivar = 1;
+			break;
+		    }
+		}
+		break;
+	    }
+
+	    case RB_IVAR_TBL:
+		has_ivar = 
+		    CFDictionaryGetCount(
+			(CFDictionaryRef)ROBJECT(obj)->ivars.as.tbl)
+		    	    > 0;
+		break;
+	}
+#else
         VALUE *ptr = ROBJECT_IVPTR(obj);
         long len = ROBJECT_NUMIV(obj);
         long i;
@@ -416,6 +491,7 @@
                 break;
             }
         }
+#endif
 
         if (has_ivar) {
             VALUE str;
@@ -496,7 +572,11 @@
     }
 
     while (cl) {
+#if WITH_OBJC
+	if (cl == c) // TODO check included modules
+#else
 	if (cl == c || RCLASS_M_TBL(cl) == RCLASS_M_TBL(c))
+#endif
 	    return Qtrue;
 	cl = RCLASS_SUPER(cl);
     }
@@ -677,7 +757,7 @@
 rb_obj_tainted(VALUE obj)
 {
 #if WITH_OBJC
-    if (!SPECIAL_CONST_P(obj) && rb_objc_is_non_native(obj)) {
+    if (!SPECIAL_CONST_P(obj) && NATIVE(obj)) {
 	return rb_objc_flag_check((const void *)obj, FL_TAINT) ? Qtrue : Qfalse;
     }
 #endif
@@ -700,7 +780,7 @@
 {
     rb_secure(4);
 #if WITH_OBJC
-    if (!SPECIAL_CONST_P(obj) && rb_objc_is_non_native(obj)) {
+    if (!SPECIAL_CONST_P(obj) && NATIVE(obj)) {
 	rb_objc_flag_set((const void *)obj, FL_TAINT, true);
 	return obj;
     }
@@ -727,7 +807,7 @@
 {
     rb_secure(3);
 #if WITH_OBJC
-    if (!SPECIAL_CONST_P(obj) && rb_objc_is_non_native(obj)) {
+    if (!SPECIAL_CONST_P(obj) && NATIVE(obj)) {
 	rb_objc_flag_set((const void *)obj, FL_TAINT, false);
 	return obj;
     }
@@ -772,6 +852,7 @@
 rb_obj_freeze(VALUE obj)
 {
     if (!OBJ_FROZEN(obj)) {
+	int type;
 	if (rb_safe_level() >= 4 && !OBJ_TAINTED(obj)) {
 	    rb_raise(rb_eSecurityError, "Insecure: can't freeze object");
 	}
@@ -783,9 +864,12 @@
 	    st_insert(immediate_frozen_tbl, obj, (st_data_t)Qtrue);
 	}
 #if WITH_OBJC
-	else if (rb_objc_is_non_native(obj)) {
+	else if (NATIVE(obj)) {
 	    rb_objc_flag_set((const void *)obj, FL_FREEZE, true);
 	}
+	else if ((type = TYPE(obj)) == T_CLASS || type == T_MODULE) {
+	    RCLASS_SET_VERSION_FLAG(obj, RCLASS_IS_FROZEN);
+	}
 #endif
 	else {
 	    FL_SET(obj, FL_FREEZE);
@@ -814,11 +898,15 @@
 	return Qfalse;
     }
 #if WITH_OBJC
-    if (rb_objc_is_non_native(obj)) {
+    if (NATIVE(obj)) {
 	return rb_objc_is_immutable(obj) 
 	    || rb_objc_flag_check((const void *)obj, FL_FREEZE)
 	    ? Qtrue : Qfalse;
     }
+    int type = TYPE(obj);
+    if (type == T_CLASS || type == T_MODULE) {
+	return (RCLASS_VERSION(obj) & RCLASS_IS_FROZEN) == RCLASS_IS_FROZEN ? Qtrue : Qfalse;
+    }
 #endif
     if (FL_TEST(obj, FL_FREEZE)) return Qtrue;
     return Qfalse;
@@ -1155,7 +1243,7 @@
 static VALUE
 rb_mod_to_s(VALUE klass)
 {
-    if (FL_TEST(klass, FL_SINGLETON)) {
+    if (RCLASS_SINGLETON(klass)) {
 	VALUE s = rb_usascii_str_new2("#<");
 	VALUE v = rb_iv_get(klass, "__attached__");
 
@@ -1220,7 +1308,9 @@
 VALUE
 rb_class_inherited_p(VALUE mod, VALUE arg)
 {
+#if !WITH_OBJC
     VALUE start = mod;
+#endif
 
     if (mod == arg) return Qtrue;
     switch (TYPE(arg)) {
@@ -1230,6 +1320,8 @@
       default:
 	rb_raise(rb_eTypeError, "compared with non class/module");
     }
+#if WITH_OBJC // TODO
+#else
     while (mod) {
 	if (RCLASS_M_TBL(mod) == RCLASS_M_TBL(arg))
 	    return Qtrue;
@@ -1241,6 +1333,7 @@
 	    return Qfalse;
 	arg = RCLASS_SUPER(arg);
     }
+#endif
     return Qnil;
 }
 
@@ -1416,8 +1509,7 @@
     }
     RCLASS_SUPER(klass) = super;
 #if WITH_OBJC
-    class_setSuperclass(RCLASS(klass)->ocklass, RCLASS(super)->ocklass);
-    rb_objc_install_primitives(RCLASS(klass)->ocklass, RCLASS(super)->ocklass);
+    rb_objc_install_primitives((Class)klass, (Class)super);
 #endif
     rb_make_metaclass(klass, RBASIC(super)->klass);
     rb_class_inherited(super, klass);
@@ -1443,7 +1535,7 @@
     if (RCLASS_SUPER(klass) == 0 && klass != rb_cBasicObject) {
 	rb_raise(rb_eTypeError, "can't instantiate uninitialized class");
     }
-    if (FL_TEST(klass, FL_SINGLETON)) {
+    if (RCLASS_SINGLETON(klass)) {
 	rb_raise(rb_eTypeError, "can't create instance of singleton class");
     }
     obj = rb_funcall(klass, ID_ALLOCATOR, 0, 0);
@@ -1480,7 +1572,7 @@
 {
     VALUE obj;
 
-#if WITH_OBJC
+#if 0//WITH_OBJC
     if (FL_TEST(klass, RCLASS_OBJC_IMPORTED)) {
 	static SEL sel_new = 0;
 	if (sel_new == 0)
@@ -1720,9 +1812,6 @@
 
 	args[0] = Qtrue;
 	ary = rb_class_instance_methods(1, args, CLASS_OF(obj));
-#if WITH_OBJC
-	rb_objc_methods(ary, RCLASS(CLASS_OF(obj))->ocklass);
-#endif
 	return ary;
     }
     else {
@@ -2361,13 +2450,12 @@
 
 #if WITH_OBJC
 static VALUE
-rb_obj_is_pure(VALUE recv)
+rb_obj_is_native(VALUE recv)
 {
-    return rb_objc_is_non_native(recv) ? Qtrue : Qfalse;
+    return NATIVE(recv) ? Qtrue : Qfalse;
 }
 #endif
 
-
 /*
  *  Document-class: Class
  *
@@ -2453,7 +2541,8 @@
     VALUE metaclass;
 
 #if WITH_OBJC
-    rb_cBasicObject = rb_objc_import_class((Class)objc_getClass("NSObject"));
+    rb_cBasicObject = boot_defclass("BasicObject", rb_objc_import_class((Class)objc_getClass("NSObject")));
+    RCLASS_SET_VERSION_FLAG(rb_cBasicObject, RCLASS_IS_OBJECT_SUBCLASS);
 #else
     rb_cBasicObject = boot_defclass("BasicObject", 0);
 #endif
@@ -2461,13 +2550,24 @@
     rb_cModule = boot_defclass("Module", rb_cObject);
     rb_cClass =  boot_defclass("Class",  rb_cModule);
 
+#if WITH_OBJC
+    metaclass = 0; // eliminate warning
+    RCLASS_SUPER(*(Class *)RCLASS_SUPER(rb_cBasicObject)) = rb_cClass;
+    //metaclass = boot_defclass("MetaClass", rb_cClass);
+    //RCLASS_SUPER(*(Class *)rb_cBasicObject) = rb_cClass;//metaclass;
+#else
     metaclass = rb_make_metaclass(rb_cBasicObject, rb_cClass);
     metaclass = rb_make_metaclass(rb_cObject, metaclass);
     metaclass = rb_make_metaclass(rb_cModule, metaclass);
     metaclass = rb_make_metaclass(rb_cClass, metaclass);
+#endif
 
     rb_define_private_method(rb_cBasicObject, "initialize", rb_obj_dummy, 0);
     rb_define_alloc_func(rb_cBasicObject, rb_class_allocate_instance);
+#if WITH_OBJC
+    // required because otherwise NSObject.new will be first in the method chain.
+    rb_define_singleton_method(rb_cBasicObject, "new", rb_class_new_instance, -1);
+#endif
     rb_define_method(rb_cBasicObject, "==", rb_obj_equal, 1);
     rb_define_method(rb_cBasicObject, "equal?", rb_obj_equal, 1);
     rb_define_method(rb_cBasicObject, "!", rb_obj_not, 0);
@@ -2478,11 +2578,7 @@
     rb_define_private_method(rb_cBasicObject, "singleton_method_undefined", rb_obj_dummy, 1);
 
     rb_mKernel = rb_define_module("Kernel");
-#if WITH_OBJC
-    rb_include_module(rb_cBasicObject, rb_mKernel);
-#else
     rb_include_module(rb_cObject, rb_mKernel);
-#endif
     rb_define_private_method(rb_cClass, "inherited", rb_obj_dummy, 1);
     rb_define_private_method(rb_cModule, "included", rb_obj_dummy, 1);
     rb_define_private_method(rb_cModule, "extended", rb_obj_dummy, 1);
@@ -2496,7 +2592,9 @@
     rb_define_method(rb_mKernel, "!~", rb_obj_not_match, 1);
     rb_define_method(rb_mKernel, "eql?", rb_obj_equal, 1);
 
+#if !WITH_OBJC // defined in NSObject
     rb_define_method(rb_mKernel, "class", rb_obj_class, 0);
+#endif
     rb_define_method(rb_mKernel, "clone", rb_obj_clone, 0);
     rb_define_method(rb_mKernel, "dup", rb_obj_dup, 0);
     rb_define_method(rb_mKernel, "initialize_copy", rb_obj_init_copy, 1);
@@ -2527,7 +2625,7 @@
     rb_define_method(rb_mKernel, "tap", rb_obj_tap, 0);
 
 #if WITH_OBJC
-    rb_define_method(rb_mKernel, "__pure__?", rb_obj_is_pure, 0);
+    rb_define_method(rb_mKernel, "__native__?", rb_obj_is_native, 0);
 #endif
 
     rb_define_global_function("sprintf", rb_f_sprintf, -1); /* in sprintf.c */

Modified: MacRuby/branches/lrz_unstable/parse.y
===================================================================
--- MacRuby/branches/lrz_unstable/parse.y	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/parse.y	2008-07-30 02:27:07 UTC (rev 382)
@@ -8711,6 +8711,14 @@
 	n->nd_mid = rb_intern(buf);
 	n->nd_args = new_argv;
     }
+    else if (args != NULL && args->nd_argc >= 1) {
+	char buf[512];
+
+	strlcpy(buf, rb_id2name(n->u2.id), sizeof buf);
+	strlcat(buf, ":", sizeof buf);
+
+	n->nd_mid = rb_intern(buf);
+    }
     return n;
 }
 

Modified: MacRuby/branches/lrz_unstable/proc.c
===================================================================
--- MacRuby/branches/lrz_unstable/proc.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/proc.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -757,7 +757,7 @@
     }
 
     while (rclass != klass &&
-	   (FL_TEST(rclass, FL_SINGLETON) || TYPE(rclass) == T_ICLASS)) {
+	   (RCLASS_SINGLETON(rclass) || TYPE(rclass) == T_ICLASS)) {
 	rclass = RCLASS_SUPER(rclass);
     }
     if (TYPE(klass) == T_ICLASS)
@@ -1080,7 +1080,7 @@
 	struct METHOD *method = (struct METHOD *)DATA_PTR(body);
 	VALUE rclass = method->rclass;
 	if (rclass != mod) {
-	    if (FL_TEST(rclass, FL_SINGLETON)) {
+	    if (RCLASS_SINGLETON(rclass)) {
 		rb_raise(rb_eTypeError,
 			 "can't bind singleton method to a different class");
 	    }
@@ -1299,7 +1299,7 @@
 
     Data_Get_Struct(method, struct METHOD, data);
     if (data->rclass != CLASS_OF(recv)) {
-	if (FL_TEST(data->rclass, FL_SINGLETON)) {
+	if (RCLASS_SINGLETON(data->rclass)) {
 	    rb_raise(rb_eTypeError,
 		     "singleton method called for a different object");
 	}
@@ -1435,7 +1435,7 @@
     rb_str_buf_cat2(str, s);
     rb_str_buf_cat2(str, ": ");
 
-    if (FL_TEST(data->oclass, FL_SINGLETON)) {
+    if (RCLASS_SINGLETON(data->oclass)) {
 	VALUE v = rb_iv_get(data->oclass, "__attached__");
 
 	if (data->recv == Qundef) {

Modified: MacRuby/branches/lrz_unstable/string.c
===================================================================
--- MacRuby/branches/lrz_unstable/string.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/string.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -478,7 +478,7 @@
 	&& klass != rb_cString 
 	&& klass != rb_cStringRuby 
 	&& klass != rb_cSymbol)
-	*(Class *)str = RCLASS_OCID(klass);
+	*(Class *)str = (Class)klass;
     CFMakeCollectable((CFTypeRef)str);
 #else
     NEWOBJ(str, struct RString);
@@ -8378,11 +8378,10 @@
 }
 
 #if WITH_OBJC
-#define NSCFSTRING() (RCLASS_OCID(rb_cCFString))
 
 #define PREPARE_RCV(x) \
     Class old = *(Class *)x; \
-    *(Class *)x = NSCFSTRING();
+    *(Class *)x = (Class)rb_cCFString;
 
 #define RESTORE_RCV(x) \
     *(Class *)x = old;
@@ -8390,7 +8389,7 @@
 bool
 rb_objc_str_is_pure(VALUE str)
 {
-    return *(Class *)str == NSCFSTRING();
+    return *(Class *)str == (Class)rb_cCFString;
 }
 
 static CFIndex
@@ -8521,7 +8520,6 @@
     rb_cString = rb_objc_import_class((Class)objc_getClass("NSString"));
     rb_cStringRuby =
         rb_objc_import_class((Class)objc_getClass("NSMutableString"));
-    FL_UNSET(rb_cStringRuby, RCLASS_OBJC_IMPORTED);
     rb_const_set(rb_cObject, rb_intern("String"), rb_cStringRuby);
     rb_define_method(rb_cString, "__bytestring__?", rb_str_bytestring_m, 0);
 #else

Modified: MacRuby/branches/lrz_unstable/thread.c
===================================================================
--- MacRuby/branches/lrz_unstable/thread.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/thread.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -3102,7 +3102,7 @@
 	if (TYPE(klass) == T_ICLASS) {
 	    klass = RBASIC(klass)->klass;
 	}
-	else if (FL_TEST(klass, FL_SINGLETON)) {
+	else if (RCLASS_SINGLETON(klass)) {
 	    klass = rb_iv_get(klass, "__attached__");
 	}
     }

Modified: MacRuby/branches/lrz_unstable/variable.c
===================================================================
--- MacRuby/branches/lrz_unstable/variable.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/variable.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -19,9 +19,6 @@
 void rb_vm_change_state(void);
 st_table *rb_global_tbl;
 st_table *rb_class_tbl;
-#if WITH_OBJC
-st_table *rb_objc_class_tbl;
-#endif
 static ID autoload, classpath, tmp_classpath;
 
 void
@@ -31,10 +28,6 @@
     GC_ROOT(&rb_global_tbl);
     rb_class_tbl = st_init_numtable();
     GC_ROOT(&rb_class_tbl);
-#if WITH_OBJC
-    rb_objc_class_tbl = st_init_numtable();
-    GC_ROOT(&rb_objc_class_tbl);
-#endif
     autoload = rb_intern("__autoload__");
     classpath = rb_intern("__classpath__");
     tmp_classpath = rb_intern("__tmp_classpath__");
@@ -56,8 +49,12 @@
     path = rb_str_dup(rb_id2str(name));
     while (fc) {
 	if (fc->track == rb_cObject) break;
+#if WITH_OBJC
+	if ((tmp = rb_attr_get(fc->track, classpath)) != Qnil) {
+#else
 	if (RCLASS_IV_TBL(fc->track) &&
 	    st_lookup(RCLASS_IV_TBL(fc->track), classpath, &tmp)) {
+#endif
 	    tmp = rb_str_dup(tmp);
 	    rb_str_cat2(tmp, "::");
 	    rb_str_append(tmp, path);
@@ -86,7 +83,13 @@
     switch (TYPE(value)) {
       case T_MODULE:
       case T_CLASS:
+      {
+#if WITH_OBJC
+	CFDictionaryRef iv_dict = rb_class_ivar_dict(value);
+	if (iv_dict == NULL) return ST_CONTINUE;
+#else
 	if (!RCLASS_IV_TBL(value)) return ST_CONTINUE;
+#endif
 	else {
 	    struct fc_result arg;
 	    struct fc_result *list;
@@ -102,13 +105,18 @@
 	    arg.klass = res->klass;
 	    arg.track = value;
 	    arg.prev = res;
+#if WITH_OBJC
+	    rb_hash_foreach((VALUE)iv_dict, fc_i, (VALUE)&arg);
+#else
 	    st_foreach(RCLASS_IV_TBL(value), fc_i, (st_data_t)&arg);
+#endif
 	    if (arg.path) {
 		res->path = arg.path;
 		return ST_STOP;
 	    }
 	}
 	break;
+      }
 
       default:
 	break;
@@ -126,18 +134,32 @@
     arg.klass = klass;
     arg.track = rb_cObject;
     arg.prev = 0;
+
+#if WITH_OBJC
+    CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(rb_cObject);
+    if (iv_dict != NULL) {
+	rb_hash_foreach((VALUE)iv_dict, fc_i, (VALUE)&arg);
+    }
+#else
     if (RCLASS_IV_TBL(rb_cObject)) {
 	st_foreach_safe(RCLASS_IV_TBL(rb_cObject), fc_i, (st_data_t)&arg);
     }
+#endif
     if (arg.path == 0) {
 	st_foreach_safe(rb_class_tbl, fc_i, (st_data_t)&arg);
     }
     if (arg.path) {
+#if WITH_OBJC
+	iv_dict = rb_class_ivar_dict_or_create(klass);
+	CFDictionarySetValue(iv_dict, (const void *)classpath, (const void *)arg.path);
+	CFDictionaryRemoveValue(iv_dict, (const void *)tmp_classpath);
+#else
 	if (!RCLASS_IV_TBL(klass)) {
 	    GC_WB(&RCLASS_IV_TBL(klass), st_init_numtable());
 	}
 	st_insert(RCLASS_IV_TBL(klass), classpath, arg.path);
 	st_delete(RCLASS_IV_TBL(klass), &tmp_classpath, 0);
+#endif
 	return arg.path;
     }
     return Qnil;
@@ -149,6 +171,25 @@
     VALUE path = Qnil;
 
     if (!klass) klass = rb_cObject;
+#if WITH_OBJC
+    CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(klass);
+    if (iv_dict != NULL) {
+	if (!CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict, 
+	    (const void *)classpath, (const void **)&path)) {
+
+	    static ID classid = 0;
+	    if (classid == 0)
+		classid = rb_intern("__classid__");
+
+	    if (!CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict, 
+		(const void *)classid, (const void **)&path))
+		return find_class_path(klass);
+
+	    path = rb_str_dup(rb_id2str(SYM2ID(path)));
+	    OBJ_FREEZE(path);
+	    CFDictionarySetValue(iv_dict, (const void *)classpath, (const void *)path);
+	    CFDictionaryRemoveValue(iv_dict, (const void *)classid);
+#else
     if (RCLASS_IV_TBL(klass)) {
 	if (!st_lookup(RCLASS_IV_TBL(klass), classpath, &path)) {
 	    ID classid = rb_intern("__classid__");
@@ -160,12 +201,11 @@
 	    OBJ_FREEZE(path);
 	    st_insert(RCLASS_IV_TBL(klass), classpath, path);
 	    st_delete(RCLASS_IV_TBL(klass), (st_data_t*)&classid, 0);
+#endif
 	}
-#if !WITH_OBJC
 	if (TYPE(path) != T_STRING) {
 	    rb_bug("class path is not set properly");
 	}
-#endif
 	return path;
     }
     return find_class_path(klass);
@@ -193,8 +233,12 @@
     VALUE path = classname(klass);
 
     if (!NIL_P(path)) return path;
+#if WITH_OBJC
+    if ((path = rb_attr_get(klass, tmp_classpath)) != Qnil) {
+#else
     if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),
 					   tmp_classpath, &path)) {
+#endif
 	return path;
     }
     else {
@@ -1078,21 +1122,115 @@
 #endif
 }
 
+#if WITH_OBJC
+# define RCLASS_RUBY_IVAR_DICT(mod) (*(CFMutableDictionaryRef *)((void *)mod + class_getInstanceSize(*(Class *)RCLASS_SUPER(mod))))
+CFMutableDictionaryRef 
+rb_class_ivar_dict(VALUE mod)
+{
+    CFMutableDictionaryRef dict;
+
+    if (RCLASS_RUBY(mod)) {
+	dict = RCLASS_RUBY_IVAR_DICT(mod);
+    }
+    else {
+	dict = NULL;
+	if (generic_iv_dict != NULL) {
+	    CFDictionaryGetValueIfPresent(generic_iv_dict, 
+		(const void *)mod, (const void **)&dict);
+	} 
+    }
+    return dict;
+}
+
+void
+rb_class_ivar_set_dict(VALUE mod, CFMutableDictionaryRef dict)
+{
+    if (RCLASS_RUBY(mod)) {
+	CFMutableDictionaryRef old_dict = RCLASS_RUBY_IVAR_DICT(mod);
+	if (old_dict != dict) {
+	    if (old_dict != NULL)
+		CFRelease(old_dict);
+	    CFRetain(dict);
+	    RCLASS_RUBY_IVAR_DICT(mod) = dict;
+	}
+    }
+    else {
+	if (generic_iv_dict == NULL) {
+	    CFDictionaryValueCallBacks values_cb;
+
+	    memset(&values_cb, 0, sizeof(values_cb));
+	    values_cb.retain = rb_cfdictionary_retain_cb;
+	    values_cb.release = rb_cfdictionary_release_cb;
+
+	    generic_iv_dict = CFDictionaryCreateMutable(NULL, 0, NULL, &values_cb);
+	}
+	CFDictionarySetValue(generic_iv_dict, (const void *)mod, (const void *)dict);
+    }
+}
+
+CFMutableDictionaryRef
+rb_class_ivar_dict_or_create(VALUE mod)
+{
+    CFMutableDictionaryRef dict;
+
+    dict = rb_class_ivar_dict(mod);
+    if (dict == NULL) {
+	CFDictionaryValueCallBacks values_cb;
+
+	memset(&values_cb, 0, sizeof(values_cb));
+	values_cb.retain = rb_cfdictionary_retain_cb;
+	values_cb.release = rb_cfdictionary_release_cb;
+
+	dict = CFDictionaryCreateMutable(NULL, 0, NULL, &values_cb);
+	rb_class_ivar_set_dict(mod, dict);
+	CFMakeCollectable(dict);
+    }
+    return dict;
+}
+#endif
+
 static VALUE
 ivar_get(VALUE obj, ID id, int warn)
 {
-    VALUE val, *ptr;
+    VALUE val;
+#if !WITH_OBJC
+    VALUE *ptr;
     struct st_table *iv_index_tbl;
     long len;
     st_data_t index;
+#endif
 
 #if WITH_OBJC
-    if (!rb_special_const_p(obj) && rb_objc_is_non_native(obj))
+    if (!rb_special_const_p(obj) && NATIVE(obj))
 	return generic_ivar_get(obj, id, warn);
 #endif
 
     switch (TYPE(obj)) {
       case T_OBJECT:
+#if WITH_OBJC
+	switch (RB_IVAR_TYPE(ROBJECT(obj)->ivars)) {
+	    case RB_IVAR_ARY: 
+	    {
+		int i;
+		val = Qundef;
+		for (i = 0; i < RB_IVAR_ARY_LEN(ROBJECT(obj)->ivars); i++) {
+		    if (ROBJECT(obj)->ivars.as.ary[i].name == id) {
+			val = ROBJECT(obj)->ivars.as.ary[i].value;
+			break;		    
+		    }
+		}
+		break;
+	    }
+
+	    case RB_IVAR_TBL:
+		if (!CFDictionaryGetValueIfPresent(
+		    (CFDictionaryRef)ROBJECT(obj)->ivars.as.tbl,
+		    (const void *)id,
+		    (const void **)val))
+		    val = Qundef;
+		break;
+	}
+#else
         len = ROBJECT_NUMIV(obj);
         ptr = ROBJECT_IVPTR(obj);
         iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
@@ -1100,13 +1238,24 @@
         if (!st_lookup(iv_index_tbl, id, &index)) break;
         if (len <= index) break;
         val = ptr[index];
+#endif
         if (val != Qundef)
             return val;
 	break;
       case T_CLASS:
       case T_MODULE:
+#if WITH_OBJC
+      {
+	  CFDictionaryRef iv_dict = rb_class_ivar_dict(obj);
+	  if (iv_dict != NULL 
+	      && CFDictionaryGetValueIfPresent(
+		  iv_dict, (const void *)id, (const void **)&val))
+	      return val;
+      }
+#else
 	if (RCLASS_IV_TBL(obj) && st_lookup(RCLASS_IV_TBL(obj), id, &val))
 	    return val;
+#endif
 	break;
       default:
 	if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
@@ -1134,16 +1283,18 @@
 VALUE
 rb_ivar_set(VALUE obj, ID id, VALUE val)
 {
+#if !WITH_OBJC
     struct st_table *iv_index_tbl;
     st_data_t index;
     long i, len;
     int ivar_extended;
+#endif
 
     if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
 	rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
     if (OBJ_FROZEN(obj)) rb_error_frozen("object");
 #if WITH_OBJC
-    if (!rb_special_const_p(obj) && rb_objc_is_non_native(obj)) {
+    if (!rb_special_const_p(obj) && NATIVE(obj)) {
 	rb_objc_flag_set((const void *)obj, FL_EXIVAR, true);
 	generic_ivar_set(obj, id, val);
 	return val;
@@ -1151,6 +1302,78 @@
 #endif
     switch (TYPE(obj)) {
       case T_OBJECT:
+#if WITH_OBJC
+	switch (RB_IVAR_TYPE(ROBJECT(obj)->ivars)) {
+	    case RB_IVAR_ARY: 
+	    {
+		int i, len;
+		bool new_ivar;
+
+		len = RB_IVAR_ARY_LEN(ROBJECT(obj)->ivars);
+		new_ivar = true;
+
+		if (len == 0) {
+		    assert(ROBJECT(obj)->ivars.as.ary == NULL);
+		    GC_WB(&ROBJECT(obj)->ivars.as.ary,
+			(struct rb_ivar_ary_entry *)xmalloc(
+			    sizeof(struct rb_ivar_ary_entry)));
+		}
+		else {
+		    assert(ROBJECT(obj)->ivars.as.ary != NULL);
+		    for (i = 0; i < len; i++) {
+			if (ROBJECT(obj)->ivars.as.ary[i].value == Qundef) {
+			    ROBJECT(obj)->ivars.as.ary[i].name = id;	
+			    GC_WB(&ROBJECT(obj)->ivars.as.ary[i].value, val);
+			    new_ivar = false;
+			    break;
+			}
+			else if (ROBJECT(obj)->ivars.as.ary[i].name == id) {
+			    GC_WB(&ROBJECT(obj)->ivars.as.ary[i].value, val);
+			    new_ivar = false;
+			    break;
+			}
+		    }
+		}
+		if (new_ivar) {
+		    if (len + 1 == RB_IVAR_ARY_MAX) {
+			CFMutableDictionaryRef tbl;
+			CFDictionaryValueCallBacks values_cb;
+
+			memset(&values_cb, 0, sizeof(values_cb));
+			values_cb.retain = rb_cfdictionary_retain_cb;
+			values_cb.release = rb_cfdictionary_release_cb;
+
+			tbl = CFDictionaryCreateMutable(NULL, 0, NULL, &values_cb);
+
+			for (i = 0; i < len; i++)
+			    CFDictionarySetValue(tbl, 
+				(const void *)ROBJECT(obj)->ivars.as.ary[i].name, 
+				(const void *)ROBJECT(obj)->ivars.as.ary[i].value);
+
+			xfree(ROBJECT(obj)->ivars.as.ary);
+			GC_WB(&ROBJECT(obj)->ivars.as.tbl, tbl);
+			RB_IVAR_SET_TYPE(ROBJECT(obj)->ivars, RB_IVAR_TBL);
+		    }
+		    else {
+			if (len > 0) {
+			    struct rb_ivar_ary_entry *ary;
+			    ary = ROBJECT(obj)->ivars.as.ary;
+			    REALLOC_N(ary, struct rb_ivar_ary_entry, len + 1);	    
+			    GC_WB(&ROBJECT(obj)->ivars.as.ary, ary);
+			}
+			ROBJECT(obj)->ivars.as.ary[len].name = id;
+			GC_WB(&ROBJECT(obj)->ivars.as.ary[len].value, val);
+			RB_IVAR_ARY_SET_LEN(ROBJECT(obj)->ivars, len + 1);
+		    }
+		}
+		break;
+	    }
+
+	    case RB_IVAR_TBL:
+		CFDictionarySetValue(ROBJECT(obj)->ivars.as.tbl, (const void *)id, (const void *)val);
+		break;
+	}
+#else
         iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
         if (!iv_index_tbl) {
             VALUE klass = rb_obj_class(obj);
@@ -1200,14 +1423,23 @@
             }
         }
         GC_WB(&ROBJECT_IVPTR(obj)[index], val);
+#endif
 	break;
       case T_CLASS:
       case T_MODULE:
+#if WITH_OBJC
+      {
+	  CFMutableDictionaryRef iv_dict = rb_class_ivar_dict_or_create(obj);
+	  CFDictionarySetValue(iv_dict, (const void *)id, (const void *)val);
+	  break;
+      }
+#else
 	if (!RCLASS_IV_TBL(obj)) {
 	    GC_WB(&RCLASS_IV_TBL(obj), st_init_numtable());
 	}
 	st_insert(RCLASS_IV_TBL(obj), id, val);
         break;
+#endif
       default:
 	generic_ivar_set(obj, id, val);
 	FL_SET(obj, FL_EXIVAR);
@@ -1220,28 +1452,64 @@
 rb_ivar_defined(VALUE obj, ID id)
 {
     VALUE val;
+#if !WITH_OBJC
     struct st_table *iv_index_tbl;
     st_data_t index;
+#endif
+
 #if WITH_OBJC
-    if (!rb_special_const_p(obj) && rb_objc_is_non_native(obj)) {
+    if (!rb_special_const_p(obj) && NATIVE(obj)) {
 	return generic_ivar_defined(obj, id);
     }
 #endif
     switch (TYPE(obj)) {
       case T_OBJECT:
+#if WITH_OBJC
+	val = Qundef;
+	switch (RB_IVAR_TYPE(ROBJECT(obj)->ivars)) {
+	    case RB_IVAR_ARY:
+	    {
+		int i;
+		for (i = 0; i < RB_IVAR_ARY_LEN(ROBJECT(obj)->ivars); i++) {
+		    if (ROBJECT(obj)->ivars.as.ary[i].name == id) {
+			val = ROBJECT(obj)->ivars.as.ary[i].value;
+			break;
+		    }
+		}
+		break;
+	    }
+
+	    case RB_IVAR_TBL:
+		if (CFDictionaryGetValueIfPresent(
+		    (CFDictionaryRef)ROBJECT(obj)->ivars.as.tbl,
+		    (const void *)id, NULL))
+		    val = Qtrue;
+		break;
+	}
+#else
         iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
         if (!iv_index_tbl) break;
         if (!st_lookup(iv_index_tbl, id, &index)) break;
         if (ROBJECT_NUMIV(obj) <= index) break;
         val = ROBJECT_IVPTR(obj)[index];
+#endif
         if (val != Qundef)
             return Qtrue;
 	break;
       case T_CLASS:
       case T_MODULE:
+#if WITH_OBJC
+      {
+	  CFDictionaryRef iv_dict = rb_class_ivar_dict(obj);
+	  if (iv_dict != NULL && CFDictionaryGetValueIfPresent(iv_dict, (const void *)id, NULL))
+	      return Qtrue;
+	  break;
+      }
+#else
 	if (RCLASS_IV_TBL(obj) && st_lookup(RCLASS_IV_TBL(obj), id, 0))
 	    return Qtrue;
 	break;
+#endif
       default:
 	if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
 	    return generic_ivar_defined(obj, id);
@@ -1256,6 +1524,7 @@
     st_data_t arg;
 };
 
+#if !WITH_OBJC
 static int
 obj_ivar_i(ID key, VALUE index, struct obj_ivar_tag *data)
 {
@@ -1284,22 +1553,52 @@
 
     st_foreach_safe(tbl, obj_ivar_i, (st_data_t)&data);
 }
+#endif
 
 void rb_ivar_foreach(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
 {
 #if WITH_OBJC
-    if (!rb_special_const_p(obj) && rb_objc_is_non_native(obj))
+    if (!rb_special_const_p(obj) && NATIVE(obj))
 	goto generic;
 #endif
     switch (TYPE(obj)) {
       case T_OBJECT:
+#if WITH_OBJC
+	switch (RB_IVAR_TYPE(ROBJECT(obj)->ivars)) {
+	     case RB_IVAR_ARY:
+	     {
+		int i;
+		for (i = 0; i < RB_IVAR_ARY_LEN(ROBJECT(obj)->ivars); i++) {
+		    if ((*func)(ROBJECT(obj)->ivars.as.ary[i].name, 
+				ROBJECT(obj)->ivars.as.ary[i].value, arg) 
+			    	    != ST_CONTINUE)
+			break;
+		}
+		break;
+	     }
+
+	     case RB_IVAR_TBL:
+		 CFDictionaryApplyFunction(ROBJECT(obj)->ivars.as.tbl, 
+		     (CFDictionaryApplierFunction)func, (void *)arg);
+		 break;
+	}
+#else
         obj_ivar_each(obj, func, arg);
+#endif
 	return;
       case T_CLASS:
       case T_MODULE:
+#if WITH_OBJC
+      {
+	  CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(obj);
+	  if (iv_dict != NULL)
+	      rb_hash_foreach((VALUE)iv_dict, func, arg);
+      }
+#else
 	if (RCLASS_IV_TBL(obj)) {
 	    st_foreach_safe(RCLASS_IV_TBL(obj), func, arg);
 	}
+#endif
 	return;
     }
     if (!FL_TEST(obj, FL_EXIVAR) && !rb_special_const_p(obj))
@@ -1390,8 +1689,10 @@
 {
     VALUE val = Qnil;
     ID id = rb_to_id(name);
+#if !WITH_OBJC
     struct st_table *iv_index_tbl;
     st_data_t index;
+#endif
 
     if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
 	rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
@@ -1402,6 +1703,33 @@
 
     switch (TYPE(obj)) {
       case T_OBJECT:
+#if WITH_OBJC
+	switch (RB_IVAR_TYPE(ROBJECT(obj)->ivars)) {
+	    case RB_IVAR_ARY:
+	    {
+		int i;
+		for (i = 0; i < RB_IVAR_ARY_LEN(ROBJECT(obj)->ivars); i++) {
+		    if (ROBJECT(obj)->ivars.as.ary[i].name == id) {
+			val = ROBJECT(obj)->ivars.as.ary[i].value;
+			ROBJECT(obj)->ivars.as.ary[i].value = Qundef;
+			return val;
+		    }
+		}
+		break;
+	    }
+
+	    case RB_IVAR_TBL:
+		if (CFDictionaryGetValueIfPresent(
+		    (CFDictionaryRef)ROBJECT(obj)->ivars.as.tbl,
+		    (const void *)id,
+		    (const void **)val)) {
+		    CFDictionaryRemoveValue(ROBJECT(obj)->ivars.as.tbl, 
+		       (const void *)id);
+		    return val;
+		}
+		break;
+	}
+#else
         iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
         if (!iv_index_tbl) break;
         if (!st_lookup(iv_index_tbl, id, &index)) break;
@@ -1411,13 +1739,25 @@
             ROBJECT_IVPTR(obj)[index] = Qundef;
             return val;
         }
+#endif
 	break;
       case T_CLASS:
       case T_MODULE:
+#if WITH_OBJC
+      {
+	  CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(obj);
+	  if (iv_dict != NULL && CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict, (const void *)id, (const void **)&val)) {
+	      CFDictionaryRemoveValue(iv_dict, (const void *)id);
+	      return val;
+	  }	      
+	  break;
+      }
+#else
 	if (RCLASS_IV_TBL(obj) && st_delete(RCLASS_IV_TBL(obj), (st_data_t*)&id, &val)) {
 	    return val;
 	}
 	break;
+#endif
       default:
 	if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
 	    if (generic_ivar_remove(obj, id, &val)) {
@@ -1486,14 +1826,15 @@
     return Qnil;		/* not reached */
 }
 
+#if WITH_OBJC
+static void *rb_mark_tbl = (void *)0x42;
+#endif
+
 static struct st_table *
 check_autoload_table(VALUE av)
 {
     Check_Type(av, T_DATA);
-    if (
-#if !WITH_OBJC
-	RDATA(av)->dmark != (RUBY_DATA_FUNC)rb_mark_tbl ||
-#endif
+    if (RDATA(av)->dmark != (RUBY_DATA_FUNC)rb_mark_tbl ||
 	RDATA(av)->dfree != (RUBY_DATA_FUNC)st_free_table) {
 	VALUE desc = rb_inspect(av);
 	rb_raise(rb_eTypeError, "wrong autoload table: %s", RSTRING_PTR(desc));
@@ -1514,21 +1855,29 @@
 	rb_raise(rb_eArgError, "empty file name");
     }
 
+#if WITH_OBJC
+    if ((av = rb_attr_get(mod, id)) != Qnil && av != Qundef)
+#else
     if ((tbl = RCLASS_IV_TBL(mod)) && st_lookup(tbl, id, &av) && av != Qundef)
+#endif
 	return;
 
     rb_const_set(mod, id, Qundef);
+#if WITH_OBJC
+    if ((av = rb_attr_get(mod, autoload)) != Qnil) {
+#else
     tbl = RCLASS_IV_TBL(mod);
     if (st_lookup(tbl, autoload, &av)) {
+#endif
 	tbl = check_autoload_table(av);
     }
     else {
+	av = Data_Wrap_Struct(0, rb_mark_tbl, st_free_table, 0);
 #if WITH_OBJC
-	av = Data_Wrap_Struct(0, NULL, st_free_table, 0);
+	rb_ivar_set(mod, autoload, av);
 #else
-	av = Data_Wrap_Struct(0, rb_mark_tbl, st_free_table, 0);
+	st_add_direct(tbl, autoload, av);
 #endif
-	st_add_direct(tbl, autoload, av);
 	DATA_PTR(av) = tbl = st_init_numtable();
     }
     fn = rb_str_new2(file);
@@ -1543,8 +1892,16 @@
     VALUE val;
     st_data_t load = 0;
 
+#if WITH_OBJC
+    CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(mod);
+    assert(iv_dict != NULL);
+    CFDictionaryRemoveValue(iv_dict, (const void *)id);
+    if (CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict, 
+	(const void *)autoload, (const void **)&val)) {
+#else
     st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, 0);
     if (st_lookup(RCLASS_IV_TBL(mod), autoload, &val)) {
+#endif
 	struct st_table *tbl = check_autoload_table(val);
 
 	st_delete(tbl, (st_data_t*)&id, &load);
@@ -1553,9 +1910,13 @@
 	    DATA_PTR(val) = 0;
 	    st_free_table(tbl);
 	    id = autoload;
+#if WITH_OBJC
+	    CFDictionaryRemoveValue(iv_dict, (const void *)id);
+#else
 	    if (st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, &val)) {
 		rb_gc_force_recycle(val);
 	    }
+#endif
 	}
     }
 
@@ -1581,10 +1942,20 @@
     struct st_table *tbl;
     st_data_t load;
 
+#if WITH_OBJC
+    CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(mod);
+    assert(iv_dict != NULL);
+    if (!CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict, 
+	   (const void *)autoload, (const void **)&val)
+	|| (tbl = check_autoload_table(val)) == NULL
+	|| !st_lookup(tbl, id, &load))
+	return Qnil;
+#else
     if (!st_lookup(RCLASS_IV_TBL(mod), autoload, &val) ||
 	!(tbl = check_autoload_table(val)) || !st_lookup(tbl, id, &load)) {
 	return Qnil;
     }
+#endif
     file = ((NODE *)load)->nd_lit;
     Check_Type(file, T_STRING);
     if (RSTRING_LEN(file) == 0) {
@@ -1600,9 +1971,13 @@
 	DATA_PTR(val) = 0;
 	st_free_table(tbl);
 	id = autoload;
+#if WITH_OBJC
+	CFDictionaryRemoveValue(iv_dict, (const void *)id);
+#else
 	if (st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, &val)) {
 	    rb_gc_force_recycle(val);
 	}
+#endif
     }
     return Qnil;
 }
@@ -1610,12 +1985,22 @@
 VALUE
 rb_autoload_p(VALUE mod, ID id)
 {
+#if WITH_OBJC
+    CFDictionaryRef iv_dict = (CFDictionaryRef)rb_class_ivar_dict(mod);
+    VALUE val;
+
+    if (iv_dict == NULL 
+	|| !CFDictionaryGetValueIfPresent(iv_dict, (const void *)id, (const void **)&val)
+	|| val != Qundef)
+	return Qnil;
+#else
     struct st_table *tbl = RCLASS_IV_TBL(mod);
     VALUE val;
 
     if (!tbl || !st_lookup(tbl, id, &val) || val != Qundef) {
 	return Qnil;
     }
+#endif
     return autoload_file(mod, id);
 }
 
@@ -1628,7 +2013,11 @@
     tmp = klass;
   retry:
     while (RTEST(tmp)) {
+#if WITH_OBJC
+	while ((value = rb_attr_get(tmp, id)) != Qnil) {
+#else
 	while (RCLASS_IV_TBL(tmp) && st_lookup(RCLASS_IV_TBL(tmp),id,&value)) {
+#endif
 	    if (value == Qundef) {
 		if (!RTEST(rb_autoload_load(tmp, id))) break;
 		continue;
@@ -1712,7 +2101,13 @@
 	rb_raise(rb_eSecurityError, "Insecure: can't remove constant");
     if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
 
+#if WITH_OBJC
+    CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(mod);
+    if (iv_dict != NULL && CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict, (const void *)id, (const void **)&val)) {
+	CFDictionaryRemoveValue(iv_dict, (const void *)id);
+#else	
     if (RCLASS_IV_TBL(mod) && st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, &val)) {
+#endif
 	if (val == Qundef) {
 	    autoload_delete(mod, id);
 	    val = Qnil;
@@ -1746,9 +2141,15 @@
     if (!tbl) {
 	tbl = st_init_numtable();
     }
+#if WITH_OBJC
+    CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(mod);
+    if (iv_dict != NULL)
+	rb_hash_foreach((VALUE)iv_dict, sv_i, (VALUE)tbl);
+#else
     if (RCLASS_IV_TBL(mod)) {
 	st_foreach_safe(RCLASS_IV_TBL(mod), sv_i, (st_data_t)tbl);
     }
+#endif
     return tbl;
 }
 
@@ -1831,7 +2232,13 @@
     tmp = klass;
   retry:
     while (tmp) {
+#if WITH_OBJC
+	CFDictionaryRef iv_dict = rb_class_ivar_dict(tmp);
+	if (iv_dict != NULL && CFDictionaryGetValueIfPresent(iv_dict, 
+	    (const void *)id, (const void **)&value)) {
+#else
 	if (RCLASS_IV_TBL(tmp) && st_lookup(RCLASS_IV_TBL(tmp), id, &value)) {
+#endif
 	    if (value == Qundef && NIL_P(autoload_file(klass, id)))
 		return Qfalse;
 	    return Qtrue;
@@ -1880,13 +2287,22 @@
 	    rb_error_frozen("class");
 	}
     }
+#if WITH_OBJC
+    CFMutableDictionaryRef iv_dict = rb_class_ivar_dict_or_create(klass);
+#else
     if (!RCLASS_IV_TBL(klass)) {
 	GC_WB(&RCLASS_IV_TBL(klass), st_init_numtable());
     }
-    else if (isconst) {
+    else
+#endif
+    if (isconst) {
 	VALUE value = Qfalse;
 
+#if WITH_OBJC
+	if (CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict, (const void *)id, (const void **)&value)) {
+#else
 	if (st_lookup(RCLASS_IV_TBL(klass), id, &value)) {
+#endif
 	    if (value == Qundef)
 	      autoload_delete(klass, id);
 	    else
@@ -1894,10 +2310,14 @@
 	}
     }
 
-    if(isconst){
+    if (isconst) {
 	rb_vm_change_state();
     }
+#if WITH_OBJC
+    CFDictionarySetValue(iv_dict, (const void *)id, (const void *)val);
+#else
     st_insert(RCLASS_IV_TBL(klass), id, val);
+#endif
 }
 
 void
@@ -1938,11 +2358,17 @@
     return c;
 }
 
+#if WITH_OBJC
+# define IV_LOOKUP(k,i,v) ((iv_dict = rb_class_ivar_dict(k)) != NULL && CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict, (const void *)i, (const void **)(v)))
+#else
+# define IV_LOOKUP(k,i,v) (RCLASS_IV_TBL(k) && st_lookup(RCLASS_IV_TBL(k),(i),(v)))
+#endif
+
 #define CVAR_LOOKUP(v,r) do {\
-    if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),id,(v))) {\
+    if (IV_LOOKUP(klass, id, v)) {\
 	r;\
     }\
-    if (FL_TEST(klass, FL_SINGLETON) ) {\
+    if (RCLASS_SINGLETON(klass)) {\
 	VALUE obj = rb_iv_get(klass, "__attached__");\
 	switch (TYPE(obj)) {\
 	  case T_MODULE:\
@@ -1958,7 +2384,7 @@
 	klass = RCLASS_SUPER(klass);\
     }\
     while (klass) {\
-	if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),id,(v))) {\
+	if (IV_LOOKUP(klass, id, v)) {\
 	    r;\
 	}\
 	klass = RCLASS_SUPER(klass);\
@@ -1969,6 +2395,9 @@
 rb_cvar_set(VALUE klass, ID id, VALUE val)
 {
     VALUE tmp, front = 0, target = 0;
+#if WITH_OBJC
+    CFMutableDictionaryRef iv_dict;
+#endif
 
     tmp = klass;
     CVAR_LOOKUP(0, {if (!front) front = klass; target = klass;});
@@ -1981,8 +2410,12 @@
 			   rb_id2name(id), rb_class2name(original_module(front)),
 			   rb_class2name(original_module(target)));
 	    }
-	    if (BUILTIN_TYPE(front) == T_CLASS) {
+	    if (TYPE(front) == T_CLASS) {
+#if WITH_OBJC
+		CFDictionaryRemoveValue(rb_class_ivar_dict(front), (const void *)did);
+#else
 		st_delete(RCLASS_IV_TBL(front),&did,0);
+#endif
 	    }
 	}
     }
@@ -1996,6 +2429,9 @@
 rb_cvar_get(VALUE klass, ID id)
 {
     VALUE value, tmp, front = 0, target = 0;
+#if WITH_OBJC
+    CFMutableDictionaryRef iv_dict;
+#endif
 
     tmp = klass;
     CVAR_LOOKUP(&value, {if (!front) front = klass; target = klass;});
@@ -2012,7 +2448,11 @@
 		       rb_class2name(original_module(target)));
 	}
 	if (BUILTIN_TYPE(front) == T_CLASS) {
+#if WITH_OBJC
+	    CFDictionaryRemoveValue(rb_class_ivar_dict(front), (const void *)did);
+#else
 	    st_delete(RCLASS_IV_TBL(front),&did,0);
+#endif
 	}
     }
     return value;
@@ -2021,6 +2461,9 @@
 VALUE
 rb_cvar_defined(VALUE klass, ID id)
 {
+#if WITH_OBJC
+    CFMutableDictionaryRef iv_dict;
+#endif
     if (!klass) return Qfalse;
     CVAR_LOOKUP(0,return Qtrue);
     return Qfalse;
@@ -2090,9 +2533,15 @@
 {
     VALUE ary = rb_ary_new();
 
+#if WITH_OBJC
+    CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(obj);
+    if (iv_dict != NULL)
+	rb_hash_foreach((VALUE)iv_dict, cv_i, (VALUE)ary);
+#else
     if (RCLASS_IV_TBL(obj)) {
 	st_foreach_safe(RCLASS_IV_TBL(obj), cv_i, ary);
     }
+#endif
     return ary;
 }
 
@@ -2129,9 +2578,17 @@
 	rb_raise(rb_eSecurityError, "Insecure: can't remove class variable");
     if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
 
+#if WITH_OBJC
+    CFMutableDictionaryRef iv_dict = rb_class_ivar_dict(mod);
+    if (iv_dict != NULL && CFDictionaryGetValueIfPresent((CFDictionaryRef)iv_dict, (const void *)id, (const void **)&val)) {
+	CFDictionaryRemoveValue(iv_dict, (const void *)id);
+	return val;
+    }
+#else
     if (RCLASS_IV_TBL(mod) && st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, &val)) {
 	return val;
     }
+#endif
     if (rb_cvar_defined(mod, id)) {
 	rb_name_error(id, "cannot remove %s for %s",
 		 rb_id2name(id), rb_class2name(mod));

Modified: MacRuby/branches/lrz_unstable/vm.c
===================================================================
--- MacRuby/branches/lrz_unstable/vm.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/vm.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -14,10 +14,6 @@
 #include "ruby/encoding.h"
 #include "gc.h"
 
-#if WITH_OBJC
-NODE *rb_current_cfunc_node = NULL;
-#endif
-
 #include "insnhelper.h"
 #include "vm_insnhelper.c"
 #include "vm_eval.c"
@@ -852,6 +848,12 @@
 /* optimization: redefine management */
 
 VALUE ruby_vm_redefined_flag = 0;
+#if WITH_OBJC
+static void 
+rb_vm_check_redefinition_opt_method(const NODE *node) 
+{
+}
+#else
 static st_table *vm_opt_method_table = 0;
 
 static void
@@ -876,10 +878,12 @@
 	rb_bug("undefined optimized method: %s", rb_id2name(mid));
     }
 }
+#endif
 
 static void
 vm_init_redefined_flag(void)
 {
+#if !WITH_OBJC
     ID mid;
     VALUE bop;
 
@@ -899,16 +903,13 @@
     OP(LTLT, LTLT), (C(String), C(Array));
     OP(AREF, AREF), (C(Array), C(Hash));
     OP(ASET, ASET), (C(Array), C(Hash));
-#if WITH_OBJC
-    OP(Length, LENGTH), (C(Array), C(Hash));
-#else
     OP(Length, LENGTH), (C(Array), C(String), C(Hash));
-#endif
     OP(Succ, SUCC), (C(Fixnum), C(String), C(Time));
     OP(GT, GT), (C(Fixnum));
     OP(GE, GE), (C(Fixnum));
 #undef C
 #undef OP
+#endif
 }
 
 /* evaluator body */

Modified: MacRuby/branches/lrz_unstable/vm_eval.c
===================================================================
--- MacRuby/branches/lrz_unstable/vm_eval.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/vm_eval.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -72,13 +72,7 @@
 	    cfp->method_id = id;
 	    cfp->method_class = klass;
 
-#if WITH_OBJC
-	    rb_current_cfunc_node = (NODE *)body;
-#endif
 	    val = call_cfunc(body->nd_cfnc, recv, body->nd_argc, argc, argv);
-#if WITH_OBJC
-	    rb_current_cfunc_node = NULL;
-#endif
 
 	    if (reg_cfp != th->cfp + 1) {
 		SDR2(reg_cfp);
@@ -188,42 +182,38 @@
     NODE *body, *method;
     int noex;
     ID id = mid;
+#if !WITH_OBJC
     struct cache_entry *ent;
-    rb_thread_t *th = GET_THREAD();
-#if WITH_OBJC
-    unsigned redo = 0;
 #endif
+    rb_thread_t *th = GET_THREAD();
 
-rb_call0_redo:
-
-#if WITH_OBJC
-# define REDO_PERHAPS() \
-    do { \
-	if (!redo && mid != missing) { \
-	    ID newid = rb_objc_missing_sel(mid, argc); \
-	    if (newid != mid) { \
-		id = mid = newid; \
-		redo = 1; \
-		goto rb_call0_redo; \
-	    } \
-	} \
-    } \
-    while (0)
-#else
-# define REDO_PERHAPS()
-#endif
-
     if (!klass) {
 	rb_raise(rb_eNotImpError,
 		 "method `%s' called on terminated object (%p)",
 		 rb_id2name(mid), (void *)recv);
     }
+
+#if WITH_OBJC
+    IMP imp;
+    SEL sel;
+
+    method = rb_objc_method_node(klass, mid, &imp, &sel);    
+
+    if (imp != NULL && method == NULL) {
+	printf("OBJC_CALL!\n");
+	assert(1==0);
+    }
+    else if (method != NULL) {
+	noex = method->nd_noex;
+	klass = method->nd_clss;
+	body = method->nd_body;
+    }
+#else
     /* is it in the method cache? */
     ent = cache + EXPR1(klass, mid);
 
     if (ent->mid == mid && ent->klass == klass) {
 	if (!ent->method) {
-	    REDO_PERHAPS();
 	    return method_missing(recv, mid, argc, argv,
 				  scope == 2 ? NOEX_VCALL : 0);
 	}
@@ -237,8 +227,8 @@
 	klass = method->nd_clss;
 	body = method->nd_body;
     }
+#endif
     else {
-	REDO_PERHAPS();
 	if (scope == 3) {
 	    return method_missing(recv, mid, argc, argv, NOEX_SUPER);
 	}
@@ -246,7 +236,6 @@
 			      scope == 2 ? NOEX_VCALL : 0);
     }
     
-
     if (mid != missing) {
 	/* receiver specified form for private method */
 	if (UNLIKELY(noex)) {

Modified: MacRuby/branches/lrz_unstable/vm_insnhelper.c
===================================================================
--- MacRuby/branches/lrz_unstable/vm_insnhelper.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/vm_insnhelper.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -371,13 +371,7 @@
 
 	reg_cfp->sp -= num + 1;
 
-#if WITH_OBJC
-	rb_current_cfunc_node = (NODE *)mn;
-#endif
 	val = call_cfunc(mn->nd_cfnc, recv, mn->nd_argc, num, reg_cfp->sp + 1);
-#if WITH_OBJC
-	rb_current_cfunc_node = NULL;
-#endif
 
 	if (reg_cfp != th->cfp + 1) {
 	    rb_bug("cfp consistency error - send");
@@ -488,10 +482,50 @@
 static inline VALUE
 vm_call_method(rb_thread_t * const th, rb_control_frame_t * const cfp,
 	       const int num, rb_block_t * const blockptr, const VALUE flag,
-	       const ID id, const NODE * mn, const VALUE recv, VALUE klass)
+	       const ID id, const NODE * mn, const VALUE recv, VALUE klass,
+	       SEL sel)
 {
     VALUE val;
+#if WITH_OBJC
+    IMP imp;
 
+#define STUPID_CACHE 0
+
+#if STUPID_CACHE
+static VALUE c_klass = 0;
+static IMP c_imp = 0;
+static NODE *c_mn = NULL;
+
+if (c_klass == klass) {
+imp = c_imp;
+mn = c_mn;
+}
+else {
+#endif
+
+    NODE *rb_objc_method_node2(VALUE mod, SEL sel, IMP *pimp); 
+
+    if (sel == 0)
+	mn = rb_objc_method_node(klass, id, &imp, &sel);
+    else
+	mn = rb_objc_method_node2(klass, sel, &imp);
+
+#if STUPID_CACHE
+c_klass = klass;
+c_imp = imp;
+c_mn = (NODE*)mn;
+}
+#endif
+
+    if (mn == NULL && imp != NULL) {
+	printf("OBJC_CALL %p %s %p %p\n",(void*)klass,(char*)sel,mn,imp);
+	assert(1==0);
+	return Qnil;
+    }
+
+    DLOG("RCALL", "[<%s %p> %s] node=%p", class_getName((Class)klass), (void *)recv, (char *)sel, mn);
+#endif
+
   start_method_dispatch:
 
     if (mn != 0) {
@@ -594,7 +628,7 @@
 	}
 	else {
 	    int stat = 0;
-#if WITH_OBJC
+#if 0//WITH_OBJC
 	    mn = rb_objc_define_objc_mid_closure(recv, id, 0);
 	    if (mn != NULL) {
 		return vm_call_method(th, cfp, num, blockptr, flag, id,
@@ -997,6 +1031,9 @@
 		VALUE orig_klass, ID id, int is_defined)
 {
     VALUE val;
+#if WITH_OBJC
+    CFDictionaryRef iv_dict;
+#endif
 
     if (orig_klass == Qnil) {
 	/* in current lexical scope */
@@ -1010,8 +1047,13 @@
 
 	    if (!NIL_P(klass)) {
 	      search_continue:
+#if WITH_OBJC
+		iv_dict = (CFDictionaryRef)rb_class_ivar_dict(klass);
+		if (iv_dict != NULL && CFDictionaryGetValueIfPresent(iv_dict, (const void *)id, (const void **)&val)) {
+#else
 		if (RCLASS_IV_TBL(klass) &&
 		    st_lookup(RCLASS_IV_TBL(klass), id, &val)) {
+#endif
 		    if (val == Qundef) {
 			rb_autoload_load(klass, id);
 			goto search_continue;
@@ -1057,7 +1099,7 @@
 {
     VALUE klass;
 
-    while (cref && cref->nd_next && (NIL_P(cref->nd_clss) || FL_TEST(cref->nd_clss, FL_SINGLETON))) {
+    while (cref && cref->nd_next && (NIL_P(cref->nd_clss) || RCLASS_SINGLETON(cref->nd_clss))) {
 	cref = cref->nd_next;
 
 	if (!cref->nd_next) {
@@ -1114,7 +1156,7 @@
     INC_VM_STATE_VERSION();
 }
 
-#if WITH_OBJC
+#if 0//TODO WITH_OBJC
 static inline void
 vm_method_process_named_args(ID *pid, NODE **pmn, VALUE recv, rb_num_t *pnum, 
 			     rb_control_frame_t *cfp) 

Modified: MacRuby/branches/lrz_unstable/vm_method.c
===================================================================
--- MacRuby/branches/lrz_unstable/vm_method.c	2008-07-30 02:24:49 UTC (rev 381)
+++ MacRuby/branches/lrz_unstable/vm_method.c	2008-07-30 02:27:07 UTC (rev 382)
@@ -62,6 +62,7 @@
     }
 }
 
+#if !WITH_OBJC
 static void
 rb_clear_cache_by_id(ID id)
 {
@@ -80,6 +81,7 @@
 	ent++;
     }
 }
+#endif
 
 void
 rb_clear_cache_by_class(VALUE klass)
@@ -100,18 +102,7 @@
     }
 }
 
-#if WITH_OBJC
-void rb_objc_sync_ruby_method(VALUE, ID, NODE*, unsigned);
-#endif
-
 void
-rb_add_method_direct(VALUE klass, ID mid, NODE *node)
-{
-    rb_clear_cache_by_id(mid);
-    st_insert(RCLASS_M_TBL(klass), (st_data_t)mid, (st_data_t)node);
-}
-
-void
 rb_add_method(VALUE klass, ID mid, NODE * node, int noex)
 {
     NODE *body;
@@ -122,12 +113,12 @@
     if (rb_safe_level() >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
 	rb_raise(rb_eSecurityError, "Insecure: can't define method");
     }
-    if (!FL_TEST(klass, FL_SINGLETON) &&
+    if (!RCLASS_SINGLETON(klass) &&
 	node && nd_type(node) != NODE_ZSUPER &&
 	(mid == rb_intern("initialize") || mid == rb_intern("initialize_copy"))) {
 	noex = NOEX_PRIVATE | noex;
     }
-    else if (FL_TEST(klass, FL_SINGLETON) && node
+    else if (RCLASS_SINGLETON(klass) && node
 	     && nd_type(node) == NODE_CFUNC && mid == rb_intern("allocate")) {
 	rb_warn
 	    ("defining %s.allocate is deprecated; use rb_define_alloc_func()",
@@ -137,7 +128,9 @@
     if (OBJ_FROZEN(klass)) {
 	rb_error_frozen("class/module");
     }
+#if !WITH_OBJC
     rb_clear_cache_by_id(mid);
+#endif
 
     /*
      * NODE_METHOD (NEW_METHOD(body, klass, vis)):
@@ -157,6 +150,7 @@
 	body = 0;
     }
 
+#if !WITH_OBJC // TODO
     {
 	/* check re-definition */
 	st_data_t data;
@@ -184,18 +178,16 @@
 	    }
 	}
     }
+#endif
 
+#if WITH_OBJC
+    rb_objc_register_ruby_method(klass, mid, body != NULL ? body->nd_body : NULL);
+#else
     st_insert(RCLASS_M_TBL(klass), mid, (st_data_t) body);
-
-#if WITH_OBJC
-    if (node != NULL && noex == NOEX_PUBLIC) {
-	unsigned override = !FL_TEST(klass, FL_SINGLETON);
-	rb_objc_sync_ruby_method(klass, mid, node, override);
-    }
 #endif
 
     if (node && mid != ID_ALLOCATOR && ruby_running) {
-	if (FL_TEST(klass, FL_SINGLETON)) {
+	if (RCLASS_SINGLETON(klass)) {
 	    rb_funcall(rb_iv_get(klass, "__attached__"), singleton_added, 1,
 		       ID2SYM(mid));
 	}
@@ -236,6 +228,17 @@
 static NODE *
 search_method(VALUE klass, ID id, VALUE *klassp)
 {
+#if WITH_OBJC
+    NODE *node;
+    if (klass == 0)
+	return NULL;
+    node = rb_objc_method_node(klass, id, NULL, NULL);
+    if (node != NULL) {
+	if (klassp != NULL) /* TODO honour klassp */
+	    *klassp = klass;
+    }
+    return node;
+#else
     st_data_t body;
 
     if (!klass) {
@@ -253,6 +256,7 @@
     }
 
     return (NODE *)body;
+#endif
 }
 
 /*
@@ -266,6 +270,9 @@
 NODE *
 rb_get_method_body(VALUE klass, ID id, ID *idp)
 {
+#if WITH_OBJC
+    return search_method(klass, id, NULL);
+#else
     NODE *volatile fbody, *body;
     NODE *method;
 
@@ -301,11 +308,15 @@
     }
 
     return body;
+#endif
 }
 
 NODE *
 rb_method_node(VALUE klass, ID id)
 {
+#if WITH_OBJC
+    return rb_objc_method_node(klass, id, NULL, NULL);
+#else
     struct cache_entry *ent;
 
     ent = cache + EXPR1(klass, id);
@@ -314,12 +325,15 @@
     }
 
     return rb_get_method_body(klass, id, 0);
+#endif
 }
 
 static void
 remove_method(VALUE klass, ID mid)
 {
+#if !WITH_OBJC
     st_data_t data;
+#endif
     NODE *body = 0;
 
     if (klass == rb_cObject) {
@@ -333,6 +347,9 @@
     if (mid == object_id || mid == __send__ || mid == idInitialize) {
 	rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
     }
+#if WITH_OBJC
+    // TODO
+#else
     if (st_lookup(RCLASS_M_TBL(klass), mid, &data)) {
 	body = (NODE *)data;
 	if (!body || !body->nd_body) body = 0;
@@ -340,6 +357,7 @@
 	    st_delete(RCLASS_M_TBL(klass), &mid, &data);
 	}
     }
+#endif
     if (!body) {
 	rb_name_error(mid, "method `%s' not defined in %s",
 		      rb_id2name(mid), rb_class2name(klass));
@@ -350,7 +368,7 @@
     }
 
     rb_clear_cache_for_undef(klass, mid);
-    if (FL_TEST(klass, FL_SINGLETON)) {
+    if (RCLASS_SINGLETON(klass)) {
 	rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1,
 		   ID2SYM(mid));
     }
@@ -408,10 +426,23 @@
     if (klass == rb_cObject) {
 	rb_secure(4);
     }
+#if WITH_OBJC
+    fbody = rb_method_node(klass, name);
+    if (fbody == NULL && TYPE(klass) == T_MODULE) {
+	fbody = rb_method_node(rb_cObject, name);
+	origin = rb_method_node(rb_cObject, name) == fbody
+	    ? rb_cObject : klass;
+    }
+    else {
+	origin = rb_method_node(RCLASS_SUPER(klass), name) == fbody
+	    ? RCLASS_SUPER(klass) : klass;
+    }
+#else
     fbody = search_method(klass, name, &origin);
     if (!fbody && TYPE(klass) == T_MODULE) {
 	fbody = search_method(rb_cObject, name, &origin);
     }
+#endif
     if (!fbody || !fbody->nd_body) {
 	rb_print_undef(klass, name, 0);
     }
@@ -503,7 +534,7 @@
 #if WITH_OBJC
     /* TODO: we should only warn regarding important NSObject methods that
        are necessary by the GC to call finalizers. */
-    if (class_respondsToSelector(RCLASS_OCID(rb_cBasicObject),
+    if (class_respondsToSelector((Class)rb_cBasicObject,
 				 sel_registerName(rb_id2name(id)))) {
 	rb_warn("undefining `NSObject#%s' may cause serious problem", 
 		rb_id2name(id));
@@ -514,7 +545,7 @@
 	const char *s0 = " class";
 	VALUE c = klass;
 
-	if (FL_TEST(c, FL_SINGLETON)) {
+	if (RCLASS_SINGLETON(c)) {
 	    VALUE obj = rb_iv_get(klass, "__attached__");
 
 	    switch (TYPE(obj)) {
@@ -527,27 +558,13 @@
 	else if (TYPE(c) == T_MODULE) {
 	    s0 = " module";
 	}
-#if WITH_OBJC
-	if (!class_respondsToSelector(RCLASS(klass)->ocklass,
-	    			      sel_registerName(rb_id2name(id))))
-#endif
 	rb_name_error(id, "undefined method `%s' for%s `%s'",
 		      rb_id2name(id), s0, rb_class2name(c));
     }
 
     rb_add_method(klass, id, 0, NOEX_PUBLIC);
 
-#if WITH_OBJC
-    {
-	Method method;
-        method = class_getInstanceMethod(RCLASS(klass)->ocklass,
-	 				 sel_registerName(rb_id2name(id)));
-	if (method != NULL)
-	    method_setImplementation(method, NULL);
-    }
-#endif
-
-    if (FL_TEST(klass, FL_SINGLETON)) {
+    if (RCLASS_SINGLETON(klass)) {
 	rb_funcall(rb_iv_get(klass, "__attached__"),
 		   singleton_undefined, 1, ID2SYM(id));
     }
@@ -766,14 +783,22 @@
 void
 rb_alias(VALUE klass, ID name, ID def)
 {
+#if !WITH_OBJC
     NODE *orig_fbody, *node;
+    st_data_t data;
+#endif
     VALUE singleton = 0;
-    st_data_t data;
 
     rb_frozen_class_p(klass);
     if (klass == rb_cObject) {
 	rb_secure(4);
     }
+#if WITH_OBJC
+    if (RCLASS_SINGLETON(klass)) {
+	singleton = rb_iv_get(klass, "__attached__");
+    }
+    rb_objc_alias(klass, name, def);
+#else
     orig_fbody = search_method(klass, def, 0);
     if (!orig_fbody || !orig_fbody->nd_body) {
 	if (TYPE(klass) == T_MODULE) {
@@ -807,13 +832,9 @@
 			     orig_fbody->nd_body->nd_clss,
 			     NOEX_WITH_SAFE(orig_fbody->nd_body->nd_noex)), def));
 
-#if WITH_OBJC
-    if (orig_fbody->nd_body->nd_noex == NOEX_PUBLIC)
-	rb_objc_sync_ruby_method(klass, name, orig_fbody->nd_body->nd_body, 0);
+    rb_clear_cache_by_id(name);
 #endif
 
-    rb_clear_cache_by_id(name);
-
     if (!ruby_running) return;
 
     if (singleton) {
@@ -1104,6 +1125,10 @@
 int
 rb_obj_respond_to(VALUE obj, ID id, int priv)
 {
+#if WITH_OBJC
+    SEL sel = sel_registerName(rb_id2name(id));
+    return class_respondsToSelector(*(Class *)obj, sel); 
+#else
     VALUE klass = CLASS_OF(obj);
 
     if (rb_method_node(klass, idRespond_to) == basic_respond_to) {
@@ -1117,6 +1142,7 @@
 	    args[n++] = Qtrue;
 	return RTEST(rb_funcall2(obj, idRespond_to, n, args));
     }
+#endif
 }
 
 int
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080729/f1101d1c/attachment-0001.html 


More information about the macruby-changes mailing list