[macruby-changes] [190] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Sat May 10 17:16:57 PDT 2008


Revision: 190
          http://trac.macosforge.org/projects/ruby/changeset/190
Author:   lsansonetti at apple.com
Date:     2008-05-10 17:16:55 -0700 (Sat, 10 May 2008)

Log Message:
-----------
lots of misc fixes and performance/memory usage improvements

Modified Paths:
--------------
    MacRuby/trunk/array.c
    MacRuby/trunk/bignum.c
    MacRuby/trunk/enumerator.c
    MacRuby/trunk/error.c
    MacRuby/trunk/eval.c
    MacRuby/trunk/eval_error.c
    MacRuby/trunk/ext/readline/readline.c
    MacRuby/trunk/ext/syck/rubyext.c
    MacRuby/trunk/ext/syck/syck.c
    MacRuby/trunk/ext/syck/syck.h
    MacRuby/trunk/ext/syck/token.c
    MacRuby/trunk/file.c
    MacRuby/trunk/gc.c
    MacRuby/trunk/hash.c
    MacRuby/trunk/include/ruby/ruby.h
    MacRuby/trunk/io.c
    MacRuby/trunk/iseq.c
    MacRuby/trunk/load.c
    MacRuby/trunk/marshal.c
    MacRuby/trunk/objc.m
    MacRuby/trunk/object.c
    MacRuby/trunk/pack.c
    MacRuby/trunk/process.c
    MacRuby/trunk/re.c
    MacRuby/trunk/ruby.c
    MacRuby/trunk/signal.c
    MacRuby/trunk/sprintf.c
    MacRuby/trunk/string.c
    MacRuby/trunk/util.c

Modified: MacRuby/trunk/array.c
===================================================================
--- MacRuby/trunk/array.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/array.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -43,8 +43,6 @@
 #if WITH_OBJC
 /* TODO optimize this */
 struct rb_objc_ary_struct {
-    bool frozen;
-    bool tainted;
     bool named_args;
     void *cptr;
 };
@@ -67,27 +65,11 @@
     if (s == NULL) {
 	s = xmalloc(sizeof(struct rb_objc_ary_struct));
 	rb_objc_set_associative_ref((void *)ary, &rb_objc_ary_assoc_key, s);
-	s->frozen = false;
-	s->tainted = false;
 	s->named_args = false;
 	s->cptr = NULL;
     }
     return s;
 }
-
-static void
-rb_objc_ary_copy_struct(VALUE old, VALUE new)
-{
-    struct rb_objc_ary_struct *s;
-
-    s = rb_objc_ary_get_struct(old);
-    if (s != NULL) {
-	struct rb_objc_ary_struct *n;
-
-	n = rb_objc_ary_get_struct2(new);
-	memcpy(n, s, sizeof(struct rb_objc_ary_struct));
-    }
-}
 #else
 #define ARY_SHARED_P(a) FL_TEST(a, ELTS_SHARED)
 
@@ -109,14 +91,12 @@
 {
 #if WITH_OBJC
     bool _CFArrayIsMutable(void *);
-    if (rb_ary_frozen_p(ary) == Qtrue) rb_error_frozen("hash");
     if (!_CFArrayIsMutable((void *)ary))
 	rb_raise(rb_eRuntimeError, "can't modify immutable array");
-#else
+#endif
     if (OBJ_FROZEN(ary)) rb_error_frozen("array");
     if (!OBJ_TAINTED(ary) && rb_safe_level() >= 4)
 	rb_raise(rb_eSecurityError, "Insecure: can't modify array");
-#endif
 }
 
 static void
@@ -139,40 +119,9 @@
 VALUE
 rb_ary_freeze(VALUE ary)
 {
-#if WITH_OBJC
-    rb_objc_ary_get_struct2(ary)->frozen = true;
-    return ary;
-#else
     return rb_obj_freeze(ary);
-#endif
 }
 
-#if WITH_OBJC
-VALUE
-rb_ary_taint(VALUE ary)
-{
-    rb_objc_ary_get_struct2(ary)->tainted = true;
-    return ary;
-}
-
-VALUE 
-rb_ary_untaint(VALUE ary)
-{
-    struct rb_objc_ary_struct *s;
-    s = rb_objc_ary_get_struct(ary);
-    if (s != NULL)
-        s->tainted = false;
-    return ary;
-}
-
-VALUE
-rb_ary_tainted(VALUE ary)
-{
-    struct rb_objc_ary_struct *s = rb_objc_ary_get_struct(ary);
-    return s != NULL && s->tainted ? Qtrue : Qfalse;
-}
-#endif
-
 /*
  *  call-seq:
  *     array.frozen?  -> true or false
@@ -184,13 +133,8 @@
 VALUE
 rb_ary_frozen_p(VALUE ary)
 {
-#if WITH_OBJC
-    struct rb_objc_ary_struct *s = rb_objc_ary_get_struct(ary);
-    return s != NULL && s->frozen ? Qtrue : Qfalse;
-#else
     if (OBJ_FROZEN(ary)) return Qtrue;
     return Qfalse;
-#endif
 }
 
 #if WITH_OBJC
@@ -236,7 +180,8 @@
         *(Class *)ary = RCLASS_OCID(klass);
 
     CFMakeCollectable((CFTypeRef)ary);
-
+    rb_gc_malloc_increase(sizeof(void *));
+    
     return ary;
 #else
     NEWOBJ(ary, struct RArray);
@@ -1591,14 +1536,6 @@
 		CFRangeMake(0, n));
     return dup;
 }
-
-VALUE
-rb_ary_clone(VALUE ary)
-{
-    VALUE dup = rb_ary_dup2(ary);
-    rb_objc_ary_copy_struct(ary, dup);
-    return dup;
-}
 #endif
 
 VALUE
@@ -4033,9 +3970,6 @@
 	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);
-    rb_define_method(rb_cArray, "freeze", rb_ary_freeze, 0);
-    rb_define_method(rb_cArray, "taint", rb_ary_taint, 0);
-    rb_define_method(rb_cArray, "tainted?", rb_ary_tainted, 0);
 #else
     rb_cArray  = rb_define_class("Array", rb_cObject);
 #endif

Modified: MacRuby/trunk/bignum.c
===================================================================
--- MacRuby/trunk/bignum.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/bignum.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -574,7 +574,7 @@
 VALUE
 rb_str_to_inum(VALUE str, int base, int badcheck)
 {
-    char *s;
+    const char *s;
     long len;
 
     StringValue(str);
@@ -880,7 +880,7 @@
 
     if (FIXNUM_P(x)) {
         VALUE str = rb_fix2str(x, base);
-        char* str_ptr = RSTRING_CPTR(str);
+        const char* str_ptr = RSTRING_CPTR(str);
         long str_len = RSTRING_CLEN(str);
         if (trim) {
             if (FIX2INT(x) == 0) return 0;

Modified: MacRuby/trunk/enumerator.c
===================================================================
--- MacRuby/trunk/enumerator.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/enumerator.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -320,7 +320,7 @@
 {
     struct enumerator *e;
     int argc = 0;
-    VALUE *argv = 0;
+    const VALUE *argv = 0;
 
     if (!rb_block_given_p()) return obj;
     e = enumerator_ptr(obj);
@@ -353,7 +353,7 @@
     struct enumerator *e = enumerator_ptr(obj);
     VALUE memo = 0;
     int argc = 0;
-    VALUE *argv = 0;
+    const VALUE *argv = 0;
 
     RETURN_ENUMERATOR(obj, 0, 0);
     if (e->args) {

Modified: MacRuby/trunk/error.c
===================================================================
--- MacRuby/trunk/error.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/error.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -447,7 +447,7 @@
 
     klass = CLASS_OF(exc);
     exc = rb_obj_as_string(exc);
-    if (RSTRING_LEN(exc) == 0) {
+    if (RSTRING_CLEN(exc) == 0) {
 	return rb_str_dup(rb_class_name(klass));
     }
 
@@ -768,7 +768,7 @@
 	    break;
 	  default:
 	    d = rb_protect(rb_inspect, obj, 0);
-	    if (NIL_P(d) || RSTRING_LEN(d) > 65) {
+	    if (NIL_P(d) || RSTRING_CLEN(d) > 65) {
 		d = rb_any_to_s(obj);
 	    }
 	    desc = RSTRING_CPTR(d);

Modified: MacRuby/trunk/eval.c
===================================================================
--- MacRuby/trunk/eval.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/eval.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -1798,7 +1798,7 @@
 		mesg = rb_attr_get(errinfo, rb_intern("mesg"));
 		if (!NIL_P(errat) && TYPE(errat) == T_ARRAY &&
 		    (bt2 = backtrace(-2), RARRAY_LEN(bt2) > 0)) {
-		    if (!NIL_P(mesg) && TYPE(mesg) == T_STRING && !RSTRING_LEN(mesg)) {
+		    if (!NIL_P(mesg) && TYPE(mesg) == T_STRING && !RSTRING_CLEN(mesg)) {
 			rb_str_update(mesg, 0, 0, rb_str_new2(": "));
 			rb_str_update(mesg, 0, 0, RARRAY_AT(errat, 0));
 		    }
@@ -1835,7 +1835,7 @@
 rb_f_eval(int argc, VALUE *argv, VALUE self)
 {
     VALUE src, scope, vfile, vline;
-    char *file = "(eval)";
+    const char *file = "(eval)";
     int line = 1;
 
     rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);

Modified: MacRuby/trunk/eval_error.c
===================================================================
--- MacRuby/trunk/eval_error.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/eval_error.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -91,7 +91,7 @@
     VALUE errat = Qnil;		/* OK */
     VALUE errinfo = GET_THREAD()->errinfo;
     volatile VALUE eclass, e;
-    char *einfo;
+    const char *einfo;
     long elen;
 
     if (NIL_P(errinfo))

Modified: MacRuby/trunk/ext/readline/readline.c
===================================================================
--- MacRuby/trunk/ext/readline/readline.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/ext/readline/readline.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -76,7 +76,7 @@
     rb_secure(4);
     if (rb_scan_args(argc, argv, "02", &tmp, &add_hist) > 0) {
 	SafeStringValue(tmp);
-	prompt = RSTRING_PTR(tmp);
+	prompt = RSTRING_CPTR(tmp);
     }
 
     if (!isatty(0) && errno == EBADF) rb_raise(rb_eIOError, "stdin closed");
@@ -189,8 +189,8 @@
     result = ALLOC_N(char *, matches + 2);
     for (i = 0; i < matches; i++) {
 	temp = rb_obj_as_string(RARRAY_AT(ary, i));
-	result[i + 1] = ALLOC_N(char, RSTRING_LEN(temp) + 1);
-	strcpy(result[i + 1], RSTRING_PTR(temp));
+	result[i + 1] = ALLOC_N(char, RSTRING_CLEN(temp) + 1);
+	strcpy(result[i + 1], RSTRING_CPTR(temp));
     }
     result[matches + 1] = NULL;
 
@@ -265,10 +265,10 @@
     }
     else {
 	SafeStringValue(str);
-	if (RSTRING_LEN(str) == 0) {
+	if (RSTRING_CLEN(str) == 0) {
 	    rl_completion_append_character = '\0';
 	} else {
-	    rl_completion_append_character = RSTRING_PTR(str)[0];
+	    rl_completion_append_character = RSTRING_CPTR(str)[0];
 	}
     }
     return self;
@@ -288,8 +288,7 @@
     if (rl_completion_append_character == '\0')
 	return Qnil;
 
-    str = rb_str_new("", 1);
-    RSTRING_PTR(str)[0] = rl_completion_append_character;
+    str = rb_str_new(&rl_completion_append_character, 1);
     return str;
 #else
     rb_notimplement();
@@ -307,14 +306,14 @@
     SafeStringValue(str);
     if (basic_word_break_characters == NULL) {
 	basic_word_break_characters =
-	    ALLOC_N(char, RSTRING_LEN(str) + 1);
+	    ALLOC_N(char, RSTRING_CLEN(str) + 1);
     }
     else {
-	REALLOC_N(basic_word_break_characters, char, RSTRING_LEN(str) + 1);
+	REALLOC_N(basic_word_break_characters, char, RSTRING_CLEN(str) + 1);
     }
     strncpy(basic_word_break_characters,
-	    RSTRING_PTR(str), RSTRING_LEN(str));
-    basic_word_break_characters[RSTRING_LEN(str)] = '\0';
+	    RSTRING_CPTR(str), RSTRING_CLEN(str));
+    basic_word_break_characters[RSTRING_CLEN(str)] = '\0';
     rl_basic_word_break_characters = basic_word_break_characters;
     return self;
 #else
