[macruby-changes] [5114] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Tue Jan 4 21:18:28 PST 2011


Revision: 5114
          http://trac.macosforge.org/projects/ruby/changeset/5114
Author:   lsansonetti at apple.com
Date:     2011-01-04 21:18:23 -0800 (Tue, 04 Jan 2011)
Log Message:
-----------
introduce a better unichar API, which should be as fast as before the recent string datastore change, also fixing the rubygems crasher and also various memory leaks

Modified Paths:
--------------
    MacRuby/trunk/encoding.h
    MacRuby/trunk/parse.y
    MacRuby/trunk/re.c
    MacRuby/trunk/re.h
    MacRuby/trunk/sprintf.c
    MacRuby/trunk/string.c
    MacRuby/trunk/symbol.c

Modified: MacRuby/trunk/encoding.h
===================================================================
--- MacRuby/trunk/encoding.h	2011-01-05 04:59:09 UTC (rev 5113)
+++ MacRuby/trunk/encoding.h	2011-01-05 05:18:23 UTC (rev 5114)
@@ -295,9 +295,46 @@
 // The following functions should always been prefered over anything else,
 // especially if this "else" is RSTRING_PTR and RSTRING_LEN.
 // They also work on CFStrings.
+
 VALUE rb_unicode_str_new(const UniChar *ptr, const size_t len);
-void rb_str_get_uchars(VALUE str, UChar **chars_p, long *chars_len_p,
-	bool *need_free_p);
+
+#define STR_UCHARS_STATIC_BUFSIZE 35
+
+typedef struct {
+    UChar static_buf[STR_UCHARS_STATIC_BUFSIZE];
+    UChar *chars;
+    long len;
+} rb_str_uchars_buf_t;
+
+void rb_str_get_uchars_always(VALUE str, rb_str_uchars_buf_t *buf);
+
+static inline void
+rb_str_get_uchars(VALUE str, rb_str_uchars_buf_t *buf)
+{
+    if (IS_RSTR(str)) {
+	rb_str_t *rstr = RSTR(str);
+	if (rstr->encoding->ascii_compatible && str_is_ascii_only(rstr)
+		&& rstr->length_in_bytes < STR_UCHARS_STATIC_BUFSIZE) {
+	    // Fast path.
+	    for (long i = 0; i < rstr->length_in_bytes; i++) {
+		buf->static_buf[i] = rstr->bytes[i];
+	    }
+	    buf->chars = buf->static_buf;
+	    buf->len = rstr->length_in_bytes;
+	    return;
+	}
+    }
+    rb_str_get_uchars_always(str, buf);
+}
+
+UChar *rb_str_xcopy_uchars(VALUE str, long *len_p);
+
+#define RB_STR_GET_UCHARS(str, _chars, _len) \
+    rb_str_uchars_buf_t __buf; \
+    rb_str_get_uchars(str, &__buf); \
+    UChar *_chars = __buf.chars; \
+    long _len = __buf.len
+
 long rb_str_chars_len(VALUE str);
 UChar rb_str_get_uchar(VALUE str, long pos);
 void rb_str_append_uchar(VALUE str, UChar c);

Modified: MacRuby/trunk/parse.y
===================================================================
--- MacRuby/trunk/parse.y	2011-01-05 04:59:09 UTC (rev 5113)
+++ MacRuby/trunk/parse.y	2011-01-05 05:18:23 UTC (rev 5114)
@@ -5094,15 +5094,13 @@
     struct parser_params *parser;
     Data_Get_Struct(vparser, struct parser_params, parser);
 
-    UChar *chars = NULL;
     long chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(s, &chars, &chars_len, &need_free);
+    UChar *chars = rb_str_xcopy_uchars(s, &chars_len); 
 
     struct lex_get_str_context *ctx = (struct lex_get_str_context *)
 	xmalloc(sizeof(struct lex_get_str_context));
     GC_WB(&ctx->str, s);
-    ctx->chars = chars;
+    GC_WB(&ctx->chars, chars);
     ctx->chars_len = chars_len;
 
     lex_gets = lex_get_str;
