[macruby-changes] [210] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Thu May 22 18:13:25 PDT 2008


Revision: 210
          http://trac.macosforge.org/projects/ruby/changeset/210
Author:   lsansonetti at apple.com
Date:     2008-05-22 18:13:24 -0700 (Thu, 22 May 2008)

Log Message:
-----------
fixing more regressions, performance tuning

Modified Paths:
--------------
    MacRuby/trunk/array.c
    MacRuby/trunk/ext/strscan/strscan.c
    MacRuby/trunk/file.c
    MacRuby/trunk/hash.c
    MacRuby/trunk/include/ruby/ruby.h
    MacRuby/trunk/objc.m
    MacRuby/trunk/string.c
    MacRuby/trunk/test/ruby/test_objc.rb

Modified: MacRuby/trunk/array.c
===================================================================
--- MacRuby/trunk/array.c	2008-05-22 06:33:11 UTC (rev 209)
+++ MacRuby/trunk/array.c	2008-05-23 01:13:24 UTC (rev 210)
@@ -17,6 +17,7 @@
 
 VALUE rb_cArray;
 #if WITH_OBJC
+VALUE rb_cCFArray;
 VALUE rb_cArrayRuby;
 #endif
 
@@ -86,14 +87,30 @@
 
 VALUE rb_ary_frozen_p(VALUE ary);
 
+#if WITH_OBJC
+
 static inline void
 rb_ary_modify_check(VALUE ary)
 {
-#if WITH_OBJC
-    bool _CFArrayIsMutable(void *);
-    if (!_CFArrayIsMutable((void *)ary))
-	rb_raise(rb_eRuntimeError, "can't modify immutable array");
-#endif
+    long mask;
+    mask = rb_objc_flag_get_mask(ary);
+    if (mask == 0) {
+	bool _CFArrayIsMutable(void *);
+	if (!_CFArrayIsMutable((void *)ary))
+	    mask |= FL_FREEZE;
+    }
+    if ((mask & FL_FREEZE) == FL_FREEZE)
+	rb_raise(rb_eRuntimeError, "can't modify frozen/immutable array");
+    if ((mask & FL_TAINT) == FL_TAINT && rb_safe_level() >= 4)
+	rb_raise(rb_eSecurityError, "Insecure: can't modify array");
+}
+#define rb_ary_modify rb_ary_modify_check
+
+#else
+
+static inline void
+rb_ary_modify_check(VALUE ary)
+{
     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");
@@ -105,7 +122,6 @@
     VALUE *ptr;
 
     rb_ary_modify_check(ary);
-#if !WITH_OBJC
     if (ARY_SHARED_P(ary)) {
 	ptr = ALLOC_N(VALUE, RARRAY_LEN(ary));
 	FL_UNSET(ary, ELTS_SHARED);
@@ -113,8 +129,8 @@
 	MEMCPY(ptr, RARRAY_PTR(ary), VALUE, RARRAY_LEN(ary));
 	RARRAY(ary)->ptr = ptr;
     }
+}
 #endif
-}
 
 VALUE
 rb_ary_freeze(VALUE ary)
@@ -632,7 +648,12 @@
 VALUE
 rb_ary_push(VALUE ary, VALUE item)
 {
+#if WITH_OBJC
+    rb_ary_modify(ary);
+    CFArrayAppendValue((CFMutableArrayRef)ary, (const void *)item);
+#else
     rb_ary_store(ary, RARRAY_LEN(ary), item);
+#endif
     return ary;
 }
 
@@ -3934,12 +3955,8 @@
 }
 
 #if WITH_OBJC
-static Class __nscfarray = NULL;
 
-#define NSCFARRAY() \
-    (__nscfarray == NULL \
-	? __nscfarray = (Class)objc_getClass("NSCFArray") \
-	: __nscfarray)
+#define NSCFARRAY() RCLASS_OCID(rb_cCFArray)
 
 #define PREPARE_RCV(x) \
     Class old = *(Class *)x; \
