Revision: 525 http://trac.macosforge.org/projects/ruby/changeset/525 Author: lsansonetti@apple.com Date: 2008-08-29 22:13:53 -0700 (Fri, 29 Aug 2008) Log Message: ----------- fixed #dup for boxed structs Modified Paths: -------------- MacRuby/trunk/objc.m MacRuby/trunk/test/ruby/test_objc.rb Modified: MacRuby/trunk/objc.m =================================================================== --- MacRuby/trunk/objc.m 2008-08-30 04:26:04 UTC (rev 524) +++ MacRuby/trunk/objc.m 2008-08-30 05:13:53 UTC (rev 525) @@ -2150,11 +2150,32 @@ bs_element_boxed_t *bs_boxed = rb_klass_get_bs_boxed(CLASS_OF(recv)); bs_element_struct_t *bs_struct = (bs_element_struct_t *)bs_boxed->value; VALUE *data, *new_data; + int i; + static ID idDup = 0; + if (idDup == 0) { + idDup = rb_intern("dup"); + } + Data_Get_Struct(recv, VALUE, data); new_data = (VALUE *)xmalloc(bs_struct->fields_count * sizeof(VALUE)); - memcpy(new_data, data, bs_struct->fields_count * sizeof(VALUE)); + for (i = 0; i < bs_struct->fields_count; i++) { + bs_element_struct_field_t *bs_field = + (bs_element_struct_field_t *)&bs_struct->fields[i]; + size_t fdata_size; + void *fdata; + VALUE fval; + + fdata_size = rb_objc_octype_to_ffitype(bs_field->type)->size; + fdata = alloca(fdata_size); + + rb_objc_rval_to_ocval(data[i], bs_field->type, fdata); + rb_objc_ocval_to_rval(fdata, bs_field->type, &fval); + + GC_WB(&new_data[i], fval); + } + return Data_Wrap_Struct(CLASS_OF(recv), NULL, NULL, new_data); } Modified: MacRuby/trunk/test/ruby/test_objc.rb =================================================================== --- MacRuby/trunk/test/ruby/test_objc.rb 2008-08-30 04:26:04 UTC (rev 524) +++ MacRuby/trunk/test/ruby/test_objc.rb 2008-08-30 05:13:53 UTC (rev 525) @@ -260,6 +260,17 @@ r.inspect) end + def test_struct_dup + r = NSMakeRect(1, 2, 3, 4) + r2 = r.dup + assert_kind_of(NSRect, r2) + assert_equal(r, r2) + r2.origin.x = 42 + assert(r != r2) + r2.origin.x = 1 + assert_equal(r, r2) + end + class TestInitCallInitialize attr_reader :foo def initialize