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

source_changes at macosforge.org source_changes at macosforge.org
Mon Apr 27 21:25:24 PDT 2009


Revision: 1497
          http://trac.macosforge.org/projects/ruby/changeset/1497
Author:   lsansonetti at apple.com
Date:     2009-04-27 21:25:21 -0700 (Mon, 27 Apr 2009)
Log Message:
-----------
more Pointer work (should be almost done) + misc fixes

Modified Paths:
--------------
    MacRuby/branches/experimental/roxor.cpp
    MacRuby/branches/experimental/spec/macruby/pointer_spec.rb

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-04-28 03:11:40 UTC (rev 1496)
+++ MacRuby/branches/experimental/roxor.cpp	2009-04-28 04:25:21 UTC (rev 1497)
@@ -5624,6 +5624,7 @@
 	    return Type::Int32Ty;
 
 	case _C_LNG:
+	case _C_ULNG:
 #if __LP64__
 	    return Type::Int64Ty;
 #else
@@ -5659,8 +5660,7 @@
 	    break;
     }
 
-    printf("unrecognized runtime type `%s' - aborting\n", type);
-    abort();
+    rb_raise(rb_eTypeError, "unrecognized runtime type `%s'\n", type);
 }
 
 Function *
@@ -9085,15 +9085,22 @@
     void *val;
 } rb_vm_pointer_t;
 
+static const char *convert_ffi_type(VALUE type,
+	bool raise_exception_if_unknown);
+
 static VALUE
-rb_pointer_new(VALUE rcv, SEL sel, VALUE type)
+rb_pointer_new(VALUE rcv, SEL sel, int argc, VALUE *argv)
 {
+    VALUE type, len;
+    rb_scan_args(argc, argv, "11", &type, &len);
+    const size_t rlen = NIL_P(len) ? 1 : FIX2LONG(len);
+
     StringValuePtr(type);
+    const char *type_str = convert_ffi_type(type, false);
 
     rb_vm_pointer_t *ptr = (rb_vm_pointer_t *)xmalloc(sizeof(rb_vm_pointer_t));
-    GC_WB(&ptr->type, type);
+    GC_WB(&ptr->type, rb_str_new2(type_str));
 
-    const char *type_str = RSTRING_PTR(type);
     ptr->convert_to_rval =
 	(VALUE (*)(void *))GET_VM()->gen_to_rval_convertor(type_str);
     ptr->convert_to_ocval =
@@ -9101,7 +9108,7 @@
 
     ptr->type_size = GET_VM()->get_sizeof(type_str);
     assert(ptr->type_size > 0);
-    GC_WB(&ptr->val, xmalloc(ptr->type_size));
+    GC_WB(&ptr->val, xmalloc(ptr->type_size * rlen));
 
     return Data_Wrap_Struct(rb_cPointer, NULL, NULL, ptr);
 }
@@ -9152,6 +9159,7 @@
 void
 Init_BridgeSupport(void)
 {
+    // Boxed
     rb_cBoxed = rb_define_class("Boxed", rb_cObject);
     rb_objc_define_method(*(VALUE *)rb_cBoxed, "type",
 	    (void *)rb_boxed_objc_type, 0);
@@ -9159,11 +9167,12 @@
 	    (void *)rb_boxed_is_opaque, 0);
     boxed_ivar_type = rb_intern("__octype__");
 
+    // Pointer
     rb_cPointer = rb_define_class("Pointer", rb_cObject);
     rb_objc_define_method(*(VALUE *)rb_cPointer, "new",
-	    (void *)rb_pointer_new, 1);
+	    (void *)rb_pointer_new, -1);
     rb_objc_define_method(*(VALUE *)rb_cPointer, "new_with_type",
-	    (void *)rb_pointer_new, 1);
+	    (void *)rb_pointer_new, -1);
     rb_objc_define_method(rb_cPointer, "[]",
 	    (void *)rb_pointer_aref, 1);
     rb_objc_define_method(rb_cPointer, "[]=",
@@ -9515,12 +9524,12 @@
 // FFI
 
 static const char *
-convert_ffi_type(VALUE type)
+convert_ffi_type(VALUE type, bool raise_exception_if_unknown)
 {
     const char *typestr = StringValueCStr(type);
     assert(typestr != NULL);
 
-    // Converting Ruby-FFI types to Objective-C runtime types.
+    // Ruby-FFI types.
 
     if (strcmp(typestr, "char") == 0) {
 	return "c";
@@ -9565,8 +9574,17 @@
 	return "^";
     }
 
-    rb_raise(rb_eArgError, "unrecognized string `%s' given as FFI type",
-	typestr);
+    // MacRuby extensions.
+
+    if (strcmp(typestr, "object") == 0) {
+	return "@";
+    }
+
+    if (raise_exception_if_unknown) {
+	rb_raise(rb_eTypeError, "unrecognized string `%s' given as FFI type",
+		typestr);
+    }
+    return typestr;
 }
 
 Function *
@@ -9644,12 +9662,12 @@
     }
 
     std::string types;
