Revision: 190 http://trac.macosforge.org/projects/ruby/changeset/190 Author: lsansonetti@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;
participants (1)
-
source_changes@macosforge.org