@@ -4079,6 +4096,7 @@
 Init_Array(void)
 {
 #if WITH_OBJC
+    rb_cCFArray = rb_objc_import_class((Class)objc_getClass("NSCFArray"));;
     rb_cArray = rb_objc_import_class((Class)objc_getClass("NSArray"));
     rb_cArrayRuby = 
 	rb_objc_import_class((Class)objc_getClass("NSMutableArray"));

Modified: MacRuby/trunk/ext/strscan/strscan.c
===================================================================
--- MacRuby/trunk/ext/strscan/strscan.c	2008-05-22 06:33:11 UTC (rev 209)
+++ MacRuby/trunk/ext/strscan/strscan.c	2008-05-23 01:13:24 UTC (rev 210)
@@ -130,7 +130,9 @@
 str_new(struct strscanner *p, const char *ptr, long len)
 {
     VALUE str = rb_str_new(ptr, len);
+#if !WITH_OBJC
     rb_enc_copy(str, p->str);
+#endif
     return str;
 }
 

Modified: MacRuby/trunk/file.c
===================================================================
--- MacRuby/trunk/file.c	2008-05-22 06:33:11 UTC (rev 209)
+++ MacRuby/trunk/file.c	2008-05-23 01:13:24 UTC (rev 210)
@@ -3209,16 +3209,28 @@
 {
 #if WITH_OBJC
     VALUE mstr;
-    if (RARRAY_LEN(ary) == 0) {
-	mstr = rb_str_new(0, 0);
+    long count;
+
+    mstr = rb_str_new(0, 0);
+    count = RARRAY_LEN(ary);
+    if (count > 0) {
+	long i;
+	for (i = 0; i < count; i++) {
+	    VALUE tmp = RARRAY_AT(ary, i);
+	    switch (TYPE(tmp)) {
+		case T_STRING:
+		    break;
+		case T_ARRAY:
+		    tmp = rb_file_join(tmp, sep);
+		    break;
+		default:
+		    FilePathStringValue(tmp);
+	    }
+	    if (i > 0)
+		rb_str_buf_append(mstr, sep);
+	    rb_str_buf_append(mstr, tmp);
+	}
     }
-    else {
-	VALUE str;
-	str = (VALUE)CFStringCreateByCombiningStrings(NULL, (CFArrayRef)ary,
-		(CFStringRef)sep);
-	mstr = rb_str_dup(str);
-	CFRelease((CFTypeRef)str);
-    }
     return mstr;
 #else
     long len, i, count;

Modified: MacRuby/trunk/hash.c
===================================================================
--- MacRuby/trunk/hash.c	2008-05-22 06:33:11 UTC (rev 209)
+++ MacRuby/trunk/hash.c	2008-05-23 01:13:24 UTC (rev 210)
@@ -33,6 +33,7 @@
 
 VALUE rb_cHash;
 #if WITH_OBJC
+VALUE rb_cCFHash;
 VALUE rb_cHashRuby;
 #endif
 
@@ -253,7 +254,7 @@
 static Boolean 
 rb_cfdictionary_equal_cb(const void *v1, const void *v2)
 {
-    return !rb_any_cmp((VALUE)v1, (VALUE)v2);
+    return v1 == v2 || !rb_any_cmp((VALUE)v1, (VALUE)v2);
 }
 
 static CFHashCode
@@ -364,14 +365,31 @@
 #endif
 }
 
+#if WITH_OBJC
+
+static inline void
+rb_hash_modify_check(VALUE hash)
+{
+    long mask;
+    mask = rb_objc_flag_get_mask(hash);
+    if (mask == 0) {
+	bool _CFDictionaryIsMutable(void *);
+	if (!_CFDictionaryIsMutable((void *)hash))
+	    mask |= FL_FREEZE;
+    }
+    if ((mask & FL_FREEZE) == FL_FREEZE)
+	rb_raise(rb_eRuntimeError, "can't modify frozen/immutable hash");
+    if ((mask & FL_TAINT) == FL_TAINT && rb_safe_level() >= 4)
+	rb_raise(rb_eSecurityError, "Insecure: can't modify hash");
+}
+
+#define rb_hash_modify rb_hash_modify_check
+
+#else
+
 static void
 rb_hash_modify_check(VALUE hash)
 {
-#if WITH_OBJC
-    bool _CFDictionaryIsMutable(void *);
-    if (!_CFDictionaryIsMutable((void *)hash)) 
-	rb_raise(rb_eRuntimeError, "can't modify immutable hash");
-#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");
@@ -380,25 +398,21 @@
 struct st_table *
 rb_hash_tbl(VALUE hash)
 {
-#if WITH_OBJC
-    rb_notimplement();
-#else
     if (!RHASH(hash)->ntbl) {
 	GC_WB(&RHASH(hash)->ntbl, st_init_table(&objhash));
     }
     return RHASH(hash)->ntbl;
-#endif
 }
 
 static void
 rb_hash_modify(VALUE hash)
 {
     rb_hash_modify_check(hash);
-#if !WITH_OBJC
     rb_hash_tbl(hash);
+}
 #endif
-}
 
+
 /*
  *  call-seq:
  *     Hash.new                          => hash
@@ -2902,16 +2916,12 @@
  */
 
 #if WITH_OBJC
-static Class __nscfdictionary = NULL;
 
-#define NSCFDICTIONARY() \
-    (__nscfdictionary == NULL \
-	? __nscfdictionary = (Class)objc_getClass("NSCFDictionary") \
- 	: __nscfdictionary)
+#define NSCFDICTIONARY() RCLASS_OCID(rb_cCFHash)
 
 #define PREPARE_RCV(x) \
     Class old = *(Class *)x; \
-    *(Class *)x = __nscfdictionary;
+    *(Class *)x = NSCFDICTIONARY();
 
 #define RESTORE_RCV(x) \
     *(Class *)x = old;
@@ -3047,6 +3057,7 @@
     id_default = rb_intern("default");
 
 #if WITH_OBJC
+    rb_cCFHash = rb_objc_import_class((Class)objc_getClass("NSCFDictionary"));
     rb_cHash = rb_objc_import_class((Class)objc_getClass("NSDictionary"));
     rb_cHashRuby = rb_objc_import_class((Class)objc_getClass("NSMutableDictionary"));
     FL_UNSET(rb_cHashRuby, RCLASS_OBJC_IMPORTED);

Modified: MacRuby/trunk/include/ruby/ruby.h
===================================================================
--- MacRuby/trunk/include/ruby/ruby.h	2008-05-22 06:33:11 UTC (rev 209)
+++ MacRuby/trunk/include/ruby/ruby.h	2008-05-23 01:13:24 UTC (rev 210)
@@ -571,7 +571,7 @@
  */
 const VALUE *rb_ary_ptr(VALUE);
 # define RARRAY_PTR(a) (rb_ary_ptr((VALUE)a)) 
-# define RARRAY_AT(a,i) (rb_ary_elt((VALUE)a, (int)i))
+# define RARRAY_AT(a,i) ((VALUE)CFArrayGetValueAtIndex((CFArrayRef)a, (long)i))
 #endif
 
 struct RRegexp {
@@ -1042,6 +1042,15 @@
 	if (obj == Qfalse) return rb_cFalseClass;
     }
 #if WITH_OBJC
+    extern VALUE rb_cCFString;
+    extern VALUE rb_cCFArray;
+    extern VALUE rb_cCFHash;
+    if (rb_cCFString != 0 && *(Class *)obj == RCLASS_OCID(rb_cCFString))
+	return rb_cCFString;
+    if (rb_cCFArray != 0 && *(Class *)obj == RCLASS_OCID(rb_cCFArray))
+	return rb_cCFArray;
+    if (rb_cCFHash != 0 && *(Class *)obj == RCLASS_OCID(rb_cCFHash))
+	return rb_cCFHash;
     VALUE rb_objc_import_class(Class);
     if (rb_objc_is_non_native(obj))
 	return rb_objc_import_class(RBASIC(obj)->isa);
@@ -1066,8 +1075,7 @@
     /* FIXME this is super slow */
     else if (rb_cHash != 0 
 	     && rb_cArray != 0
-	     && rb_cString != 0
-	     && !class_isMetaClass(*(Class *)obj)) {
+	     && rb_cString != 0) {
 	Class k = *(Class *)obj;
 	while (k != NULL) {
 	    if (k == RCLASS_OCID(rb_cHash))

Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m	2008-05-22 06:33:11 UTC (rev 209)
+++ MacRuby/trunk/objc.m	2008-05-23 01:13:24 UTC (rev 210)
@@ -2553,15 +2553,21 @@
 
 static CFMutableDictionaryRef __obj_flags;
 
+long
+rb_objc_flag_get_mask(const void *obj)
+{
+    if (__obj_flags == NULL)
+	return 0;
+
+    return (long)CFDictionaryGetValue(__obj_flags, obj);
+}
+
 bool
 rb_objc_flag_check(const void *obj, int flag)
 {
     long v;
 
-    if (__obj_flags == NULL)
-	return false;
- 
-    v = (long)CFDictionaryGetValue(__obj_flags, obj);
+    v = rb_objc_flag_get_mask(obj);
     if (v == 0)
 	return false;
 

Modified: MacRuby/trunk/string.c
===================================================================
--- MacRuby/trunk/string.c	2008-05-22 06:33:11 UTC (rev 209)
+++ MacRuby/trunk/string.c	2008-05-23 01:13:24 UTC (rev 210)
@@ -27,6 +27,7 @@
 
 VALUE rb_cString;
 #if WITH_OBJC
+VALUE rb_cCFString;
 VALUE rb_cStringRuby;
 #endif
 VALUE rb_cSymbol;
@@ -8323,13 +8324,8 @@
 }
 
 #if WITH_OBJC
-static Class __nscfstring = NULL;
+#define NSCFSTRING() (RCLASS_OCID(rb_cCFString))
 
-#define NSCFSTRING() \
-    (__nscfstring == NULL \
-	? __nscfstring = (Class)objc_getClass("NSCFString") \
-	: __nscfstring)
-
 #define PREPARE_RCV(x) \
     Class old = *(Class *)x; \
     *(Class *)x = NSCFSTRING();
@@ -8467,6 +8463,7 @@
 Init_String(void)
 {
 #if WITH_OBJC
+    rb_cCFString = rb_objc_import_class((Class)objc_getClass("NSCFString"));
     rb_cString = rb_objc_import_class((Class)objc_getClass("NSString"));
     rb_cStringRuby =
         rb_objc_import_class((Class)objc_getClass("NSMutableString"));

Modified: MacRuby/trunk/test/ruby/test_objc.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_objc.rb	2008-05-22 06:33:11 UTC (rev 209)
+++ MacRuby/trunk/test/ruby/test_objc.rb	2008-05-23 01:13:24 UTC (rev 210)
@@ -2,6 +2,10 @@
 
 class TestObjC < Test::Unit::TestCase
 
+  def setup
+    framework 'Foundation'
+  end
+
   def test_all_objects_inherit_from_nsobject
     assert_kind_of(NSObject, true)
     assert_kind_of(NSObject, false)
@@ -67,5 +71,25 @@
     assert_equal('xxxyyy', r)
   end
 
+  def test_pure_objc_ivar
+    o = NSObject.alloc.init
+    assert_kind_of(NSObject, o)
+    o.instance_variable_set(:@foo, 'foo')
+    GC.start
+    assert_equal('foo', o.instance_variable_get(:@foo))
+  end
+
+  def test_method_variadic
+    p = NSPredicate.predicateWithFormat('foo == 1')
+    assert_kind_of(NSPredicate, p)
+    assert_equal('foo == 1', p.predicateFormat)
+    p = NSPredicate.predicateWithFormat('foo == %@', 'bar')
+    assert_kind_of(NSPredicate, p)
+    assert_equal('foo == "bar"', p.predicateFormat)
+    p = NSPredicate.predicateWithFormat('%@ == %@', 'foo', 'bar')
+    assert_kind_of(NSPredicate, p)
+    assert_equal('"foo" == "bar"', p.predicateFormat)
+  end
+
 end
 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080522/24b04fd4/attachment-0001.htm 


More information about the macruby-changes mailing list