[macruby-changes] [125] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Mar 31 17:29:17 PDT 2008


Revision: 125
          http://trac.macosforge.org/projects/ruby/changeset/125
Author:   lsansonetti at apple.com
Date:     2008-03-31 17:29:16 -0700 (Mon, 31 Mar 2008)

Log Message:
-----------
fixing more Array regressions

Modified Paths:
--------------
    MacRuby/trunk/array.c
    MacRuby/trunk/enumerator.c
    MacRuby/trunk/hash.c
    MacRuby/trunk/include/ruby/intern.h
    MacRuby/trunk/object.c
    MacRuby/trunk/test/ruby/test_array.rb

Modified: MacRuby/trunk/array.c
===================================================================
--- MacRuby/trunk/array.c	2008-03-31 19:26:59 UTC (rev 124)
+++ MacRuby/trunk/array.c	2008-04-01 00:29:16 UTC (rev 125)
@@ -41,8 +41,10 @@
 }
 
 #if WITH_OBJC
+/* TODO optimize this */
 struct rb_objc_ary_struct {
     bool frozen;
+    bool tainted;
     bool named_args;
     void *cptr;
 };
@@ -63,13 +65,29 @@
 
     s = rb_objc_ary_get_struct(ary);
     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->named_args = false;
+	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)
 
@@ -129,6 +147,22 @@
 #endif
 }
 
