[macruby-changes] [1482] MacRuby/branches/experimental

source_changes at macosforge.org source_changes at macosforge.org
Thu Apr 23 19:47:52 PDT 2009


Revision: 1482
          http://trac.macosforge.org/projects/ruby/changeset/1482
Author:   lsansonetti at apple.com
Date:     2009-04-23 19:47:49 -0700 (Thu, 23 Apr 2009)
Log Message:
-----------
implemented struct #dup/#clone

Modified Paths:
--------------
    MacRuby/branches/experimental/id.c
    MacRuby/branches/experimental/id.h
    MacRuby/branches/experimental/include/ruby/intern.h
    MacRuby/branches/experimental/object.c
    MacRuby/branches/experimental/roxor.cpp
    MacRuby/branches/experimental/spec/macruby/struct_spec.rb

Modified: MacRuby/branches/experimental/id.c
===================================================================
--- MacRuby/branches/experimental/id.c	2009-04-24 00:42:31 UTC (rev 1481)
+++ MacRuby/branches/experimental/id.c	2009-04-24 02:47:49 UTC (rev 1482)
@@ -84,6 +84,7 @@
     selBinding = sel_registerName("binding");
     selEach = sel_registerName("each");
     selEqq = sel_registerName("===:");
+    selDup = sel_registerName("dup");
     selBackquote = sel_registerName("`:");
     selMethodAdded = sel_registerName("method_added:");
     selSingletonMethodAdded = sel_registerName("singleton_method_added:");

Modified: MacRuby/branches/experimental/id.h
===================================================================
--- MacRuby/branches/experimental/id.h	2009-04-24 00:42:31 UTC (rev 1481)
+++ MacRuby/branches/experimental/id.h	2009-04-24 02:47:49 UTC (rev 1482)
@@ -93,6 +93,7 @@
 extern SEL selBinding;
 extern SEL selEach;
 extern SEL selEqq;
+extern SEL selDup;
 extern SEL selBackquote;
 extern SEL selMethodAdded;
 extern SEL selSingletonMethodAdded;

Modified: MacRuby/branches/experimental/include/ruby/intern.h
===================================================================
--- MacRuby/branches/experimental/include/ruby/intern.h	2009-04-24 00:42:31 UTC (rev 1481)
+++ MacRuby/branches/experimental/include/ruby/intern.h	2009-04-24 02:47:49 UTC (rev 1482)
@@ -413,6 +413,7 @@
 VALUE rb_fix2str(VALUE, int);
 VALUE rb_dbl_cmp(double, double);
 /* object.c */
+VALUE rb_send_dup(VALUE);
 int rb_eql(VALUE, VALUE);
 VALUE rb_any_to_s(VALUE);
 VALUE rb_inspect(VALUE);

Modified: MacRuby/branches/experimental/object.c
===================================================================
--- MacRuby/branches/experimental/object.c	2009-04-24 00:42:31 UTC (rev 1481)
+++ MacRuby/branches/experimental/object.c	2009-04-24 02:47:49 UTC (rev 1482)
@@ -40,7 +40,14 @@
 static void *initializeCache = NULL;
 static void *initialize2Cache = NULL;
 static void *eqCache = NULL;
+static void *dupCache = NULL;
 
+inline VALUE
+rb_send_dup(VALUE obj)
+{
+    return rb_vm_call_with_cache(dupCache, obj, selDup, 0, NULL);
+}
+
 /*
  *  call-seq:
  *     obj === other   => true or false
@@ -2672,6 +2679,7 @@
     initializeCache = rb_vm_get_call_cache(selInitialize);
     initialize2Cache = rb_vm_get_call_cache(selInitialize2);
     eqCache = rb_vm_get_call_cache(selEq);
+    dupCache = rb_vm_get_call_cache(selDup);
 
     rb_objc_define_method(*(VALUE *)rb_cModule, "alloc", rb_module_s_alloc, 0);
     rb_objc_define_method(*(VALUE *)rb_cClass, "alloc", rb_class_s_alloc, 0);

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-04-24 00:42:31 UTC (rev 1481)
+++ MacRuby/branches/experimental/roxor.cpp	2009-04-24 02:47:49 UTC (rev 1482)
@@ -8588,6 +8588,28 @@
     return str;
 }
 
+static VALUE
+rb_vm_struct_dup(VALUE rcv, SEL sel)
+{
+    VALUE klass = CLASS_OF(rcv);
+    rb_vm_bs_boxed_t *bs_boxed = locate_bs_boxed(klass);
+
+    VALUE *rcv_data;
+    Data_Get_Struct(rcv, VALUE, rcv_data);
+    VALUE *new_data = (VALUE *)xmalloc(
+	    bs_boxed->as.s->fields_count * sizeof(VALUE));
+    for (unsigned i = 0; i < bs_boxed->as.s->fields_count; i++) {
+	VALUE field = rcv_data[i];
+	// Numeric values cannot be duplicated.
+	if (!rb_obj_is_kind_of(field, rb_cNumeric)) {
+	    field = rb_send_dup(field);
+	}
+	GC_WB(&new_data[i], field);
+    }
+
+    return Data_Wrap_Struct(klass, NULL, NULL, new_data);
+}
+
 static bool
 register_bs_boxed(bs_element_type_t type, void *value)
 {
@@ -8632,6 +8654,10 @@
 	// Define other utility methods.
 	rb_objc_define_method(boxed->klass, "==",
 		(void *)rb_vm_struct_equal, 1);
+	rb_objc_define_method(boxed->klass, "dup",
+		(void *)rb_vm_struct_dup, 0);
+	rb_objc_define_method(boxed->klass, "clone",
+		(void *)rb_vm_struct_dup, 0);
 	rb_objc_define_method(boxed->klass, "inspect",
 		(void *)rb_vm_struct_inspect, 0);
     }

Modified: MacRuby/branches/experimental/spec/macruby/struct_spec.rb
===================================================================
--- MacRuby/branches/experimental/spec/macruby/struct_spec.rb	2009-04-24 00:42:31 UTC (rev 1481)
+++ MacRuby/branches/experimental/spec/macruby/struct_spec.rb	2009-04-24 02:47:49 UTC (rev 1482)
@@ -162,4 +162,23 @@
     r.size = s
     r.inspect.should == "#<NSRect origin=#<NSPoint x=1.0 y=2.0> size=#<NSSize width=3.0 height=4.0>>"
   end
+
+  it "can be duplicated using #dup or #clone" do
+    p = NSPoint.new(1, 2)
+    p.should == p.dup
+    p.should == p.clone
+
+    p2 = p.dup
+    p2.x = 42
+    p2.should_not == p
+
+    r = NSRect.new
+    r.origin.x = 1
+    r.origin.y = 2
+    r2 = r.dup
+    r.size.width = 3.0
+    r.size.height = 4.0
+    r2.size = NSSize.new(3, 4)
+    r.should == r2
+  end
 end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090423/c548435a/attachment.html>


More information about the macruby-changes mailing list