@@ -347,14 +346,14 @@
     SafeStringValue(str);
     if (completer_word_break_characters == NULL) {
 	completer_word_break_characters =
-	    ALLOC_N(char, RSTRING_LEN(str) + 1);
+	    ALLOC_N(char, RSTRING_CLEN(str) + 1);
     }
     else {
-	REALLOC_N(completer_word_break_characters, char, RSTRING_LEN(str) + 1);
+	REALLOC_N(completer_word_break_characters, char, RSTRING_CLEN(str) + 1);
     }
     strncpy(completer_word_break_characters,
-	    RSTRING_PTR(str), RSTRING_LEN(str));
-    completer_word_break_characters[RSTRING_LEN(str)] = '\0';
+	    RSTRING_CPTR(str), RSTRING_CLEN(str));
+    completer_word_break_characters[RSTRING_CLEN(str)] = '\0';
     rl_completer_word_break_characters = completer_word_break_characters;
     return self;
 #else
@@ -387,14 +386,14 @@
     SafeStringValue(str);
     if (basic_quote_characters == NULL) {
 	basic_quote_characters =
-	    ALLOC_N(char, RSTRING_LEN(str) + 1);
+	    ALLOC_N(char, RSTRING_CLEN(str) + 1);
     }
     else {
-	REALLOC_N(basic_quote_characters, char, RSTRING_LEN(str) + 1);
+	REALLOC_N(basic_quote_characters, char, RSTRING_CLEN(str) + 1);
     }
     strncpy(basic_quote_characters,
-	    RSTRING_PTR(str), RSTRING_LEN(str));
-    basic_quote_characters[RSTRING_LEN(str)] = '\0';
+	    RSTRING_CPTR(str), RSTRING_CLEN(str));
+    basic_quote_characters[RSTRING_CLEN(str)] = '\0';
     rl_basic_quote_characters = basic_quote_characters;
 
     return self;
@@ -428,13 +427,13 @@
     SafeStringValue(str);
     if (completer_quote_characters == NULL) {
 	completer_quote_characters =
-	    ALLOC_N(char, RSTRING_LEN(str) + 1);
+	    ALLOC_N(char, RSTRING_CLEN(str) + 1);
     }
     else {
-	REALLOC_N(completer_quote_characters, char, RSTRING_LEN(str) + 1);
+	REALLOC_N(completer_quote_characters, char, RSTRING_CLEN(str) + 1);
     }
-    strncpy(completer_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
-    completer_quote_characters[RSTRING_LEN(str)] = '\0';
+    strncpy(completer_quote_characters, RSTRING_CPTR(str), RSTRING_CLEN(str));
+    completer_quote_characters[RSTRING_CLEN(str)] = '\0';
     rl_completer_quote_characters = completer_quote_characters;
 
     return self;
@@ -468,13 +467,13 @@
     SafeStringValue(str);
     if (filename_quote_characters == NULL) {
 	filename_quote_characters =
-	    ALLOC_N(char, RSTRING_LEN(str) + 1);
+	    ALLOC_N(char, RSTRING_CLEN(str) + 1);
     }
     else {
-	REALLOC_N(filename_quote_characters, char, RSTRING_LEN(str) + 1);
+	REALLOC_N(filename_quote_characters, char, RSTRING_CLEN(str) + 1);
     }
-    strncpy(filename_quote_characters, RSTRING_PTR(str), RSTRING_LEN(str));
-    filename_quote_characters[RSTRING_LEN(str)] = '\0';
+    strncpy(filename_quote_characters, RSTRING_CPTR(str), RSTRING_CLEN(str));
+    filename_quote_characters[RSTRING_CLEN(str)] = '\0';
     rl_filename_quote_characters = filename_quote_characters;
 
     return self;
@@ -535,7 +534,7 @@
     if (i < 0) {
         i += history_length;
     }
-    entry = replace_history_entry(i, RSTRING_PTR(str), NULL);
+    entry = replace_history_entry(i, RSTRING_CPTR(str), NULL);
     if (entry == NULL) {
 	rb_raise(rb_eIndexError, "invalid index");
     }
@@ -551,7 +550,7 @@
 {
     rb_secure(4);
     SafeStringValue(str);
-    add_history(RSTRING_PTR(str));
+    add_history(RSTRING_CPTR(str));
     return self;
 }
 
@@ -564,7 +563,7 @@
     while (argc--) {
 	str = *argv++;
 	SafeStringValue(str);
-	add_history(RSTRING_PTR(str));
+	add_history(RSTRING_CPTR(str));
     }
     return self;
 }

Modified: MacRuby/trunk/ext/syck/rubyext.c
===================================================================
--- MacRuby/trunk/ext/syck/rubyext.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/ext/syck/rubyext.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -56,7 +56,7 @@
 static VALUE sym_scalar, sym_seq, sym_map;
 static VALUE sym_1quote, sym_2quote, sym_fold, sym_literal, sym_plain, sym_inline;
 static VALUE cDate, cNode, cMap, cSeq, cScalar, cOut, cParser, cResolver, cPrivateType, cDomainType, cYObject, cBadAlias, cDefaultKey, cMergeKey, cEmitter;
-static VALUE oDefaultResolver, oGenericResolver;
+static VALUE oDefaultResolver, oGenericResolver, oColon, oDoubleColon;
 
 /*
  * my private collection of numerical oddities.
@@ -1026,9 +1026,9 @@
 syck_const_find(VALUE const_name)
 {
     VALUE tclass = rb_cObject;
-    VALUE tparts = rb_str_split( const_name, "::" );
-    int i = 0;
-    for ( i = 0; i < RARRAY_LEN(tparts); i++ ) {
+    VALUE tparts = rb_str_split2( const_name, oDoubleColon );
+    int i = 0, count;
+    for ( i = 0, count = RARRAY_LEN(tparts); i < count; i++ ) {
         VALUE tpart = rb_to_id( rb_ary_entry( tparts, i ) );
         if ( !rb_const_defined( tclass, tpart ) ) return Qnil;
         tclass = rb_const_get( tclass, tpart );
@@ -1050,7 +1050,6 @@
     if ( ! (NIL_P(type) || RSTRING_CLEN(StringValue(type)) == 0) )
     {
         VALUE str_xprivate = rb_str_new2( "x-private" );
-        VALUE colon = rb_str_new2( ":" );
         VALUE tags = rb_attr_get(self, s_tags);
         VALUE target_class = rb_hash_aref( tags, type );
         VALUE subclass = target_class;
@@ -1062,17 +1061,18 @@
         if ( NIL_P( target_class ) )
         {
             VALUE subclass_parts = rb_ary_new();
-            VALUE parts = rb_str_split( type, ":" );
+            VALUE parts = rb_str_split2( type, oColon );
 
             while ( RARRAY_LEN(parts) > 1 )
             {
                 VALUE partial;
                 rb_ary_unshift( subclass_parts, rb_ary_pop( parts ) );
-                partial = rb_ary_join( parts, colon );
+                partial = rb_ary_join( parts, oColon );
+		//printf("partial %p parts %p\n", partial, parts);
                 target_class = rb_hash_aref( tags, partial );
                 if ( NIL_P( target_class ) )
                 {
-                    rb_str_append( partial, colon );
+                    rb_str_append( partial, oColon );
                     target_class = rb_hash_aref( tags, partial );
                 }
 
@@ -1086,7 +1086,7 @@
                          RTEST( rb_funcall( target_class, s_tag_subclasses, 0 ) ) )
                     {
                         VALUE subclass_v;
-                        subclass = rb_ary_join( subclass_parts, colon );
+                        subclass = rb_ary_join( subclass_parts, oColon );
                         subclass = rb_funcall( target_class, s_tag_read_class, 1, subclass );
                         subclass_v = syck_const_find( subclass );
 
@@ -1146,17 +1146,17 @@
             }
             else 
             {
-                VALUE parts = rb_str_split( type, ":" );
+                VALUE parts = rb_str_split2( type, oColon );
                 VALUE scheme = rb_ary_shift( parts );
                 if ( rb_str_cmp( scheme, str_xprivate ) == 0 )
                 {
-                    VALUE name = rb_ary_join( parts, colon );
+                    VALUE name = rb_ary_join( parts, oColon );
                     obj = rb_funcall( cPrivateType, s_new, 2, name, val );
                 }
                 else
                 {
                     VALUE domain = rb_ary_shift( parts );
-                    VALUE name = rb_ary_join( parts, colon );
+                    VALUE name = rb_ary_join( parts, oColon );
                     obj = rb_funcall( cDomainType, s_new, 3, domain, name, val );
                 }
             }
@@ -2158,6 +2158,11 @@
     oGenericResolver = rb_funcall( cResolver, rb_intern( "new" ), 0 );
     rb_define_singleton_method( oGenericResolver, "node_import", syck_genericresolver_node_import, 1 );
     rb_define_const( rb_syck, "GenericResolver", oGenericResolver );
+    
+    oColon = rb_str_new2( ":" );
+    rb_global_variable( &oColon );
+    oDoubleColon = rb_str_new2( "::" );
+    rb_global_variable( &oDoubleColon );
 
     /*
      * Define YAML::Syck::Parser class

Modified: MacRuby/trunk/ext/syck/syck.c
===================================================================
--- MacRuby/trunk/ext/syck/syck.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/ext/syck/syck.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -354,7 +354,7 @@
     if ( p->lvl_idx <= 1 ) return;
 
     p->lvl_idx -= 1;
-    xfree( p->levels[p->lvl_idx].domain );
+    free( p->levels[p->lvl_idx].domain );
 }
 
 void 

Modified: MacRuby/trunk/ext/syck/syck.h
===================================================================
--- MacRuby/trunk/ext/syck/syck.h	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/ext/syck/syck.h	2008-05-11 00:16:55 UTC (rev 190)
@@ -48,7 +48,7 @@
 
 #define ALLOC_CT 8
 #define SYCK_BUFFERSIZE 4096
-#if WITH_OBJC
+#if 0//WITH_OBJC
 #define S_ALLOC_N(type,n) (type*)xmalloc(sizeof(type)*(n))
 #define S_ALLOC(type) (type*)xmalloc(sizeof(type))
 #define S_REALLOC_N(var,type,n) (var)=(type*)xrealloc((char*)(var),sizeof(type)*(n))

Modified: MacRuby/trunk/ext/syck/token.c
===================================================================
--- MacRuby/trunk/ext/syck/token.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/ext/syck/token.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -2111,7 +2111,7 @@
                         char *chr_text = syck_strndup( YYTOKEN, 4 );
                         chr_text[0] = '0';
                         ch = strtol( chr_text, NULL, 16 );
-                        xfree( chr_text );
+                        free( chr_text );
                         QUOTECAT(qstr, qcapa, qidx, ch);
                         goto DoubleQuote2; 
                     }
@@ -2173,7 +2173,7 @@
                         YYCURSOR = YYTOKTMP;
                         if ( YYCURSOR == YYTOKEN + 1 )
                         {
-                            xfree( qstr );
+                            free( qstr );
                             return YAML_ITRANSFER;
                         }
 
@@ -2188,7 +2188,7 @@
                             sycklval->name[0] = '\0';
                             strcat( sycklval->name, lvl->domain );
                             strncat( sycklval->name, qstr + 1, qidx - 1 );
-                            xfree( qstr );
+                            free( qstr );
                         }
                         else
                         {
@@ -2202,13 +2202,13 @@
 
                             if ( carat < qend )
                             {
-                                xfree( lvl->domain );
+                                free( lvl->domain );
                                 lvl->domain = syck_strndup( qstr, carat - qstr );
                                 sycklval->name = S_ALLOC_N( char, ( qend - carat ) + strlen( lvl->domain ) );
                                 sycklval->name[0] = '\0';
                                 strcat( sycklval->name, lvl->domain );
                                 strncat( sycklval->name, carat + 1, ( qend - carat ) - 1 );
-                                xfree( qstr );
+                                free( qstr );
                             }
                             else
                             {
@@ -2314,7 +2314,7 @@
                         char *chr_text = syck_strndup( YYTOKTMP, 4 );
                         chr_text[0] = '0';
                         ch = strtol( chr_text, NULL, 16 );
-                        xfree( chr_text );
+                        free( chr_text );
                         QUOTECAT(qstr, qcapa, qidx, ch);
                         goto TransferMethod2;
                     }

Modified: MacRuby/trunk/file.c
===================================================================
--- MacRuby/trunk/file.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/file.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -829,7 +829,7 @@
     rb_secure(2);
     FilePathValue(fname);
     if (lstat(StringValueCStr(fname), &st) == -1) {
-	rb_sys_fail(RSTRING_PTR(fname));
+	rb_sys_fail(RSTRING_CPTR(fname));
     }
     return stat_new(&st);
 #else
@@ -1565,13 +1565,13 @@
     FilePathValue(fname1);
     fname1 = rb_str_new4(fname1);
     FilePathValue(fname2);
-    if (access(RSTRING_PTR(fname1), 0)) return Qfalse;
-    if (access(RSTRING_PTR(fname2), 0)) return Qfalse;
+    if (access(RSTRING_CPTR(fname1), 0)) return Qfalse;
+    if (access(RSTRING_CPTR(fname2), 0)) return Qfalse;
 #endif
     fname1 = rb_file_expand_path(fname1, Qnil);
     fname2 = rb_file_expand_path(fname2, Qnil);
-    if (RSTRING_LEN(fname1) != RSTRING_LEN(fname2)) return Qfalse;
-    if (rb_memcicmp(RSTRING_PTR(fname1), RSTRING_PTR(fname2), RSTRING_LEN(fname1)))
+    if (RSTRING_CLEN(fname1) != RSTRING_CLEN(fname2)) return Qfalse;
+    if (rb_memcicmp(RSTRING_CPTR(fname1), RSTRING_CPTR(fname2), RSTRING_CLEN(fname1)))
 	return Qfalse;
 #endif
     return Qtrue;
@@ -1658,7 +1658,7 @@
     rb_secure(2);
     FilePathValue(fname);
     if (lstat(StringValueCStr(fname), &st) == -1) {
-	rb_sys_fail(RSTRING_PTR(fname));
+	rb_sys_fail(RSTRING_CPTR(fname));
     }
 
     return rb_file_ftype(&st);
@@ -1724,7 +1724,7 @@
     struct stat st;
 
     if (rb_stat(fname, &st) < 0)
-	rb_sys_fail(RSTRING_PTR(fname));
+	rb_sys_fail(RSTRING_CPTR(fname));
     return stat_mtime(&st);
 }
 
@@ -1769,7 +1769,7 @@
     struct stat st;
 
     if (rb_stat(fname, &st) < 0)
-	rb_sys_fail(RSTRING_PTR(fname));
+	rb_sys_fail(RSTRING_CPTR(fname));
     return stat_ctime(&st);
 }
 
@@ -2159,7 +2159,7 @@
 #endif
     const char *e1, *e2;
     int len = 5;
-    int l1 = RSTRING_LEN(s1), l2 = RSTRING_LEN(s2);
+    int l1 = RSTRING_CLEN(s1), l2 = RSTRING_CLEN(s2);
 
     e1 = e2 = "";
     if (l1 > max_pathlen) {
@@ -2175,8 +2175,8 @@
     len += l1 + l2;
     buf = ALLOCA_N(char, len);
     snprintf(buf, len, "(%.*s%s, %.*s%s)",
-	     l1, RSTRING_PTR(s1), e1,
-	     l2, RSTRING_PTR(s2), e2);
+	     l1, RSTRING_CPTR(s1), e1,
+	     l2, RSTRING_CPTR(s2), e2);
     rb_sys_fail(buf);
 }
 
@@ -2263,7 +2263,7 @@
     rb_secure(2);
     FilePathValue(path);
     buf = xmalloc(size);
-    while ((rv = readlink(RSTRING_PTR(path), buf, size)) == size
+    while ((rv = readlink(RSTRING_CPTR(path), buf, size)) == size
 #ifdef _AIX
 	    || (rv < 0 && errno == ERANGE) /* quirky behavior of GPFS */
 #endif