@@ -5111,14 +5109,7 @@
     lex_pbeg = lex_p = lex_pend = 0;
     compile_for_eval = rb_parse_in_eval();
 
-    NODE *node = yycompile(parser, f, line);
-
-    if (need_free && chars != NULL) {
-	orig_free(chars);
-	chars = NULL;
-    }
-
-    return node;
+    return yycompile(parser, f, line);
 }
 
 NODE*
@@ -9901,27 +9892,13 @@
     Data_Get_Struct(self, struct parser_params, parser);
     rb_scan_args(argc, argv, "12", &src, &fname, &lineno);
 
-    UChar *chars = NULL;
     long chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(src, &chars, &chars_len, &need_free);
+    UChar *chars = rb_str_xcopy_uchars(src, &chars_len);
 
-    if (need_free) {
-	UChar *tmp = (UChar *)xmalloc(sizeof(UChar) * chars_len);
-	memcpy(tmp, chars, sizeof(UChar) * chars_len);
-	orig_free(chars);
-	chars = tmp;
-    }
-
     struct lex_get_str_context *ctx = (struct lex_get_str_context *)
 	xmalloc(sizeof(struct lex_get_str_context));
     GC_WB(&ctx->str, src);
-    if (need_free) {
-	GC_WB(&ctx->chars, chars);
-    }
-    else {
-	ctx->chars = chars;
-    }
+    GC_WB(&ctx->chars, chars);
     ctx->chars_len = chars_len;
 
     parser->parser_lex_gets = lex_get_str;

Modified: MacRuby/trunk/re.c
===================================================================
--- MacRuby/trunk/re.c	2011-01-05 04:59:09 UTC (rev 5113)
+++ MacRuby/trunk/re.c	2011-01-05 05:18:23 UTC (rev 5114)
@@ -91,20 +91,16 @@
 
 // Work around ICU limitations.
 static void
-sanitize_regexp_string(UChar **chars_p, long *chars_len_p, bool *need_free_p)
+sanitize_regexp_string(UChar **chars_p, long *chars_len_p)
 {
     UChar *chars = *chars_p;
     long chars_len = *chars_len_p;
-    bool need_free = *need_free_p;
 
 #define copy_if_needed() \
     do { \
-	if (!need_free) { \
-	    UChar *tmp = (UChar *)malloc(sizeof(UChar) * chars_len); \
-	    memcpy(tmp, chars, sizeof(UChar) * chars_len); \
-	    chars = tmp; \
-	    need_free = true; \
-	} \
+	UChar *tmp = (UChar *)xmalloc(sizeof(UChar) * chars_len); \
+	memcpy(tmp, chars, sizeof(UChar) * chars_len); \
+	chars = tmp; \
     } \
     while (0)
 
@@ -183,7 +179,6 @@
 
     *chars_p = chars;
     *chars_len_p = chars_len;
-    *need_free_p = need_free;
 }
 
 static bool
@@ -191,10 +186,7 @@
 {
     option |= REGEXP_OPT_DEFAULT;
 
-    UChar *chars = NULL;
-    long chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(str, &chars, &chars_len, &need_free);
+    RB_STR_GET_UCHARS(str, chars, chars_len);
 
     UChar null_char = '\0';
     if (chars_len == 0) {
@@ -203,10 +195,9 @@
 	// of -1 which indicates it's terminated by \0.
 	chars = &null_char;
 	chars_len = -1;
-	need_free = false;
     }
     else {
-	sanitize_regexp_string(&chars, &chars_len, &need_free);
+	sanitize_regexp_string(&chars, &chars_len);
     }
 
     UParseError pe;
@@ -214,10 +205,6 @@
     URegularExpression *pattern = uregex_open(chars, chars_len, option,
 	    &pe, &status);
 
-    if (need_free) {
-	free(chars);
-    }
-
     if (pattern == NULL) {
 	if (excp != NULL) {
 	    char error[1024];
@@ -669,7 +656,7 @@
 typedef struct rb_regexp_matcher {
     struct RBasic basic;
     URegularExpression *pattern;
-    UChar *text_to_free;
+    UChar *text_chars;
     rb_encoding_t *encoding;
     VALUE frozen_str;
 } rb_regexp_matcher_t;
@@ -681,10 +668,6 @@
 	uregex_close(m->pattern);
 	m->pattern = NULL;
     }
-    if (m->text_to_free != NULL) {
-	free(m->text_to_free);
-	m->text_to_free = NULL;
-    }
 }
 
 static IMP regexp_matcher_finalize_imp_super = NULL; 
@@ -697,6 +680,7 @@
 	((void(*)(void *, SEL))regexp_matcher_finalize_imp_super)(rcv, sel);
     }
 }