-    types.append(convert_ffi_type(ret));
+    types.append(convert_ffi_type(ret, true));
 
     Check_Type(args, T_ARRAY);
     const int argc = RARRAY_LEN(args);
     for (int i = 0; i < argc; i++) {
-	types.append(convert_ffi_type(RARRAY_AT(args, i)));
+	types.append(convert_ffi_type(RARRAY_AT(args, i), true));
     } 
 
     rb_vm_c_stub_t *stub = (rb_vm_c_stub_t *)GET_VM()->gen_stub(types, argc,

Modified: MacRuby/branches/experimental/spec/macruby/pointer_spec.rb
===================================================================
--- MacRuby/branches/experimental/spec/macruby/pointer_spec.rb	2009-04-28 03:11:40 UTC (rev 1496)
+++ MacRuby/branches/experimental/spec/macruby/pointer_spec.rb	2009-04-28 04:25:21 UTC (rev 1497)
@@ -3,7 +3,6 @@
 framework 'Foundation'
 
 describe "A Pointer object" do
-=begin # TODO
   it "can be created using the #new class method and with a valid Objective-C type or a valid Symbol object" do
     types = {
       :object     => '@',
@@ -31,22 +30,70 @@
     end
 
     lambda { Pointer.new }.should raise_error(ArgumentError)
-    lambda { Pointer.new('invalid') }.should raise_error(TypeError)
+    lambda { Pointer.new(nil) }.should raise_error(TypeError)
+    lambda { Pointer.new(123) }.should raise_error(TypeError)
+    lambda { Pointer.new('x') }.should raise_error(TypeError)
+
+    p = Pointer.new(NSRect.type)
+    p.type.should == NSRect.type
   end
-=end
 
-=begin # TODO
-  it "can be assigned an object of the given type and retrieve it later, using #[] and #[]=" 
-    p = Pointer.new('@')
+  it "can be assigned an object of the given type and retrieve it later, using #[] and #[]=" do
+    p = Pointer.new('object')
     o = Object.new
     p[0] = o
+    p[0].object_id.should == o.object_id
     p[0].should == o
 
-    p = Pointer.new('i')
-    p[0] = 42
-    p[0].should == 42
+    p[0] = 123
+    p[0].class.should == Fixnum
+    p[0].should == 123
 
-    lambda { p[0] = Object.new }.should raise_error(TypeError)
+    int_types = %w{ char uchar short ushort int uint long ulong
+                    long_long ulong_long }
+    int_types.each do |t|
+      p = Pointer.new(t)
+      p[0] = 42
+      p[0].class.should == Fixnum
+      p[0].should == 42
+
+      o = Object.new
+      def o.to_i; 42; end
+
+      p[0] = o
+      p[0].class.should == Fixnum
+      p[0].should == 42
+
+      lambda { p[0] = Object.new }.should raise_error(TypeError)
+    end
+
+    float_types = %w{ float double }
+    float_types.each do |t|
+      p = Pointer.new(t)
+      p[0] = 42
+      p[0].class.should == Float
+      p[0].should == 42.0
+
+      o = Object.new
+      def o.to_f; 42.0; end
+
+      p[0] = o
+      p[0].class.should == Float
+      p[0].should == 42.0
+
+      lambda { p[0] = Object.new }.should raise_error(TypeError)
+    end
+
+    struct_types = [[NSPoint, NSPoint.new(1, 2)],
+                    [NSSize, NSSize.new(3, 4)],
+                    [NSRect, NSRect.new(NSPoint.new(1, 2), NSSize.new(3, 4))]]
+    struct_types.each do |k, o|
+      p = Pointer.new(k.type)
+      p[0] = o
+      p[0].class.should == k
+      p[0].should == o
+
+      lambda { p[0] = Object.new }.should raise_error(TypeError)
+    end
   end
-=end 
 end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090427/22cc1119/attachment-0001.html>


More information about the macruby-changes mailing list