+#if WITH_OBJC
+VALUE
+rb_ary_taint(VALUE ary)
+{
+    rb_objc_ary_get_struct2(ary)->tainted = true;
+    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
@@ -273,9 +307,7 @@
     ary = rb_ary_new2(n);
     if (n > 0 && elts) {
 #if WITH_OBJC
-	long i;
-	for (i = 0; i < n; i++)
-	    rb_ary_insert(ary, i, elts[i]);
+	CFArrayReplaceValues((CFMutableArrayRef)ary, CFRangeMake(0, 0), (const void **)elts, n);
 #else
 	MEMCPY(RARRAY_PTR(ary), elts, VALUE, n);
 	RARRAY(ary)->len = n;
@@ -1523,10 +1555,10 @@
     return Qfalse;
 }
 
-VALUE
-rb_ary_dup(VALUE ary)
+#if WITH_OBJC
+static inline VALUE
+rb_ary_dup2(VALUE ary)
 {
-#if WITH_OBJC
     VALUE klass, dup;
     long n;
 
@@ -1536,6 +1568,24 @@
     if (n > 0)
 	CFArrayAppendArray((CFMutableArrayRef)dup, (CFArrayRef)ary,
 		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
+rb_ary_dup(VALUE ary)
+{
+#if WITH_OBJC
+    VALUE dup = rb_ary_dup2(ary);
+    /* copy the named_args flag, but not other flags */
     if (rb_ary_is_named_args(ary))
 	rb_ary_set_named_args(dup, true);
 #else
@@ -3692,7 +3742,9 @@
 	volatile VALUE cc = rb_ary_new2(n);
 	long lev = 0;
 
+#if !WITH_OBJC
 	RBASIC(cc)->klass = 0;
+#endif
 	MEMZERO(stack, long, n);
 	stack[0] = -1;
 	for (i = 0; i < nlen; i++) {
@@ -3700,7 +3752,11 @@
 	    for (lev++; lev < n; lev++) {
 		rb_ary_store(cc, lev, RARRAY_AT(ary, stack[lev+1] = stack[lev]+1));
 	    }
+#if WITH_OBJC
+	    rb_yield(rb_ary_dup(cc));
+#else
 	    rb_yield(cc);
+#endif
 	    do {
 		stack[lev--]++;
 	    } while (lev && (stack[lev+1]+n == len+lev+1));
@@ -3925,6 +3981,8 @@
     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/enumerator.c
===================================================================
--- MacRuby/trunk/enumerator.c	2008-03-31 19:26:59 UTC (rev 124)
+++ MacRuby/trunk/enumerator.c	2008-04-01 00:29:16 UTC (rev 125)
@@ -241,7 +241,7 @@
     else {
 	ptr->iter = enumerator_each_i;
     }
-    if (argc) ptr->args = rb_ary_new4(argc, argv);
+    if (argc) GC_WB(&ptr->args, rb_ary_new4(argc, argv));
     ptr->fib = 0;
     ptr->dst = Qnil;
     ptr->no_next = Qfalse;

Modified: MacRuby/trunk/hash.c
===================================================================
--- MacRuby/trunk/hash.c	2008-03-31 19:26:59 UTC (rev 124)
+++ MacRuby/trunk/hash.c	2008-04-01 00:29:16 UTC (rev 125)
@@ -260,10 +260,12 @@
     rb_objc_release(v);
 }
 
+/* TODO optimize me */
 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. */
@@ -287,6 +289,7 @@
 	s->ifnone = Qnil;
 	s->has_proc_default = false;
 	s->frozen = false;
+	s->tainted = false;
     }
     return s;
 }
@@ -312,6 +315,27 @@
     return s != NULL && s->frozen ? Qtrue : Qfalse;
 }
 
+VALUE
+rb_hash_taint(VALUE hash)
+{
+    struct rb_objc_hash_struct *s;
+
+    s = rb_objc_hash_get_struct2(hash);
+    s->tainted = true;
+
+    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)
 {
@@ -322,7 +346,20 @@
     GC_WB(&s->ifnone, ifnone);
     s->has_proc_default = has_proc_default;
 }
+
+VALUE
+rb_hash_clone(VALUE hash)
+{
+#if 0 // TODO
+    VALUE klass, dup;
+    long n;
+
+    klass = rb_obj_class(ary);
+    dup = hash_alloc(klass);
 #endif
+    return Qnil;
+}
+#endif
 
 static VALUE
 hash_alloc(VALUE klass)
@@ -3046,6 +3083,8 @@
     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/intern.h
===================================================================
--- MacRuby/trunk/include/ruby/intern.h	2008-03-31 19:26:59 UTC (rev 124)
+++ MacRuby/trunk/include/ruby/intern.h	2008-04-01 00:29:16 UTC (rev 125)
@@ -81,6 +81,7 @@
 VALUE rb_ary_elt(VALUE, long);
 void rb_ary_set_named_args(VALUE, bool);
 bool rb_ary_is_named_args(VALUE);
+VALUE rb_ary_clone(VALUE);
 #endif
 /* bignum.c */
 VALUE rb_big_clone(VALUE);
@@ -361,6 +362,9 @@
 struct st_table *rb_hash_tbl(VALUE);
 int rb_path_check(const char*);
 int rb_env_path_tainted(void);
+#if WITH_OBJC
+VALUE rb_hash_clone(VALUE);
+#endif
 /* io.c */
 #define rb_defout rb_stdout
 RUBY_EXTERN VALUE rb_fs;

Modified: MacRuby/trunk/object.c
===================================================================
--- MacRuby/trunk/object.c	2008-03-31 19:26:59 UTC (rev 124)
+++ MacRuby/trunk/object.c	2008-04-01 00:29:16 UTC (rev 125)
@@ -157,6 +157,16 @@
 static void
 init_copy(VALUE dest, VALUE obj)
 {
+#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);
+	goto call_init_copy;
+    }
+#endif
     if (OBJ_FROZEN(dest)) {
         rb_raise(rb_eTypeError, "[bug] frozen object (%s) allocated", rb_obj_classname(dest));
     }
@@ -197,6 +207,7 @@
 	}
         break;
     }
+call_init_copy:
     rb_funcall(dest, id_init_copy, 1, obj);
 }
 
@@ -234,6 +245,11 @@
     }
 #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);
         clone = rb_obj_alloc(rb_obj_class(obj));
         init_copy(clone, obj);
 	return clone;

Modified: MacRuby/trunk/test/ruby/test_array.rb
===================================================================
--- MacRuby/trunk/test/ruby/test_array.rb	2008-03-31 19:26:59 UTC (rev 124)
+++ MacRuby/trunk/test/ruby/test_array.rb	2008-04-01 00:29:16 UTC (rev 125)
@@ -182,14 +182,14 @@
 
   def test_00_new
     a = @cls.new()
-    assert_instance_of(@cls, a)
+    assert_kind_of(@cls, a)
     assert_equal(0, a.length)
     assert_nil(a[0])
   end
 
   def test_01_square_brackets
     a = @cls[ 5, 4, 3, 2, 1 ]
-    assert_instance_of(@cls, a)
+    assert_kind_of(@cls, a)
     assert_equal(5, a.length)
     5.times { |i| assert_equal(5-i, a[i]) }
     assert_nil(a[6])

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080331/0cff5afc/attachment-0001.html


More information about the macruby-changes mailing list