+
 VALUE
 rb_reg_matcher_new(VALUE re, VALUE str)
 {
@@ -712,28 +696,22 @@
 		u_errorName(status));
     }
 
-    UChar *chars = NULL;
     long chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(str, &chars, &chars_len, &need_free);
+    UChar *chars = rb_str_xcopy_uchars(str, &chars_len);
 
-    UChar null_char = '\0';
     if (chars_len == 0) {
 	// uregex_setText() will complain if we pass a NULL pattern or a
 	// pattern length of 0, so we do pass an empty pattern with a length
 	// of -1 which indicates it's terminated by \0.
-	chars = &null_char;
+	chars = (UChar *)xmalloc(sizeof(UChar));
+	*chars = '\0';
 	chars_len = -1;
-	need_free = false;
     }
 
     uregex_setText(match_pattern, chars, chars_len, &status);
 
     if (status != U_ZERO_ERROR) {
 	uregex_close(match_pattern);
-	if (need_free) {
-	    free(chars);
-	}
 	rb_raise(rb_eRegexpError, "can't set pattern text: %s",
 		u_errorName(status));	
     }
@@ -744,7 +722,7 @@
 
     // Apparently uregex_setText doesn't copy the given string, so we need
     // to keep it around until we finally destroy the matcher object.
-    matcher->text_to_free = need_free ? chars : NULL;
+    GC_WB(&matcher->text_chars, chars);
 
     return (VALUE)matcher;
 }
@@ -756,7 +734,7 @@
     xfree((void *)matcher);
 }
 
-static int
+int
 rb_reg_matcher_search_find(VALUE re, VALUE matcher, int pos, bool reverse,
 	bool findFirst)
 {
@@ -857,18 +835,6 @@
     return res[0].beg;
 }
 
-int
-rb_reg_matcher_search_first(VALUE re, VALUE matcher, int pos, bool reverse)
-{
-    return rb_reg_matcher_search_find(re, matcher, pos, reverse, true);
-}
-
-int
-rb_reg_matcher_search_next(VALUE re, VALUE matcher, int pos, bool reverse)
-{
-    return rb_reg_matcher_search_find(re, matcher, pos, reverse, false);
-}
-
 static long
 reg_match_pos(VALUE re, VALUE *strp, long pos)
 {
@@ -975,7 +941,6 @@
 	rb_backref_set(Qnil);
 	return Qnil;
     }
