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