@@ -2273,7 +2273,7 @@
     }
     if (rv < 0) {
 	free(buf);
-	rb_sys_fail(RSTRING_PTR(path));
+	rb_sys_fail(RSTRING_CPTR(path));
     }
     v = rb_tainted_str_new(buf, rv);
     xfree(buf);
@@ -2835,7 +2835,7 @@
 rb_file_s_basename(int argc, VALUE *argv)
 {
     VALUE fname, fext, basename;
-    char *name, *p;
+    const char *name, *p;
 #if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
     char *root;
 #endif
@@ -3139,7 +3139,7 @@
     FilePathValue(path);
 #ifdef HAVE_TRUNCATE
     if (truncate(StringValueCStr(path), pos) < 0)
-	rb_sys_fail(RSTRING_PTR(path));
+	rb_sys_fail(RSTRING_CPTR(path));
 #else
 # ifdef HAVE_CHSIZE
     {
@@ -3147,16 +3147,16 @@
 
 #  ifdef _WIN32
 	if ((tmpfd = open(StringValueCStr(path), O_RDWR)) < 0) {
-	    rb_sys_fail(RSTRING_PTR(path));
+	    rb_sys_fail(RSTRING_CPTR(path));
 	}
 #  else
 	if ((tmpfd = open(StringValueCStr(path), 0)) < 0) {
-	    rb_sys_fail(RSTRING_PTR(path));
+	    rb_sys_fail(RSTRING_CPTR(path));
 	}
 #  endif
 	if (chsize(tmpfd, pos) < 0) {
 	    close(tmpfd);
-	    rb_sys_fail(RSTRING_PTR(path));
+	    rb_sys_fail(RSTRING_CPTR(path));
 	}
 	close(tmpfd);
     }
@@ -3481,7 +3481,7 @@
 
 	CHECK(1);
 	if (rb_stat(argv[1], &st) == -1) {
-	    rb_sys_fail(RSTRING_PTR(argv[1]));
+	    rb_sys_fail(RSTRING_CPTR(argv[1]));
 	}
 
 	switch (cmd) {
@@ -3570,7 +3570,7 @@
     rb_secure(2);
     FilePathValue(fname);
     if (stat(StringValueCStr(fname), &st) == -1) {
-	rb_sys_fail(RSTRING_PTR(fname));
+	rb_sys_fail(RSTRING_CPTR(fname));
     }
     if (DATA_PTR(obj)) {
 	free(DATA_PTR(obj));
@@ -4212,7 +4212,7 @@
 path_check_0(VALUE path, int execpath)
 {
     struct stat st;
-    char *p0 = StringValueCStr(path);
+    const char *p0 = StringValueCStr(path);
     char *p = 0, *s;
 
     if (!is_absolute_path(p0)) {
@@ -4225,7 +4225,7 @@
 	rb_str_cat2(newpath, "/");
 	rb_str_cat2(newpath, p0);
 	path = newpath;
-	p0 = RSTRING_PTR(path);
+	p0 = RSTRING_CPTR(path);
     }
     for (;;) {
 #ifndef S_IWOTH
@@ -4307,8 +4307,8 @@
 int
 rb_find_file_ext(VALUE *filep, const char *const *ext)
 {
-    char *path, *found;
-    char *f = RSTRING_PTR(*filep);
+    const char *path, *found;
+    const char *f = RSTRING_CPTR(*filep);
     VALUE fname;
     long i, j;
 
@@ -4346,8 +4346,8 @@
 	    VALUE str = RARRAY_AT(rb_load_path, i);
 
 	    FilePathValue(str);
-	    if (RSTRING_LEN(str) == 0) continue;
-	    path = RSTRING_PTR(str);
+	    if (RSTRING_CLEN(str) == 0) continue;
+	    path = RSTRING_CPTR(str);
 	    found = dln_find_file(StringValueCStr(fname), path);
 	    if (found && file_load_ok(found)) {
 		*filep = rb_str_new2(found);
@@ -4363,7 +4363,7 @@
 {
     VALUE tmp;
     char *f = StringValueCStr(path);
-    char *lpath;
+    const char *lpath;
 
     if (f[0] == '~') {
 	path = rb_file_expand_path(path, Qnil);
@@ -4402,16 +4402,16 @@
 	for (i=0, count=RARRAY_LEN(rb_load_path);i < count;i++) {
 	    VALUE str = RARRAY_AT(rb_load_path, i);
 	    FilePathValue(str);
-	    if (RSTRING_LEN(str) > 0) {
+	    if (RSTRING_CLEN(str) > 0) {
 		rb_ary_push(tmp, str);
 	    }
 	}
 	tmp = rb_ary_join(tmp, rb_str_new2(PATH_SEP));
-	if (RSTRING_LEN(tmp) == 0) {
+	if (RSTRING_CLEN(tmp) == 0) {
 	    lpath = 0;
 	}
 	else {
-	    lpath = RSTRING_PTR(tmp);
+	    lpath = RSTRING_CPTR(tmp);
 	}
     }
     else {

Modified: MacRuby/trunk/gc.c
===================================================================
--- MacRuby/trunk/gc.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/gc.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -1,4 +1,4 @@
-  /**********************************************************************
+/**********************************************************************
 
   gc.c -
 
@@ -36,7 +36,7 @@
 #endif
 
 #if WITH_OBJC
-# if HAVE_AUTO_ZONE_H
+# if 1//HAVE_AUTO_ZONE_H
 #  include <auto_zone.h>
 # else
 #  include <malloc/malloc.h>
@@ -45,7 +45,9 @@
 #define AUTO_MEMORY_UNSCANNED 1
 #define AUTO_OBJECT_SCANNED   2
 #define AUTO_OBJECT_UNSCANNED 3 
+#define AUTO_COLLECT_RATIO_COLLECTION (0 << 0)
 #define AUTO_COLLECT_GENERATIONAL_COLLECTION (1 << 0)
+#define AUTO_COLLECT_FULL_COLLECTION (1 << 0)
 #define AUTO_LOG_COLLECTIONS (1 << 1)
 #define AUTO_LOG_REGIONS (1 << 4)
 #define AUTO_LOG_UNUSUAL (1 << 5)
@@ -76,9 +78,18 @@
     size_t unused11;
 } auto_collection_control_t;
 extern auto_collection_control_t *auto_collection_parameters(auto_zone_t *);
+typedef struct {
+    malloc_statistics_t malloc_statistics;
+    uint32_t            version;
+    size_t              num_collections[2];
+    boolean_t           last_collection_was_generational;
+    size_t              bytes_in_use_after_last_collection[2];
+    size_t              bytes_allocated_after_last_collection[2];
+    size_t              bytes_freed_during_last_collection[2];
+    // durations not included
+} auto_statistics_t;
 # endif
 static auto_zone_t *__auto_zone = NULL;
-static long gc_count = 0;
 static long xmalloc_count = 0;
 #endif
 
@@ -283,6 +294,14 @@
     return flag;
 }
 
+void
+rb_gc_malloc_increase(size_t size)
+{
+    malloc_increase += size;
+    if (!dont_gc && (ruby_gc_stress || malloc_increase > malloc_limit))
+	garbage_collect();
+}
+
 void *
 ruby_xmalloc(size_t size)
 {
@@ -292,11 +311,7 @@
 	rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
     }
     if (size == 0) size = 1;
-    malloc_increase += size;
-
-    if (ruby_gc_stress || malloc_increase > malloc_limit) {
-	garbage_collect();
-    }
+    rb_gc_malloc_increase(size);
 #if WITH_OBJC
     if (__auto_zone == NULL) {
     	fprintf(stderr,
@@ -403,7 +418,6 @@
 #endif
 }
 
-
 /*
  *  call-seq:
  *     GC.enable    => true or false
@@ -628,73 +642,7 @@
 
 #else /* !WITH_OBJC */
 
-struct finalize_at_exit {
-    VALUE v;
-    struct finalize_at_exit *next;
-};
-
-static struct finalize_at_exit *finalize_at_exit_head = NULL;
-
 void
-rb_objc_keep_for_exit_finalize(VALUE v)
-{
-    if (finalize_at_exit_head == NULL) {
-	finalize_at_exit_head = (struct finalize_at_exit *)malloc(
-	    sizeof(struct finalize_at_exit));
-	finalize_at_exit_head->v = v;
-	finalize_at_exit_head->next = NULL;
-    }
-    else {
-	struct finalize_at_exit *entry;
-	entry = (struct finalize_at_exit *)malloc(
-	    sizeof(struct finalize_at_exit));
-	entry->v = v;
-	entry->next = finalize_at_exit_head;
-	finalize_at_exit_head = entry;
-    }
-}
-
-static inline void
-rb_objc_finalize(VALUE obj) 
-{
-    struct finalize_at_exit *entry;
-    
-    //printf("rb_objc_finalize %p\n", (void *)obj);
-
-    for (entry = finalize_at_exit_head; entry != NULL; entry = entry->next) {
-	if (obj == entry->v)
-	    entry->v = Qnil;
-    }
-
-    switch (RBASIC(obj)->flags & T_MASK) {
-    	case T_FILE:
-	    if (RFILE(obj)->fptr != NULL)
-		rb_io_fptr_finalize(RFILE(obj)->fptr);
-	    break;
-	default:
-	    rb_bug("rb_objc_finalize: unhandled object type 0x%X",
-		   RBASIC(obj)->flags & T_MASK);
-    }
-}
-
-static id
-rb_objc_imp_finalize(id rcv, SEL sel)
-{
-    void *p;
-
-    assert(!rb_objc_is_non_native((VALUE)rcv));
-    rb_objc_finalize((VALUE)rcv);    
-}
-
-static void
-rb_objc_define_finalizer(VALUE klass)
-{
-    Class ocklass = (Class)RCLASS(klass)->ocklass;
-    assert(class_addMethod(ocklass, sel_registerName("finalize"), 
-			   (IMP)rb_objc_imp_finalize, "@@:")); 
-}
-
-void
 rb_objc_wb(void *dst, void *newval)
 {
     if (!SPECIAL_CONST_P(newval)) {
@@ -782,9 +730,7 @@
 rb_objc_newobj(size_t size)
 {
     void *obj;
-    malloc_increase += size;
-    if (!dont_gc && (ruby_gc_stress || malloc_increase > malloc_limit))
-	garbage_collect();
+    rb_gc_malloc_increase(size);
 #if USE_OBJECTS_POOL
     if (objects_pool == NULL) 
 	objects_pool = malloc(sizeof(void *) * OBJECTS_POOL_SIZE);
@@ -1873,24 +1819,8 @@
 {
     if (dont_gc)
 	return Qtrue;
-
     auto_collect(__auto_zone, AUTO_COLLECT_GENERATIONAL_COLLECTION, NULL);
-
-    gc_count++;
-#if 0
-    if (malloc_increase > malloc_limit) {
-	auto_statistics_t stats;
-	size_t live, freed;
-	auto_zone_statistics(__auto_zone, &stats);
-	live = stats.bytes_in_use_after_last_collection[1] / sizeof(RVALUE);
-	freed = stats.bytes_freed_during_last_collection[1] / sizeof(RVALUE);
-	malloc_limit += (malloc_increase - malloc_limit) * (double)live / (live + freed);
-	if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT;
-	printf("malloc_increase was %ld, malloc_limit is now %ld\n", malloc_increase, malloc_limit);
-    }
-#endif
     malloc_increase = 0;
-
     return Qtrue;
 }
 #endif
@@ -2403,15 +2333,46 @@
 }
 
 #if WITH_OBJC
+static CFMutableArrayRef __exit_finalize = NULL;
 
+static void
+rb_objc_finalize_pure_ruby_obj(VALUE obj)
+{
+    switch (RBASIC(obj)->flags & T_MASK) {
+	case T_FILE:
+	    if (RFILE(obj)->fptr != NULL) {
+		rb_io_fptr_finalize(RFILE(obj)->fptr);
+	    }
+	    break;
+    }
+}
+
 void
-rb_gc_call_finalizer_at_exit(void)
+rb_objc_keep_for_exit_finalize(VALUE v)
 {
-    struct finalize_at_exit *entry;
+    if (__exit_finalize == NULL) {
+	__exit_finalize = CFArrayCreateMutable(NULL, 0, 
+	    &kCFTypeArrayCallBacks);
+    }
+    CFArrayAppendValue(__exit_finalize, (void *)v);
+}
 
-    for (entry = finalize_at_exit_head; entry != NULL; entry = entry->next)
-	if (entry->v != Qnil)
-	    rb_objc_finalize(entry->v);
+void
+rb_gc_call_finalizer_at_exit(void)
+{
+    if (__exit_finalize != NULL) {
+	long i, count;
+	for (i = 0, count = CFArrayGetCount((CFArrayRef)__exit_finalize); 
+	     i < count; 
+	     i++) {
+	    VALUE v;
+	    v = (VALUE)CFArrayGetValueAtIndex((CFArrayRef)__exit_finalize, i);
+	    rb_objc_finalize_pure_ruby_obj(v);
+	}
+    }
+    CFArrayRemoveAllValues(__exit_finalize);
+    CFRelease(__exit_finalize);
+    auto_collect(__auto_zone, AUTO_COLLECT_FULL_COLLECTION, NULL);
 }
 
 #else /* WITH_OBJC */
@@ -2720,6 +2681,34 @@
  *  are also available via the <code>ObjectSpace</code> module.
  */
 
+#if WITH_OBJC
+static void (*old_batch_invalidate)(auto_zone_t *, auto_zone_foreach_object_t, 
+    auto_zone_cursor_t, size_t);
+
+static void
+__rb_objc_finalize(void *obj, void *data)
+{
+    if (rb_objc_is_non_native((VALUE)obj)) {
+	static SEL sel = NULL;
+	rb_objc_remove_keys(obj);
+	if (sel == NULL)
+	    sel = sel_registerName("finalize");
+	objc_msgSend(obj, sel);
+    }
+    else {
+	/* TODO: call ObjectSpace finalizers, if any */
+    }
+}
+
+static void 
+rb_objc_batch_invalidate(auto_zone_t *zone, 
+			 auto_zone_foreach_object_t foreach, 
+			 auto_zone_cursor_t cursor, size_t cursor_size) 
+{
+    foreach(cursor, __rb_objc_finalize, NULL);
+}
+#endif
+
 void
 Init_PreGC(void)
 {
@@ -2733,6 +2722,8 @@
     if (getenv("GC_DEBUG"))
 	auto_collection_parameters(__auto_zone)->log = 
 	    AUTO_LOG_COLLECTIONS | AUTO_LOG_REGIONS | AUTO_LOG_UNUSUAL;
+    old_batch_invalidate = auto_collection_parameters(__auto_zone)->batch_invalidate;
+    auto_collection_parameters(__auto_zone)->batch_invalidate = rb_objc_batch_invalidate;
 #endif
 }
 
@@ -2740,7 +2731,6 @@
 Init_PostGC(void)
 {
 #if WITH_OBJC
-    rb_objc_define_finalizer(rb_cIO);
 # if 0
     /* It is better to let Foundation start the dedicated collection thread
      * when necessary. 

Modified: MacRuby/trunk/hash.c
===================================================================
--- MacRuby/trunk/hash.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/hash.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -25,13 +25,11 @@
 #define HASH_DELETED  FL_USER1
 #define HASH_PROC_DEFAULT FL_USER2
 
-#if !WITH_OBJC
 VALUE
 rb_hash_freeze(VALUE hash)
 {
     return rb_obj_freeze(hash);
 }
-#endif
 
 VALUE rb_cHash;
 #if WITH_OBJC
@@ -269,8 +267,6 @@
 struct rb_objc_hash_struct {
     VALUE ifnone;
     bool has_proc_default; 
-    bool frozen;
-    bool tainted;
 };
 
 /* This variable will always stay NULL, we only use its address. */
@@ -293,61 +289,10 @@
 	rb_objc_set_associative_ref((void *)hash, &rb_objc_hash_assoc_key, s);
 	s->ifnone = Qnil;
 	s->has_proc_default = false;
-	s->frozen = false;
-	s->tainted = false;
     }
     return s;
 }
 
-VALUE
-rb_hash_freeze(VALUE hash)
-{
-    struct rb_objc_hash_struct *s;
-
-    s = rb_objc_hash_get_struct2(hash);
-    s->frozen = true;
-
-    return hash;
-}
-
-VALUE
-rb_hash_frozen(VALUE hash)
-{
-    struct rb_objc_hash_struct *s;
-
-    s = rb_objc_hash_get_struct(hash);
-
-    return s != NULL && s->frozen ? Qtrue : Qfalse;
-}
-
-VALUE
-rb_hash_taint(VALUE hash)
-{
-    rb_objc_hash_get_struct2(hash)->tainted = true;
-    return hash;
-}
-
-VALUE
-rb_hash_untaint(VALUE hash)
-{
-    struct rb_objc_hash_struct *s;
-    s = rb_objc_hash_get_struct(hash);
-    if (s != NULL)
-        s->tainted = false;
-    return hash;
-}
-
-
-VALUE
-rb_hash_tainted(VALUE hash)
-{
-    struct rb_objc_hash_struct *s;
-
-    s = rb_objc_hash_get_struct(hash);
-
-    return s != NULL && s->tainted ? Qtrue : Qfalse;
-}
-
 static void
 rb_objc_hash_set_struct(VALUE hash, VALUE ifnone, bool has_proc_default)
 {
@@ -358,20 +303,6 @@
     GC_WB(&s->ifnone, ifnone);
     s->has_proc_default = has_proc_default;
 }
-
-static void
-rb_objc_ary_copy_struct(VALUE old, VALUE new)
-{
-    struct rb_objc_hash_struct *s;
-
-    s = rb_objc_hash_get_struct(old);
-    if (s != NULL) {
-	struct rb_objc_hash_struct *n;
-
-	n = rb_objc_hash_get_struct2(new);
-	memcpy(n, s, sizeof(struct rb_objc_hash_struct));
-    }
-}
 #endif
 
 static VALUE
@@ -398,6 +329,7 @@
 	*(Class *)hash = RCLASS_OCID(klass);
 
     CFMakeCollectable((CFTypeRef)hash);
+    rb_gc_malloc_increase(sizeof(void *));
 
     return hash;
 #else
@@ -420,36 +352,17 @@
 #endif
 }
 
-#if WITH_OBJC
-static VALUE rb_hash_replace(VALUE, VALUE);
-
-VALUE
-rb_hash_clone(VALUE hash)
-{
-    VALUE klass, dup;
-    long n;
-
-    klass = rb_obj_class(hash);
-    dup = hash_alloc(klass);
-    rb_hash_replace(dup, hash);
-    rb_objc_ary_copy_struct(hash, dup);
-    return dup;
-}
-#endif
-
 static void
 rb_hash_modify_check(VALUE hash)
 {
 #if WITH_OBJC
     bool _CFDictionaryIsMutable(void *);
-    if (rb_hash_frozen(hash) == Qtrue) rb_error_frozen("hash");
     if (!_CFDictionaryIsMutable((void *)hash)) 
 	rb_raise(rb_eRuntimeError, "can't modify immutable hash");
-#else
+#endif
     if (OBJ_FROZEN(hash)) rb_error_frozen("hash");
     if (!OBJ_TAINTED(hash) && rb_safe_level() >= 4)
 	rb_raise(rb_eSecurityError, "Insecure: can't modify hash");
-#endif
 }
 
 struct st_table *
@@ -1313,8 +1226,8 @@
 {
     rb_hash_modify(hash);
 #if WITH_OBJC
-    if (TYPE(key) == T_STRING)
-	key = rb_obj_dup(key); /* FIXME temporary fix. */
+//    if (TYPE(key) == T_STRING)
+//	key = rb_obj_dup(key); /* FIXME temporary fix. */
     CFDictionarySetValue((CFMutableDictionaryRef)hash, (const void *)key,
 	(const void *)val);
 #else
@@ -2208,12 +2121,12 @@
 static VALUE
 env_delete(VALUE obj, VALUE name)
 {
-    char *nam, *val;
+    const char *nam, *val;
 
     rb_secure(4);
     SafeStringValue(name);
-    nam = RSTRING_PTR(name);
-    if (strlen(nam) != RSTRING_LEN(name)) {
+    nam = RSTRING_CPTR(name);
+    if (strlen(nam) != RSTRING_CLEN(name)) {
 	rb_raise(rb_eArgError, "bad environment variable name");
     }
     val = getenv(nam);
@@ -2247,12 +2160,12 @@
 static VALUE
 rb_f_getenv(VALUE obj, VALUE name)
 {
-    char *nam, *env;
+    const char *nam, *env;
 
     rb_secure(4);
     SafeStringValue(name);
-    nam = RSTRING_PTR(name);
-    if (strlen(nam) != RSTRING_LEN(name)) {
+    nam = RSTRING_CPTR(name);
+    if (strlen(nam) != RSTRING_CLEN(name)) {
 	rb_raise(rb_eArgError, "bad environment variable name");
     }
     env = getenv(nam);
@@ -2278,7 +2191,7 @@
 {
     VALUE key, if_none;
     long block_given;
-    char *nam, *env;
+    const char *nam, *env;
 
     rb_secure(4);
     rb_scan_args(argc, argv, "11", &key, &if_none);
@@ -2287,8 +2200,8 @@
 	rb_warn("block supersedes default value argument");
     }
     SafeStringValue(key);
-    nam = RSTRING_PTR(key);
-    if (strlen(nam) != RSTRING_LEN(key)) {
+    nam = RSTRING_CPTR(key);
+    if (strlen(nam) != RSTRING_CLEN(key)) {
 	rb_raise(rb_eArgError, "bad environment variable name");
     }
     env = getenv(nam);
@@ -2309,7 +2222,7 @@
 }
 
 static void
-path_tainted_p(char *path)
+path_tainted_p(const char *path)
 {
     path_tainted = rb_path_check(path)?0:1;
 }
@@ -2435,7 +2348,7 @@
 static VALUE
 env_aset(VALUE obj, VALUE nm, VALUE val)
 {
-    char *name, *value;
+    const char *name, *value;
 
     if (rb_safe_level() >= 4) {
 	rb_raise(rb_eSecurityError, "can't change environment variable");
@@ -2446,11 +2359,11 @@
     }
     StringValue(nm);
     StringValue(val);
-    name = RSTRING_PTR(nm);
-    value = RSTRING_PTR(val);
-    if (strlen(name) != RSTRING_LEN(nm))
+    name = RSTRING_CPTR(nm);
+    value = RSTRING_CPTR(val);
+    if (strlen(name) != RSTRING_CLEN(nm))
 	rb_raise(rb_eArgError, "bad environment variable name");
-    if (strlen(value) != RSTRING_LEN(val))
+    if (strlen(value) != RSTRING_CLEN(val))
 	rb_raise(rb_eArgError, "bad environment variable value");
 
     ruby_setenv(name, value);
@@ -2756,7 +2669,7 @@
 
     rb_secure(4);
     s = StringValuePtr(key);
-    if (strlen(s) != RSTRING_LEN(key))
+    if (strlen(s) != RSTRING_CLEN(key))
 	rb_raise(rb_eArgError, "bad environment variable name");
     if (getenv(s)) return Qtrue;
     return Qfalse;
@@ -2769,7 +2682,7 @@
 
     rb_secure(4);
     s = StringValuePtr(key);
-    if (strlen(s) != RSTRING_LEN(key))
+    if (strlen(s) != RSTRING_CLEN(key))
 	rb_raise(rb_eArgError, "bad environment variable name");
     e = getenv(s);
     if (e) return rb_assoc_new(key, rb_tainted_str_new2(e));
@@ -2789,7 +2702,7 @@
 	char *s = strchr(*env, '=');
 	if (s++) {
 	    long len = strlen(s);
-	    if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
+	    if (RSTRING_CLEN(obj) == len && strncmp(s, RSTRING_CPTR(obj), len) == 0) {
 		FREE_ENVIRON(environ);
 		return Qtrue;
 	    }
@@ -2813,7 +2726,7 @@
 	char *s = strchr(*env, '=');
 	if (s++) {
 	    long len = strlen(s);
-	    if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
+	    if (RSTRING_CLEN(obj) == len && strncmp(s, RSTRING_CPTR(obj), len) == 0) {
 		VALUE result = rb_assoc_new(rb_tainted_str_new(*env, s-*env-1), obj);
 		FREE_ENVIRON(environ);
 		return result;
@@ -2838,7 +2751,7 @@
 	char *s = strchr(*env, '=');
 	if (s++) {
 	    long len = strlen(s);
-	    if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
+	    if (RSTRING_CLEN(value) == len && strncmp(s, RSTRING_CPTR(value), len) == 0) {
 		str = env_str_new(*env, s-*env-1);
 		FREE_ENVIRON(environ);
 		return str;
@@ -2895,7 +2808,7 @@
 	char *s = strchr(*env, '=');
 	if (s) {
 	    VALUE key = env_str_new(*env, s-*env);
-	    VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
+	    VALUE val = env_str_new2(getenv(RSTRING_CPTR(key)));
 	    env_delete(Qnil, key);
 	    return rb_assoc_new(key, val);
 	}
@@ -3115,10 +3028,6 @@
     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);
-    rb_define_method(rb_cHash, "freeze", rb_hash_freeze, 0);
-    rb_define_method(rb_cHash, "frozen?", rb_hash_frozen, 0);
-    rb_define_method(rb_cHash, "taint", rb_hash_taint, 0);
-    rb_define_method(rb_cHash, "tainted?", rb_hash_tainted, 0);
 #else
     rb_cHash = rb_define_class("Hash", rb_cObject);
 #endif

Modified: MacRuby/trunk/include/ruby/ruby.h
===================================================================
--- MacRuby/trunk/include/ruby/ruby.h	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/include/ruby/ruby.h	2008-05-11 00:16:55 UTC (rev 190)
@@ -369,7 +369,7 @@
 #define NUM2DBL(x) rb_num2dbl((VALUE)(x))
 
 /* obsolete API - use StringValue() */
-char *rb_str2cstr(VALUE,long*);
+const char *rb_str2cstr(VALUE,long*);
 /* obsolete API - use StringValuePtr() */
 #define STR2CSTR(x) rb_str2cstr((VALUE)(x),0)
 
@@ -389,14 +389,10 @@
     if (rb_safe_level() >= 3) FL_SET(obj, FL_TAINT);\
 } while (0)
 #if WITH_OBJC
-void rb_objc_keep_for_exit_finalize(VALUE v);
 # define OBJSETUP(obj,c,t) do {\
     __OBJSETUP(obj,c,t);\
     if (c != 0) \
 	RBASIC(obj)->isa = (void *)RCLASS_OCID(c); \
-    if (!SPECIAL_CONST_P(obj) \
-	&& (BUILTIN_TYPE(obj) == T_FILE /*|| BUILTIN_TYPE(obj) == T_DATA*/)) \
-	rb_objc_keep_for_exit_finalize((VALUE)obj); \
 } while (0)
 #else
 # define OBJSETUP(obj,c,t) __OBJSETUP(obj,c,t)

Modified: MacRuby/trunk/io.c
===================================================================
--- MacRuby/trunk/io.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/io.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -464,6 +464,11 @@
 
     io->fptr = 0;
 
+#if WITH_OBJC
+    void rb_objc_keep_for_exit_finalize(VALUE);
+    rb_objc_keep_for_exit_finalize((VALUE)io);
+#endif
+
     return (VALUE)io;
 }
 

Modified: MacRuby/trunk/iseq.c
===================================================================
--- MacRuby/trunk/iseq.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/iseq.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -811,7 +811,7 @@
     rb_str_cat2(str, "== disasm: ");
 
     rb_str_concat(str, iseq_inspect(iseqdat->self));
-    if ((i = RSTRING_LEN(str)) < header_minlen) {
+    if ((i = RSTRING_CLEN(str)) < header_minlen) {
 	rb_str_resize(str, header_minlen);
 	memset(RSTRING_PTR(str) + i, '=', header_minlen - i);
 	RSTRING_SYNC(str);

Modified: MacRuby/trunk/load.c
===================================================================
--- MacRuby/trunk/load.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/load.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -58,7 +58,7 @@
     for (i = 0; i < RARRAY_LEN(load_path); ++i) {
 	VALUE p = RARRAY_AT(load_path, i);
 	const char *s = StringValuePtr(p);
-	long n = RSTRING_LEN(p);
+	long n = RSTRING_CLEN(p);
 
 	if (vlen < n + len + 1) continue;
 	if (n && (strncmp(name, s, n) || name[n] != '/')) continue;
@@ -123,13 +123,13 @@
     for (i = 0, count = RARRAY_LEN(features); i < count; ++i) {
 	v = RARRAY_AT(features, i);
 	f = StringValueCStr(v);
-	if ((n = RSTRING_LEN(v)) < len) continue;
+	if ((n = RSTRING_CLEN(v)) < len) continue;
 	if (strncmp(f, feature, len) != 0) {
 	    if (expanded) continue;
 	    if (!load_path) load_path = get_load_path();
 	    if (!(p = loaded_feature_path(f, n, feature, len, type, load_path)))
 		continue;
-	    f += RSTRING_LEN(p) + 1;
+	    f += RSTRING_CLEN(p) + 1;
 	}
 	if (!*(e = f + len)) {
 	    if (ext) continue;

Modified: MacRuby/trunk/marshal.c
===================================================================
--- MacRuby/trunk/marshal.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/marshal.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -182,7 +182,7 @@
 {
     VALUE buf = arg->str;
     rb_str_buf_cat(buf, s, n);
-    if (arg->dest && RSTRING_LEN(buf) >= BUFSIZ) {
+    if (arg->dest && RSTRING_CLEN(buf) >= BUFSIZ) {
 	if (arg->taint) OBJ_TAINT(buf);
 	rb_io_write(arg->dest, buf);
 	rb_str_resize(buf, 0);
@@ -916,7 +916,7 @@
     int c;
 
     if (TYPE(arg->src) == T_STRING) {
-	if (RSTRING_LEN(arg->src) > arg->offset) {
+	if (RSTRING_CLEN(arg->src) > arg->offset) {
 	    c = (unsigned char)RSTRING_CPTR(arg->src)[arg->offset++];
 	}
 	else {
@@ -989,7 +989,7 @@
 
     if (len == 0) return rb_str_new(0, 0);
     if (TYPE(arg->src) == T_STRING) {
-	if (RSTRING_LEN(arg->src) - arg->offset >= len) {
+	if (RSTRING_CLEN(arg->src) - arg->offset >= len) {
 	    str = rb_str_new(RSTRING_CPTR(arg->src)+arg->offset, len);
 	    arg->offset += len;
 	}
@@ -1004,7 +1004,7 @@
 	str = rb_funcall2(src, s_read, 1, &n);
 	if (NIL_P(str)) goto too_short;
 	StringValue(str);
-	if (RSTRING_LEN(str) != len) goto too_short;
+	if (RSTRING_CLEN(str) != len) goto too_short;
 	if (OBJ_TAINTED(str)) arg->taint = Qtrue;
     }
     return str;
@@ -1269,7 +1269,7 @@
 	    else {
 		char *e;
 		d = strtod(ptr, &e);
-		d = load_mantissa(d, e, RSTRING_LEN(str) - (e - ptr));
+		d = load_mantissa(d, e, RSTRING_CLEN(str) - (e - ptr));
 	    }
 	    v = DOUBLE2NUM(d);
 	    v = r_entry(v, arg);

Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/objc.m	2008-05-11 00:16:55 UTC (rev 190)
@@ -2506,11 +2506,10 @@
 }
 #endif
 
+#if 0
 /* XXX the ivar cluster API is not used yet, and may not simply be used. 
  */
-
 #define IVAR_CLUSTER_NAME "__rivars__"
-
 void
 rb_objc_install_ivar_cluster(Class klass)
 {
@@ -2531,7 +2530,49 @@
 {
     assert(object_setInstanceVariable((id)obj, IVAR_CLUSTER_NAME, v) != NULL);
 }
+#endif
 
+static CFMutableDictionaryRef __obj_flags;
+
+bool
+rb_objc_flag_check(const void *obj, int flag)
+{
+    long v;
+
+    if (__obj_flags == NULL)
+	return false;
+ 
+    v = (long)CFDictionaryGetValue(__obj_flags, obj);
+    if (v == 0)
+	return false;
+
+    return (v & flag) == flag;
+}
+
+void
+rb_objc_flag_set(const void *obj, int flag, bool val)
+{
+    long v;
+
+    if (__obj_flags == NULL) {
+	__obj_flags = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
+    }
+    v = (long)CFDictionaryGetValue(__obj_flags, obj);
+    if (val) {
+	v |= flag;
+    }
+    else {
+	v ^= flag;
+    }
+    CFDictionarySetValue(__obj_flags, obj, (void *)v);
+}
+
+void
+rb_objc_remove_keys(const void *obj)
+{
+    CFDictionaryRemoveValue(__obj_flags, obj);
+}
+
 static void
 rb_objc_get_types_for_format_str(char **octypes, const int len, 
 				 const char *format_str)

Modified: MacRuby/trunk/object.c
===================================================================
--- MacRuby/trunk/object.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/object.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -159,19 +159,8 @@
 {
 #if WITH_OBJC
     if (rb_objc_is_non_native(obj)) {
-	int type = TYPE(obj);
-	if (type == T_ARRAY) {
-	    if (rb_ary_tainted(obj)) 
-		rb_ary_taint(dest);
-	}
-	else if (type == T_HASH) {
-	    if (rb_hash_tainted(obj)) 
-		rb_hash_taint(dest);
-	}
-	else if (type == T_STRING) {
-	    if (rb_str_tainted(obj)) 
-		rb_str_taint(dest);
-	}
+	if (rb_objc_flag_check(obj, FL_TAINT))
+	    rb_objc_flag_set(dest, FL_TAINT);
 	goto call_init_copy;
     }
 #endif
@@ -253,15 +242,10 @@
     }
 #if WITH_OBJC
     if (rb_objc_is_non_native(obj)) {
-	int type = TYPE(obj);
-	if (type == T_ARRAY)
-	    return rb_ary_clone(obj);
-	if (type == T_HASH)
-	    return rb_hash_clone(obj);
-	if (type == T_STRING)
-	    return rb_str_clone(obj);
         clone = rb_obj_alloc(rb_obj_class(obj));
         init_copy(clone, obj);
+	if (OBJ_FROZEN(obj))
+	    OBJ_FREEZE(clone);
 	return clone;
     }
 #endif
@@ -354,12 +338,20 @@
 {
     VALUE str2;
     const char *ivname;
+    const char *cstr;
 
+    cstr = RSTRING_CPTR(str);
+
     /* need not to show internal data */
     if (CLASS_OF(value) == 0) return ST_CONTINUE;
     if (!rb_is_instance_id(id)) return ST_CONTINUE;
-    if (RSTRING_PTR(str)[0] == '-') { /* first element */
+
+    if (cstr[0] == '-') { /* first element */
+#if WITH_OBJC
+	rb_str_update(str, 0, 0, rb_str_new2("#"));
+#else
 	RSTRING_PTR(str)[0] = '#';
+#endif
 	rb_str_cat2(str, " ");
     }
     else {
@@ -385,7 +377,11 @@
 	rb_ivar_foreach(obj, inspect_i, str);
     }
     rb_str_cat2(str, ">");
+#if WITH_OBJC
+    rb_str_update(str, 0, 0, rb_str_new2("#"));
+#else
     RSTRING_PTR(str)[0] = '#';
+#endif
     OBJ_INFECT(str, obj);
 
     return str;
@@ -683,14 +679,7 @@
 {
 #if WITH_OBJC
     if (!SPECIAL_CONST_P(obj) && rb_objc_is_non_native(obj)) {
-	int type = TYPE(obj);
-	if (type == T_ARRAY)
-	    return rb_ary_tainted(obj);
-	if (type == T_HASH)
-	    return rb_hash_tainted(obj);
-	if (type == T_STRING)
-	    return rb_str_tainted(obj);
-	return Qfalse;
+	return rb_objc_flag_check(obj, FL_TAINT) ? Qtrue : Qfalse;
     }
 #endif
     if (FL_TEST(obj, FL_TAINT))
@@ -713,14 +702,8 @@
     rb_secure(4);
 #if WITH_OBJC
     if (!SPECIAL_CONST_P(obj) && rb_objc_is_non_native(obj)) {
-	int type = TYPE(obj);
-	if (type == T_ARRAY)
-	    return rb_ary_taint(obj);
-	if (type == T_HASH)
-	    return rb_hash_taint(obj);
-	if (type == T_STRING)
-	    return rb_str_taint(obj);
-	rb_raise(rb_eRuntimeError, "can't taint pure objc objects");
+	rb_objc_flag_set(obj, FL_TAINT, true);
+	return obj;
     }
 #endif
     if (!OBJ_TAINTED(obj)) {
@@ -746,16 +729,8 @@
     rb_secure(3);
 #if WITH_OBJC
     if (!SPECIAL_CONST_P(obj) && rb_objc_is_non_native(obj)) {
-	int type = TYPE(obj);
-	if (type == T_ARRAY)
-	    return rb_ary_untaint(obj);
-	else if (type == T_HASH)
-	    return rb_hash_untaint(obj);
-	else if (type == T_STRING)
-	    return rb_str_untaint(obj);
-	else
-	    rb_raise(rb_eRuntimeError, "can't untaint pure objc object `%s'",
-		    RSTRING_PTR(rb_inspect(obj)));
+	rb_objc_flag_set(obj, FL_TAINT, false);
+	return obj;
     }
 #endif
     if (OBJ_TAINTED(obj)) {
@@ -810,18 +785,7 @@
 	}
 #if WITH_OBJC
 	else if (rb_objc_is_non_native(obj)) {
-	    int type = TYPE(obj);
-	    if (type == T_ARRAY)
-		return rb_ary_freeze(obj);
-	    else if (type == T_HASH)
-		return rb_hash_freeze(obj);
-	    else if (type == T_STRING)
-		return rb_str_freeze(obj);
-	    else {
-		if (rb_cString != 0 && rb_cArray != 0 && rb_cHash != 0)
-		    rb_raise(rb_eRuntimeError, "can't freeze pure objc " \
-			     "object `%p'", RSTRING_CPTR(rb_inspect(obj)));
-	    }
+	    rb_objc_flag_set(obj, FL_FREEZE, true);
 	}
 #endif
 	else {
@@ -851,14 +815,7 @@
     }
 #if WITH_OBJC
     if (rb_objc_is_non_native(obj)) {
-	int type = TYPE(obj);
-	if (type == T_ARRAY)
-	    return rb_ary_frozen_p(obj);
-	if (type == T_HASH)
-	    return rb_hash_frozen(obj);
-	if (type == T_STRING)
-	    return rb_str_frozen(obj);
-	return Qfalse;
+	return rb_objc_flag_check(obj, FL_FREEZE) ? Qtrue : Qfalse;
     }
 #endif
     if (FL_TEST(obj, FL_FREEZE)) return Qtrue;
@@ -1522,15 +1479,9 @@
 #if WITH_OBJC
     if (FL_TEST(klass, RCLASS_OBJC_IMPORTED)) {
 	static SEL sel_new = 0;
-	id ocid;
 	if (sel_new == 0)
 	    sel_new = sel_registerName("new");
-	ocid = objc_msgSend((id)RCLASS_OCID(klass), sel_new);
-	/* FIXME this is a temporary solution until the Ruby primitive classes
-	 * are re-implemented using their CF equivalents.
-	 */
-	unsigned rb_objc_ocid_to_rval(void **ocval, VALUE *rbval);
-	rb_objc_ocid_to_rval((void **)&ocid, &obj);
+	obj = (VALUE)objc_msgSend((id)RCLASS_OCID(klass), sel_new);
 	return obj;
     }
 #endif
@@ -2229,12 +2180,12 @@
 double
 rb_str_to_dbl(VALUE str, int badcheck)
 {
-    char *s;
+    const char *s;
     long len;
 
     StringValue(str);
-    s = RSTRING_PTR(str);
-    len = RSTRING_LEN(str);
+    s = RSTRING_CPTR(str);
+    len = RSTRING_CLEN(str);
     if (s) {
 	if (s[len]) {		/* no sentinel somehow */
 	    char *p = ALLOCA_N(char, len+1);
@@ -2321,15 +2272,15 @@
     return RFLOAT_VALUE(rb_Float(val));
 }
 
-char*
+const char*
 rb_str2cstr(VALUE str, long *len)
 {
     StringValue(str);
-    if (len) *len = RSTRING_LEN(str);
-    else if (RTEST(ruby_verbose) && RSTRING_LEN(str) != strlen(RSTRING_PTR(str))) {
+    if (len) *len = RSTRING_CLEN(str);
+    else if (RTEST(ruby_verbose) && RSTRING_CLEN(str) != strlen(RSTRING_CPTR(str))) {
 	rb_warn("string contains \\0 character");
     }
-    return RSTRING_PTR(str);
+    return RSTRING_CPTR(str);
 }
 
 VALUE

Modified: MacRuby/trunk/pack.c
===================================================================
--- MacRuby/trunk/pack.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/pack.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -841,14 +841,14 @@
 
 	  case 'X':		/* back up byte */
 	  shrink:
-	    plen = RSTRING_LEN(res);
+	    plen = RSTRING_CLEN(res);
 	    if (plen < len)
 		rb_raise(rb_eArgError, "X outside of string");
 	    rb_str_set_len(res, plen - len);
 	    break;
 
 	  case '@':		/* null fill to absolute position */
-	    len -= RSTRING_LEN(res);
+	    len -= RSTRING_CLEN(res);
 	    if (len > 0) goto grow;
 	    len = -len;
 	    if (len > 0) goto shrink;
@@ -910,9 +910,9 @@
 	    from = THISFROM;
 	    if (!NIL_P(from)) {
 		StringValue(from);
-		if (RSTRING_LEN(from) < len) {
+		if (RSTRING_CLEN(from) < len) {
 		    rb_raise(rb_eArgError, "too short buffer for P(%ld for %ld)",
-			     RSTRING_LEN(from), len);
+			     RSTRING_CLEN(from), len);
 		}
 	    }
 	    len = 1;
@@ -1895,7 +1895,7 @@
 		    for (i = 0; i < count; i++) {
 			VALUE p = RARRAY_AT(a, i);
 			if (TYPE(p) == T_STRING && RSTRING_CPTR(p) == t) {
-			    if (len < RSTRING_LEN(p)) {
+			    if (len < RSTRING_CLEN(p)) {
 				tmp = rb_tainted_str_new(t, len);
 				rb_str_associate(tmp, a);
 			    }
@@ -1918,7 +1918,7 @@
 		    pend = p + RARRAY_LEN(a);
 		    while (p < pend) {
 			if (TYPE(*p) == T_STRING && RSTRING_CPTR(*p) == t) {
-			    if (len < RSTRING_LEN(*p)) {
+			    if (len < RSTRING_CLEN(*p)) {
 				tmp = rb_tainted_str_new(t, len);
 				rb_str_associate(tmp, a);
 			    }

Modified: MacRuby/trunk/process.c
===================================================================
--- MacRuby/trunk/process.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/process.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -1022,7 +1022,7 @@
 
     args = ALLOCA_N(char*, argc+1);
     for (i=0; i<argc; i++) {
-	args[i] = RSTRING_CPTR(argv[i]);
+	args[i] = (char *)RSTRING_CPTR(argv[i]);
     }
     args[i] = 0;
     if (args[0]) {

Modified: MacRuby/trunk/re.c
===================================================================
--- MacRuby/trunk/re.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/re.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -309,9 +309,15 @@
 rb_reg_source(VALUE re)
 {
     VALUE str;
+    const char *cstr;
+    long clen;
 
     rb_reg_check(re);
-    str = rb_enc_str_new(RREGEXP(re)->str,RREGEXP(re)->len, rb_enc_get(re));
+    cstr = RREGEXP(re)->str;
+    clen = RREGEXP(re)->len;
+    if (clen == 0)
+	cstr = NULL;
+    str = rb_enc_str_new(cstr, clen, rb_enc_get(re));
     if (OBJ_TAINTED(re)) OBJ_TAINT(str);
     return str;
 }
@@ -1127,12 +1133,12 @@
 	range = -pos;
     }
     else {
-	range = RSTRING_LEN(str) - pos;
+	range = RSTRING_CLEN(str) - pos;
     }
 
     enc = (RREGEXP(re)->ptr)->enc;
 
-    if (pos > 0 && ONIGENC_MBC_MAXLEN(enc) != 1 && pos < RSTRING_LEN(str)) {
+    if (pos > 0 && ONIGENC_MBC_MAXLEN(enc) != 1 && pos < RSTRING_CLEN(str)) {
 	 string = (UChar*)RSTRING_CPTR(str);
 
 	 if (range > 0) {
@@ -1324,7 +1330,7 @@
     if (BEG(0) == -1) return Qnil;
     str = RMATCH(match)->str;
     pos = END(0);
-    str = rb_str_subseq(str, pos, RSTRING_LEN(str) - pos);
+    str = rb_str_subseq(str, pos, RSTRING_CLEN(str) - pos);
     if (OBJ_TAINTED(match)) OBJ_TAINT(str);
     return str;
 }
@@ -2295,7 +2301,7 @@
 rb_reg_regcomp(VALUE str)
 {
     volatile VALUE save_str = str;
-    if (reg_cache && RREGEXP(reg_cache)->len == RSTRING_LEN(str)
+    if (reg_cache && RREGEXP(reg_cache)->len == RSTRING_CLEN(str)
 	&& ENCODING_GET(reg_cache) == ENCODING_GET(str)
         && memcmp(RREGEXP(reg_cache)->str, RSTRING_CPTR(str), RSTRING_CLEN(str)) == 0)
 	return reg_cache;
@@ -2647,7 +2653,7 @@
 	str = argv[0];
 	ptr = StringValuePtr(str);
 	if (enc
-	    ? rb_reg_initialize(self, ptr, RSTRING_LEN(str), enc, flags, err)
+	    ? rb_reg_initialize(self, ptr, RSTRING_CLEN(str), enc, flags, err)
 	    : rb_reg_initialize_str(self, str, flags, err)) {
 	    rb_reg_raise_str(str, flags, err);
 	}

Modified: MacRuby/trunk/ruby.c
===================================================================
--- MacRuby/trunk/ruby.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/ruby.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -303,7 +303,7 @@
 static VALUE
 expand_include_path(VALUE path)
 {
-    char *p = RSTRING_CPTR(path);
+    const char *p = RSTRING_CPTR(path);
     if (!p)
 	return path;
     if (*p == '.' && p[1] == '/')
@@ -1324,7 +1324,8 @@
 static void
 set_arg0(VALUE val, ID id)
 {
-    char *s, *t;
+    const char *s;
+    char *t;
     long i;
 
     if (origarg.argv == 0)

Modified: MacRuby/trunk/signal.c
===================================================================
--- MacRuby/trunk/signal.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/signal.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -714,7 +714,7 @@
 	command = rb_check_string_type(*cmd);
 	if (!NIL_P(command)) {
 	    SafeStringValue(command);	/* taint check */
-	    switch (RSTRING_LEN(command)) {
+	    switch (RSTRING_CLEN(command)) {
 	      case 0:
                 goto sig_ign;
 		break;

Modified: MacRuby/trunk/sprintf.c
===================================================================
--- MacRuby/trunk/sprintf.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/sprintf.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -282,7 +282,7 @@
     StringValue(fmt);
     enc = rb_enc_get(fmt);
     fmt = rb_str_new4(fmt);
-    p = RSTRING_PTR(fmt);
+    p = RSTRING_PTR(fmt); /* ok */
     end = p + RSTRING_LEN(fmt);
     blen = 0;
     bsiz = 120;

Modified: MacRuby/trunk/string.c
===================================================================
--- MacRuby/trunk/string.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/string.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -97,61 +97,19 @@
 
 #else
 
-struct rb_objc_str_struct {
-    void *cfdata;
-    bool tainted;
-    bool frozen;
-};
+static void *rb_str_cfdata_key;
 
-/* This variable will always stay NULL, we only use its address. */
-static void *rb_objc_str_assoc_key = NULL;
-
-static struct rb_objc_str_struct *
-rb_objc_str_get_struct(VALUE str)
+static inline void
+rb_str_cfdata_set(VALUE str, void *cfdata)
 {
-    return rb_objc_get_associative_ref((void *)str, &rb_objc_str_assoc_key);
+    rb_objc_set_associative_ref((void *)str, &rb_str_cfdata_key,
+	    cfdata);
 }
 
-static struct rb_objc_str_struct *
-rb_objc_str_get_struct2(VALUE str)
-{
-    struct rb_objc_str_struct *s;
-
-    s = rb_objc_str_get_struct(str);
-    if (s == NULL) {
-	s = xmalloc(sizeof(struct rb_objc_str_struct));
-	rb_objc_set_associative_ref((void *)str, &rb_objc_str_assoc_key, s);
-	s->cfdata = NULL;
-    }
-    return s;
-}
-
-static void
-rb_objc_str_copy_struct(VALUE old, VALUE new)
-{
-    struct rb_objc_str_struct *s;
-
-    s = rb_objc_str_get_struct(old);
-    if (s != NULL) {
-	struct rb_objc_str_struct *n;
-
-	n = rb_objc_str_get_struct2(new);
-	memcpy(n, s, sizeof(struct rb_objc_str_struct));
-	if (n->cfdata != NULL) {
-	    GC_WB(&n->cfdata, CFDataCreateMutableCopy(NULL, 0, 
-		(CFDataRef)n->cfdata));
-	    CFMakeCollectable(n->cfdata);
-	}
-    }
-}
-
 static inline void *
 rb_str_cfdata2(VALUE str) 
 {
-    struct rb_objc_str_struct *s;
-
-    s = rb_objc_str_get_struct(str);
-    return s != NULL ? s->cfdata : NULL;
+    return rb_objc_get_associative_ref((void *)str, &rb_str_cfdata_key);
 }
 
 static inline bool
@@ -163,10 +121,10 @@
 static void *
 rb_str_cfdata(VALUE str)
 {
-    struct rb_objc_str_struct *s;
+    void *cfdata;
 
-    s = rb_objc_str_get_struct2(str);
-    if (s->cfdata == NULL) {
+    cfdata = rb_str_cfdata2(str);
+    if (cfdata == NULL) {
 	CFDataRef data;
 	CFMutableDataRef mdata;
 	long len;
@@ -185,11 +143,12 @@
 	CFDataSetLength(mdata, len + 1); 
 	CFDataSetLength(mdata, len);
 	//assert(strcmp(CFDataGetBytePtr(mdata), CFStringGetCStringPtr((CFStringRef)str, 0))==0);
-	GC_WB(&s->cfdata, mdata);
+	cfdata = (void *)mdata;
+	rb_str_cfdata_set(str, cfdata);
 	CFRelease((CFTypeRef)data);
-	CFMakeCollectable(s->cfdata);
+	CFMakeCollectable(cfdata);
     }
-    return s->cfdata;    
+    return cfdata;    
 }
 
 char *
@@ -208,17 +167,17 @@
 void
 rb_str_bytesync(VALUE str)
 {
-    struct rb_objc_str_struct *s;
+    void *cfdata;
 
-    s = rb_objc_str_get_struct2(str);
-    if (s != NULL && s->cfdata != NULL) {
+    cfdata = rb_str_cfdata2(str);
+    if (cfdata != NULL) {
 	CFDataRef data;
 	CFIndex datalen;
 	const UInt8 *dataptr;
 	CFStringRef bytestr;
 	const char *strptr;
 
-	data = (CFDataRef)s->cfdata;
+	data = (CFDataRef)cfdata;
 	datalen = CFDataGetLength(data);
 	dataptr = CFDataGetBytePtr(data);
 	bytestr = CFStringCreateWithBytesNoCopy(
@@ -236,7 +195,7 @@
 		&& ((const char *)dataptr == strptr
 		    || dataptr == NULL
 		    || memcmp((const char *)dataptr, strptr, datalen) == 0)) {
-		s->cfdata = NULL;
+		rb_str_cfdata_set(str, NULL);
 	    }
 	}
     }
@@ -245,51 +204,10 @@
 VALUE
 rb_str_freeze(VALUE str)
 {
-    rb_objc_str_get_struct2(str)->frozen = true;
+    rb_obj_freeze(str);
     return str;
 }
 
-VALUE
-rb_str_frozen(VALUE str)
-{
-    struct rb_objc_str_struct *s;
-    s = rb_objc_str_get_struct(str);
-    return s != NULL && s->frozen ? Qtrue : Qfalse;
-}
-
-VALUE
-rb_str_taint(VALUE str)
-{
-    rb_objc_str_get_struct2(str)->tainted = true;
-    return str;
-}
-
-VALUE
-rb_str_untaint(VALUE str)
-{
-    struct rb_objc_str_struct *s;
-    s = rb_objc_str_get_struct(str);
-    if (s != NULL)
-	s->tainted = false;
-    return str;
-}
-
-VALUE
-rb_str_tainted(VALUE str)
-{
-    struct rb_objc_str_struct *s;
-    s = rb_objc_str_get_struct(str);
-    return s != NULL && s->tainted ? Qtrue : Qfalse;
-}
-
-VALUE
-rb_str_clone(VALUE str)
-{
-    VALUE dup = rb_str_dup(str);
-    rb_objc_str_copy_struct(str, dup);
-    return dup;
-}
-
 static VALUE
 rb_str_bytestring_m(VALUE str)
 {
@@ -546,11 +464,7 @@
 static inline void
 str_frozen_check(VALUE s)
 {
-#if WITH_OBJC
-    if (rb_str_frozen(s) == Qtrue) {
-#else
     if (OBJ_FROZEN(s)) {
-#endif
 	rb_raise(rb_eRuntimeError, "string frozen");
     }
 }
@@ -602,13 +516,11 @@
 	CFRelease(substr);
     }
     else {
-	struct rb_objc_str_struct *s;
 	CFMutableDataRef data;
 
-	s = rb_objc_str_get_struct2(str);
 	data = CFDataCreateMutable(NULL, 0);
 	CFDataAppendBytes(data, (const UInt8 *)dataptr, datalen);
-	GC_WB(&s->cfdata, (void *)data);
+	rb_str_cfdata_set(str, data);
 	CFMakeCollectable(data);
     }
 }
@@ -646,6 +558,7 @@
     }
     if (need_padding)
 	CFStringPad((CFMutableStringRef)str, CFSTR(" "), len, 0);
+    rb_gc_malloc_increase(sizeof(UniChar) * len);
 #else
     if (len > RSTRING_EMBED_LEN_MAX) {
 	RSTRING(str)->as.heap.aux.capa = len;
@@ -708,12 +621,7 @@
 rb_tainted_str_new(const char *ptr, long len)
 {
     VALUE str = rb_str_new(ptr, len);
-
-#if WITH_OBJC 
-    rb_str_taint(str);
-#else
     OBJ_TAINT(str);
-#endif
     return str;
 }
 
@@ -721,12 +629,7 @@
 rb_tainted_str_new2(const char *ptr)
 {
     VALUE str = rb_str_new2(ptr);
-
-#if WITH_OBJC 
-    rb_str_taint(str);
-#else
     OBJ_TAINT(str);
-#endif
     return str;
 }
 
@@ -982,18 +885,9 @@
 VALUE
 rb_str_dup(VALUE str)
 {
-#if WITH_OBJC
-    CFMutableStringRef copy = CFStringCreateMutableCopy(NULL, 0, 
-	(CFStringRef)str);
-    CFMakeCollectable(copy);
-    if (OBJ_TAINTED(str)) 
-	OBJ_TAINT(copy);
-    return (VALUE)copy;
-#else
     VALUE dup = str_alloc(rb_obj_class(str));
     rb_str_replace(dup, str);
     return dup;
-#endif
 }
 
 
@@ -1318,18 +1212,14 @@
     bool _CFStringIsMutable(void *);
     if (!__CFStringIsMutable(str)) 
 	rb_raise(rb_eRuntimeError, "can't modify immutable string");
-    if (rb_str_frozen(str) == Qtrue)
-	rb_error_frozen("string");
-    if (rb_str_tainted(str) == Qfalse && rb_safe_level() >= 4)
-	rb_raise(rb_eSecurityError, "Insecure: can't modify string");
 #else
     if (FL_TEST(str, STR_TMPLOCK)) {
 	rb_raise(rb_eRuntimeError, "can't modify string; temporarily locked");
     }
+#endif
     if (OBJ_FROZEN(str)) rb_error_frozen("string");
     if (!OBJ_TAINTED(str) && rb_safe_level() >= 4)
 	rb_raise(rb_eSecurityError, "Insecure: can't modify string");
-#endif
 }
 
 #if !WITH_OBJC
@@ -1447,8 +1337,14 @@
     data = (CFDataRef)rb_str_cfdata2(ptr);
     if (data == NULL) {
 	cptr = CFStringGetCStringPtr((CFStringRef)ptr, 0);
-    	if (cptr == NULL && CFStringGetLength((CFStringRef)ptr) > 0)
-	    data = (CFDataRef)rb_str_cfdata(ptr);
+    	if (cptr == NULL) {
+	    long len;
+	    len = CFStringGetLength((CFStringRef)ptr);
+	    if (len == 0)
+		return "";
+	    else 
+		data = (CFDataRef)rb_str_cfdata(ptr);
+	}
     }
     return data == NULL ? cptr : (const char *)CFDataGetBytePtr(data);
 }
@@ -1639,25 +1535,26 @@
 {
 #if WITH_OBJC
     long n = CFStringGetLength((CFStringRef)str);
-    CFStringRef substr, msubstr;
+    CFMutableStringRef substr;
     if (beg < 0)
 	beg += n;
     if (beg > n || beg < 0)
 	return Qnil;
     if (beg + len > n)
 	return (VALUE)CFSTR("");
+    substr = CFStringCreateMutable(NULL, 0);
     if (len == 1) {
 	UniChar c = CFStringGetCharacterAtIndex((CFStringRef)str, beg);
-	substr = CFStringCreateWithCharacters(NULL, &c, 1);
+	CFStringAppendCharacters(substr, &c, 1);
     }
     else {
-	substr = CFStringCreateWithSubstring(NULL, (CFStringRef)str, 
-	    CFRangeMake(beg, len));
+	UniChar *buffer = alloca(sizeof(UniChar) * len);
+	CFStringGetCharacters((CFStringRef)str, CFRangeMake(beg, len), buffer);
+	CFStringAppendCharacters(substr, buffer, len);
     }
-    msubstr = (CFStringRef)CFStringCreateMutableCopy(NULL, 0, substr);
-    CFRelease(substr);
-    CFMakeCollectable(msubstr);
-    return (VALUE)msubstr;
+    rb_gc_malloc_increase(sizeof(UniChar) * len);
+    CFMakeCollectable(substr);
+    return (VALUE)substr;
 #else
     VALUE str2 = rb_str_new5(str, RSTRING_PTR(str)+beg, len);
 
@@ -1824,13 +1721,13 @@
 #if WITH_OBJC
     slen = CFStringGetLength((CFStringRef)str);
     if (slen != len) {
-	struct rb_objc_str_struct *s;
+	void *cfdata;
 
 	CFStringPad((CFMutableStringRef)str, CFSTR(" "), len, 0);
 
-	s = rb_objc_str_get_struct(str);
-	if (s != NULL && s->cfdata != NULL)
-	    CFDataSetLength((CFMutableDataRef)s->cfdata, len); 
+	cfdata = rb_str_cfdata2(str);
+	if (cfdata != NULL)
+	    CFDataSetLength((CFMutableDataRef)cfdata, len); 
     }
 #else
     slen = RSTRING_LEN(str);
@@ -2139,8 +2036,11 @@
 #if WITH_OBJC
     CFMutableDataRef mdata;
     CFDataRef data;
+    long str2len;
 
-    if (RSTRING_CLEN(str2) == 0)
+    str2len = RSTRING_CLEN(str2);
+
+    if (str2len == 0)
 	return str;
 
     data = (CFDataRef)rb_str_cfdata2(str2);
@@ -2160,6 +2060,7 @@
 		CFDataGetLength(data));
 	}
     }
+    rb_gc_malloc_increase(sizeof(UniChar) * str2len);
 #else
     int str2_cr;
 
@@ -2230,6 +2131,7 @@
 	rb_str_modify(str1);
         CFStringAppendCharacters((CFMutableStringRef)str1, (const UniChar *)&c, 
 	    1);
+	rb_gc_malloc_increase(sizeof(UniChar));
 #else
 	rb_encoding *enc = STR_ENC_GET(str1);
 	int c = FIX2INT(str2);
@@ -4005,7 +3907,7 @@
 	CFStringReplaceAll((CFMutableStringRef)str, (CFStringRef)dest);
     }
     else {
-    	if (!tainted && rb_str_tainted(str) == Qtrue)
+    	if (!tainted && OBJ_TAINTED(str))
 	    tainted = 1;
 	str = dest;
     }
@@ -4021,7 +3923,7 @@
     }
 #endif
 
-    if (tainted) rb_str_taint(str);
+    if (tainted) OBJ_TAINT(str);
     return str;
 }
 
@@ -4101,8 +4003,8 @@
 #if WITH_OBJC
     rb_str_modify(str);
     CFStringReplaceAll((CFMutableStringRef)str, (CFStringRef)str2);
-    if (rb_str_tainted(str2) == Qtrue)
-	rb_str_taint(str);
+    if (OBJ_TAINTED(str2))
+	OBJ_TAINT(str);
 #else
     StringValue(str2);
     len = RSTRING_LEN(str2);
@@ -4875,6 +4777,7 @@
 	return Qnil;
     tmp = CFStringCreateWithCharacters(NULL, buffer, n);
     CFStringReplaceAll((CFMutableStringRef)str, tmp);
+    CFRelease(tmp);
     return str;
 #else
     rb_encoding *enc;
@@ -6138,6 +6041,7 @@
 #else
     enc = STR_ENC_GET(str);
 #endif
+    result = rb_ary_new();
     if (NIL_P(spat)) {
 	if (!NIL_P(rb_fs)) {
 	    spat = rb_fs;
@@ -6148,22 +6052,22 @@
     else {
       fs_set:
 	if (TYPE(spat) == T_STRING) {
+	    const char *spat_cstr;
+	    long spat_clen;
 #if WITH_OBJC
 	    rb_encoding *enc2 = rb_ascii8bit_encoding();
 #else
 	    rb_encoding *enc2 = STR_ENC_GET(spat);
 #endif
-	    const char *spat_cstr;
-	    long spat_clen;
 
 	    spat_cstr = RSTRING_CPTR(spat);
 	    spat_clen = RSTRING_CLEN(spat);
 
 	    if (rb_enc_mbminlen(enc2) == 1) {
 		if (spat_clen == 1 && spat_cstr[0] == ' '){
-		awk_split = Qtrue;
+		    awk_split = Qtrue;
+		}
 	    }
-	    }
 	    else {
 		int l;
 		if (rb_enc_ascget(spat_cstr, spat_cstr+spat_clen, &l, enc2) == ' ' &&
@@ -6172,7 +6076,39 @@
 		}
 	    }
 	    if (!awk_split) {
+#if WITH_OBJC
+		CFRange search_range;
+		search_range = CFRangeMake(0, clen);
+		do {
+		    CFRange result_range;
+		    CFRange substr_range;
+		    if (!CFStringFindWithOptions((CFStringRef)str, 
+			(CFStringRef)spat,
+			search_range,
+			0,
+			&result_range))
+			break;
+
+		    substr_range.location = search_range.location;
+		    substr_range.length = result_range.location 
+			- search_range.location;
+
+		    rb_ary_push(result,
+			rb_str_subseq(str, substr_range.location,
+			    substr_range.length));
+
+		    search_range.location = result_range.location 
+			+ result_range.length;
+		    search_range.length = clen - search_range.location;
+		}
+		while ((limit == Qnil || --lim > 1));
+		rb_ary_push(result, 
+		    rb_str_subseq(str, search_range.location, 
+			search_range.length));
+		goto done;
+#else
 		spat = rb_reg_regcomp(rb_reg_quote(spat));
+#endif
 	    }
 	}
 	else {
@@ -6180,7 +6116,6 @@
 	}
     }
 
-    result = rb_ary_new();
     beg = 0;
     if (awk_split) {
 	const char *ptr = cstr;
@@ -6269,6 +6204,7 @@
 	    tmp = rb_str_subseq(str, beg, clen-beg);
 	rb_ary_push(result, tmp);
     }
+done:
     if (NIL_P(limit) && lim == 0) {
 	while (RARRAY_LEN(result) > 0 &&
 	       RSTRING_CLEN(RARRAY_AT(result, RARRAY_LEN(result)-1)) == 0)
@@ -6288,6 +6224,13 @@
     return rb_str_split_m(1, &sep, str);
 }
 
+VALUE
+rb_str_split2(VALUE str, VALUE sep)
+{
+    StringValue(str);
+    StringValue(sep);
+    return rb_str_split_m(1, &sep, str);
+}
 
 /*
  *  Document-method: lines
@@ -7104,9 +7047,12 @@
 	    CFRangeMake(*start, strlen - *start),
 	    0,
 	    &result_range)) {
-	    result = (VALUE)CFStringCreateWithSubstring(NULL, 
+	    CFStringRef str = CFStringCreateWithSubstring(NULL, 
 		(CFStringRef)str, result_range);
 	    *start = result_range.location + result_range.length + 1;
+	    result = (VALUE)CFStringCreateMutableCopy(NULL, 0, str);
+	    CFRelease(str);
+	    CFMakeCollectable((CFTypeRef)result);
 	}
 	else {
 	    result = Qnil;
@@ -7431,6 +7377,7 @@
 		    NULL,
 		    (CFStringRef)pad,
 		    CFRangeMake(0, width));
+	    CFMakeCollectable((CFTypeRef)pad);
 	}
 	CFStringInsert((CFMutableStringRef)str, index, (CFStringRef)pad);
 	width -= padwidth;	
@@ -8291,10 +8238,6 @@
         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, "taint", rb_str_taint, 0);
-    rb_define_method(rb_cString, "tainted?", rb_str_tainted, 0);
-    rb_define_method(rb_cString, "freeze", rb_str_freeze, 0);
-    rb_define_method(rb_cString, "frozen?", rb_str_frozen, 0);
     rb_define_method(rb_cString, "__bytestring__?", rb_str_bytestring_m, 0);
 #else
     rb_cString  = rb_define_class("String", rb_cObject);

Modified: MacRuby/trunk/util.c
===================================================================
--- MacRuby/trunk/util.c	2008-05-06 23:07:11 UTC (rev 189)
+++ MacRuby/trunk/util.c	2008-05-11 00:16:55 UTC (rev 190)
@@ -279,13 +279,13 @@
     long slen;
     char buf[1024];
 
-    if (RSTRING_LEN(str) > 1000)
+    if (RSTRING_CLEN(str) > 1000)
         rb_fatal("Cannot do inplace edit on long filename (%ld characters)",
-		 RSTRING_LEN(str));
+		 RSTRING_CLEN(str));
 
 #if defined(DJGPP) || defined(__CYGWIN32__) || defined(_WIN32)
     /* Style 0 */
-    slen = RSTRING_LEN(str);
+    slen = RSTRING_CLEN(str);
     rb_str_cat(str, suffix, extlen);
 #if defined(DJGPP)
     if (_USE_LFN) return;

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080510/9cc94277/attachment-0001.html


More information about the macruby-changes mailing list