-
     const long start = rb_reg_search(rcv, line, 0, 0);
     if (start < 0) {
 	return Qnil;
@@ -2124,12 +2089,9 @@
 VALUE
 rb_reg_quote(VALUE pat)
 {
-    UChar *chars = NULL;
-    long chars_len = 0;
-    bool need_free = false;
     VALUE result;
 
-    rb_str_get_uchars(pat, &chars, &chars_len, &need_free);
+    RB_STR_GET_UCHARS(pat, chars, chars_len);
 
     long pos = 0;
     for (; pos < chars_len; pos++) {
@@ -2197,9 +2159,6 @@
     }
 
 bail:
-    if (need_free) {
-	free(chars);
-    }
     return result;
 }
 

Modified: MacRuby/trunk/re.h
===================================================================
--- MacRuby/trunk/re.h	2011-01-05 04:59:09 UTC (rev 5113)
+++ MacRuby/trunk/re.h	2011-01-05 05:18:23 UTC (rev 5114)
@@ -24,12 +24,29 @@
 VALUE rb_regexp_source(VALUE re);
 
 VALUE rb_reg_matcher_new(VALUE re, VALUE str);
+int rb_reg_matcher_search_find(VALUE re, VALUE matcher, int pos, bool reverse,
+	bool findFirst);
 void rb_reg_matcher_destroy(VALUE matcher);
-int rb_reg_matcher_search_first(VALUE re, VALUE matcher, int pos, bool reverse);
-int rb_reg_matcher_search_next(VALUE re, VALUE matcher, int pos, bool reverse);
-#define rb_reg_matcher_search rb_reg_matcher_search_next
 
 static inline int
+rb_reg_matcher_search_first(VALUE re, VALUE matcher, int pos, bool reverse)
+{
+    return rb_reg_matcher_search_find(re, matcher, pos, reverse, true);
+}
+
+static inline int
+rb_reg_matcher_search_next(VALUE re, VALUE matcher, int pos, bool reverse)
+{
+    return rb_reg_matcher_search_find(re, matcher, pos, reverse, false);
+}
+
+static inline int
+rb_reg_matcher_search(VALUE re, VALUE matcher, int pos, bool reverse)
+{
+    return rb_reg_matcher_search_next(re, matcher, pos, reverse);
+}
+
+static inline int
 rb_reg_search(VALUE re, VALUE str, int pos, bool reverse)
 {
     VALUE matcher = rb_reg_matcher_new(re, str);

Modified: MacRuby/trunk/sprintf.c
===================================================================
--- MacRuby/trunk/sprintf.c	2011-01-05 04:59:09 UTC (rev 5113)
+++ MacRuby/trunk/sprintf.c	2011-01-05 05:18:23 UTC (rev 5114)
@@ -372,14 +372,9 @@
 		sizeof(UChar) * (len - start - num));
     }
     if (replace_len > 0) {
-	UChar *replace_chars = NULL;
-	bool need_free = false;
-	rb_str_get_uchars(replace, &replace_chars, &replace_len, &need_free);
-	assert(replace_len > 0);
+	RB_STR_GET_UCHARS(replace, replace_chars, replace_len2);
+	assert(replace_len2 == replace_len);
 	bcopy(replace_chars, *str + start, sizeof(UChar) * replace_len);
-	if (need_free) {
-	    free(replace_chars);
-	}
     }
     return replace_len - num;
 }
@@ -413,19 +408,11 @@
 {
     bool tainted = OBJ_TAINTED(fmt);
 
-    UChar *format_str = NULL;
     long format_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(fmt, &format_str, &format_len, &need_free);
+    UChar *format_str = rb_str_xcopy_uchars(fmt, &format_len);
     if (format_len == 0) {
 	goto bail;
     }
-    UChar *tmp = (UChar *)xmalloc(format_len * sizeof(UChar));
-    memcpy(tmp, format_str, format_len * sizeof(UChar));
-    if (need_free) {
-	free(format_str);
-    }
-    format_str = tmp;
 
     long num, pos;
     int j = 0;

Modified: MacRuby/trunk/string.c
===================================================================
--- MacRuby/trunk/string.c	2011-01-05 04:59:09 UTC (rev 5113)
+++ MacRuby/trunk/string.c	2011-01-05 05:18:23 UTC (rev 5114)
@@ -320,6 +320,9 @@
 	if (chars == NULL) {
 	    str_resize_bytes(self, len);
 	}
+	else if (self->bytes == (char *)chars) {
+	    self->length_in_bytes = UCHARS_TO_BYTES(len);
+	}
 	else {
 	    str_concat_uchars(self, chars, len);
 	}
@@ -1182,42 +1185,74 @@
 }
 
 void
-rb_str_get_uchars(VALUE str, UChar **chars_p, long *chars_len_p,
-	bool *need_free_p)
+rb_str_get_uchars_always(VALUE str, rb_str_uchars_buf_t *buf)
 {
-    assert(chars_p != NULL && chars_len_p != NULL && need_free_p != NULL);
+    long len = 0;
 
-    UChar *chars = NULL;
-    long chars_len = 0;
-    bool need_free = false;
+    buf->chars = NULL;
 
     if (IS_RSTR(str)) {
 	rb_str_t *rstr = RSTR(str);
 	if (rstr->length_in_bytes > 0) {
-	    chars_len = str_length(RSTR(str));
+	    len = str_length(rstr);
 	    if (IS_NATIVE_UTF16_ENC(rstr->encoding)) {
-		chars = (UChar *)rstr->bytes;
+		buf->chars = (UChar *)rstr->bytes;
 	    }
 	    else {
-		chars = (UChar *)malloc(sizeof(UChar) * chars_len);
-		str_extract_uchars_range(RSTR(str), 0, chars_len, chars);
-		need_free = true;
+		if (len > STR_UCHARS_STATIC_BUFSIZE) {
+		    buf->chars = (UChar *)malloc(sizeof(UChar) * len);
+		}
+		else {
+		    buf->chars = buf->static_buf;
+		}
+		str_extract_uchars_range(rstr, 0, len, buf->chars);
 	    }
 	}
     }
     else {
-	chars_len = CFStringGetLength((CFStringRef)str);
-	if (chars_len > 0) {
-	    chars = (UChar *)malloc(sizeof(UChar) * chars_len);
-	    CFStringGetCharacters((CFStringRef)str, CFRangeMake(0, chars_len),
+	len = CFStringGetLength((CFStringRef)str);
+	if (len > 0) {
+	    if (len > STR_UCHARS_STATIC_BUFSIZE) {
+		buf->chars = (UChar *)malloc(sizeof(UChar) * len);
+	    }
+	    else {
+		buf->chars = buf->static_buf;
+	    }
+	    CFStringGetCharacters((CFStringRef)str, CFRangeMake(0, len),
+		    buf->chars);
+	}
+    }
+
+    buf->len = len;
+}
+
+UChar *
+rb_str_xcopy_uchars(VALUE str, long *len_p)
+{
+    UChar *chars = NULL;
+    long len = 0;
+
+    if (IS_RSTR(str)) {
+	rb_str_t *rstr = RSTR(str);
+	len = str_length(rstr);
+	if (len > 0) {
+	    chars = (UChar *)xmalloc(sizeof(UChar) * len);
+	    str_extract_uchars_range(rstr, 0, len, chars);
+	}
+    }
+    else {
+	len = CFStringGetLength((CFStringRef)str);
+	if (len > 0) {
+	    chars = (UChar *)xmalloc(sizeof(UChar) * len);
+	    CFStringGetCharacters((CFStringRef)str, CFRangeMake(0, len),
 		    chars);
-	    need_free = true;
 	}
     }
 
-    *chars_p = chars;
-    *chars_len_p = chars_len;
-    *need_free_p = need_free;
+    if (len_p != NULL) {
+	*len_p = len;
+    }
+    return chars;
 }
 
 static VALUE
@@ -3080,12 +3115,8 @@
     const int lim_orig = lim;
     long beg = 0;
     if (awk_split) {
-	UChar *chars = NULL;
-	long chars_len = 0;
-	bool need_free = false;
+	RB_STR_GET_UCHARS(str, chars, chars_len);
 
-	rb_str_get_uchars(str, &chars, &chars_len, &need_free);
-
 	for (long i = 0; i < chars_len; i++) {
 	    UChar c = chars[i];
 	    if (c == ' ' || c == '\t' || c == '\n' || c == '\v') {
@@ -3101,10 +3132,6 @@
 		}
 	    }
 	}
-
-	if (need_free) {
-	    free(chars);
-	}
     }
     else if (spat_string) {
 	if (spat_len == 0) {
@@ -3534,13 +3561,8 @@
 {
     VALUE val = 0;
 
-    UChar *str_chars = NULL;
-    long str_chars_len = 0;
-    bool str_chars_need_free = false;
+    RB_STR_GET_UCHARS(str, str_chars, str_chars_len);
 
-    rb_str_get_uchars(str, &str_chars, &str_chars_len,
-	    &str_chars_need_free);
-
     long pos = 0;
     long src_chars_len = -1;
 
@@ -3622,10 +3644,6 @@
 	str_concat_uchars(RSTR(val), &str_chars[pos], str_chars_len - pos);
     }
 
-    if (str_chars_need_free) {
-	free(str_chars);
-    }
-
     if (val == 0) {
 	return str;
     }
@@ -4887,36 +4905,19 @@
 {
     StringValue(transform_pat);
 
-    UChar *new_chars = NULL;
     long new_chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(str, &new_chars, &new_chars_len, &need_free);
-
+    UChar *new_chars = rb_str_xcopy_uchars(str, &new_chars_len);
     if (new_chars_len == 0) {
 	return Qnil;
     }
 
-    if (!need_free) {
-	UChar *tmp = (UChar *)malloc(sizeof(UChar) * new_chars_len);
-	memcpy(tmp, new_chars, sizeof(UChar) * new_chars_len);
-	new_chars = tmp;
-    }
+    RB_STR_GET_UCHARS(str, transform_chars, transform_chars_len);
 
-    UChar *transform_chars = NULL;
-    long transform_chars_len = 0;
-    need_free = false;
-    rb_str_get_uchars(transform_pat, &transform_chars, &transform_chars_len,
-	    &need_free);
-
     UErrorCode status = U_ZERO_ERROR;
     UTransliterator *trans = utrans_openU(transform_chars, transform_chars_len,
 	    UTRANS_FORWARD, NULL, 0, NULL, &status);
 
     if (trans == NULL) {
-	if (need_free) {
-	    free(transform_chars);
-	}
-	free(new_chars);
 	rb_raise(rb_eArgError, "cannot create transliterator");
     }
 
@@ -4925,16 +4926,7 @@
     utrans_transUChars(trans, new_chars, &capacity, capacity,
 	    0, &limit, &status);
 
-    new_chars_len = (long)capacity;
-
-    VALUE newstr = rb_unicode_str_new(new_chars, new_chars_len);
-
-    if (need_free) {
-	free(transform_chars);
-    }
-    free(new_chars);
-
-    return newstr;
+    return rb_unicode_str_new(new_chars, (long)capacity);
 }
 
 /*
@@ -5010,10 +5002,7 @@
 {
     StringValue(source);
 
-    UChar *chars = NULL;
-    long chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(source, &chars, &chars_len, &need_free);
+    RB_STR_GET_UCHARS(source, chars, chars_len);
 
     long pos = 0;
     if (negatep != NULL) {
@@ -5067,10 +5056,6 @@
     *lenp = bufpos;
 
 bail:
-    if (need_free) {
-	free(chars);
-    }
-
     if (error) {
 	rb_raise(rb_eArgError, "invalid string transliteration");
     }
@@ -5187,10 +5172,7 @@
 {
     INTERSECT_CHARSET_TABLE_CREATE();
 
-    UChar *chars = NULL;
-    long chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(str, &chars, &chars_len, &need_free);
+    RB_STR_GET_UCHARS(str, chars, chars_len);
 
     long count = 0;
     for (long i = 0; i < chars_len; i++) {
@@ -5198,11 +5180,6 @@
 	    count++;
 	}
     }
-
-    if (need_free) {
-	free(chars);
-    }
-
     return LONG2NUM(count); 
 }
 
@@ -5221,10 +5198,7 @@
 
     INTERSECT_CHARSET_TABLE_CREATE();
 
-    UChar *chars = NULL;
-    long chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(str, &chars, &chars_len, &need_free);
+    RB_STR_GET_UCHARS(str, chars, chars_len);
 
     bool modified = false;
     for (long i = 0; i < chars_len; i++) {
@@ -5238,20 +5212,10 @@
     }
 
     if (!modified) {
-	if (need_free) {
-	    free(chars);
-	}
 	return Qnil;
     }
 
-    if (need_free) {
-	str_replace_with_uchars(RSTR(str), chars, chars_len);
-	free(chars);
-    }
-    else {
-	RSTR(str)->length_in_bytes = UCHARS_TO_BYTES(chars_len);
-    }
-
+    str_replace_with_uchars(RSTR(str), chars, chars_len);
     return str;
 }
 
@@ -5301,10 +5265,7 @@
 
     INTERSECT_CHARSET_TABLE_CREATE();
 
-    UChar *chars = NULL;
-    long chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(str, &chars, &chars_len, &need_free);
+    RB_STR_GET_UCHARS(str, chars, chars_len);
 
     bool modified = false;
     for (long i = 0; i < chars_len; i++) {
@@ -5321,20 +5282,10 @@
     }
 
     if (!modified) {
-	if (need_free) {
-	    free(chars);
-	}
 	return Qnil;
     }
 
-    if (need_free) {
-	str_replace_with_uchars(RSTR(str), chars, chars_len);
-	free(chars);
-    }
-    else {
-	RSTR(str)->length_in_bytes = UCHARS_TO_BYTES(chars_len);
-    }
-
+    str_replace_with_uchars(RSTR(str), chars, chars_len);
     return str;
 }
 
@@ -5385,10 +5336,7 @@
     char tbl[0xff]; 
     create_translate_charset_table(tbl, source, repl);
 
-    UChar *chars = NULL;
-    long chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(str, &chars, &chars_len, &need_free);
+    RB_STR_GET_UCHARS(str, chars, chars_len);
 
     bool modified = false;
     for (long i = 0; i < chars_len; i++) {
@@ -5406,20 +5354,10 @@
     } 
 
     if (!modified) {
-	if (need_free) {
-	    free(chars);
-	}
 	return Qnil;
     }
 
-    if (need_free) {
-	str_replace_with_uchars(RSTR(str), chars, chars_len);
-	free(chars);
-    }
-//    else {
-//	RSTR(str)->length_in_bytes = UCHARS_TO_BYTES(chars_len);
-//    }
-
+    str_replace_with_uchars(RSTR(str), chars, chars_len);
     return str;
 }
 
@@ -6462,15 +6400,8 @@
 unsigned long
 rb_str_hash(VALUE str)
 {
-    UChar *chars = NULL;
-    long chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(str, &chars, &chars_len, &need_free);
-    const unsigned long hash = rb_str_hash_uchars(chars, chars_len);
-    if (need_free) {
-	free(chars);
-    }
-    return hash;
+    RB_STR_GET_UCHARS(str, chars, chars_len);
+    return rb_str_hash_uchars(chars, chars_len);
 }
 
 long

Modified: MacRuby/trunk/symbol.c
===================================================================
--- MacRuby/trunk/symbol.c	2011-01-05 04:59:09 UTC (rev 5113)
+++ MacRuby/trunk/symbol.c	2011-01-05 05:18:23 UTC (rev 5114)
@@ -49,10 +49,7 @@
 ID
 rb_intern_str(VALUE str)
 {
-    UChar *chars = NULL;
-    long chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(str, &chars, &chars_len, &need_free);
+    RB_STR_GET_UCHARS(str, chars, chars_len);
 
     const unsigned long name_hash = rb_str_hash_uchars(chars, chars_len);
     ID id = (ID)CFDictionaryGetValue(sym_id, (const void *)name_hash); 
@@ -121,9 +118,6 @@
     CFDictionarySetValue(id_str, (const void *)id, (const void *)sym);
 
 return_id:
-    if (need_free) {
-	free(chars);
-    }
     return id;
 }
 
@@ -395,10 +389,7 @@
 static bool
 sym_should_be_escaped(VALUE sym)
 {
-    UChar *chars = NULL;
-    long chars_len = 0;
-    bool need_free = false;
-    rb_str_get_uchars(RSYM(sym)->str, &chars, &chars_len, &need_free);
+    RB_STR_GET_UCHARS(RSYM(sym)->str, chars, chars_len);
 
     if (chars_len == 0) {
 	return true;
@@ -563,10 +554,6 @@
     }
 
 bail:
-    if (need_free) {
-	free(chars);
-    }
-
     return escape;
 }
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20110104/7633489e/attachment-0001.html>


More information about the macruby-changes mailing list