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

source_changes at macosforge.org source_changes at macosforge.org
Thu Jun 11 20:24:29 PDT 2009


Revision: 1841
          http://trac.macosforge.org/projects/ruby/changeset/1841
Author:   lsansonetti at apple.com
Date:     2009-06-11 20:24:28 -0700 (Thu, 11 Jun 2009)
Log Message:
-----------
added support for overwriting an ObjC method that accepts a pointer

Modified Paths:
--------------
    MacRuby/branches/experimental/bridgesupport.cpp
    MacRuby/branches/experimental/bridgesupport.h
    MacRuby/branches/experimental/compiler.cpp
    MacRuby/branches/experimental/compiler.h
    MacRuby/branches/experimental/spec/macruby/fixtures/method.m
    MacRuby/branches/experimental/spec/macruby/fixtures/method.rb
    MacRuby/branches/experimental/spec/macruby/language/objc_method_spec.rb

Modified: MacRuby/branches/experimental/bridgesupport.cpp
===================================================================
--- MacRuby/branches/experimental/bridgesupport.cpp	2009-06-12 00:55:52 UTC (rev 1840)
+++ MacRuby/branches/experimental/bridgesupport.cpp	2009-06-12 03:24:28 UTC (rev 1841)
@@ -500,15 +500,9 @@
 static const char *convert_ffi_type(VALUE type,
 	bool raise_exception_if_unknown);
 
-static VALUE
-rb_pointer_new(VALUE rcv, SEL sel, int argc, VALUE *argv)
+VALUE
+rb_pointer_new(const char *type_str, void *val)
 {
-    VALUE type, len;
-    rb_scan_args(argc, argv, "11", &type, &len);
-    const size_t rlen = NIL_P(len) ? 1 : FIX2LONG(len);
-
-    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, rb_str_new2(type_str));
 
@@ -519,11 +513,26 @@
 
     ptr->type_size = GET_VM()->get_sizeof(type_str);
     assert(ptr->type_size > 0);
-    GC_WB(&ptr->val, xmalloc(ptr->type_size * rlen));
 
+    GC_WB(&ptr->val, val);
+
     return Data_Wrap_Struct(rb_cPointer, NULL, NULL, ptr);
 }
 
+static VALUE
+rb_pointer_s_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);
+    const char *type_str = convert_ffi_type(type, false);
+
+    return rb_pointer_new(type_str,
+	    xmalloc(GET_VM()->get_sizeof(type_str) * rlen));
+}
+
 extern "C"
 void *
 rb_pointer_get_data(VALUE rcv, const char *type)
@@ -942,9 +951,9 @@
     // 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_s_new, -1);
     rb_objc_define_method(*(VALUE *)rb_cPointer, "new_with_type",
-	    (void *)rb_pointer_new, -1);
+	    (void *)rb_pointer_s_new, -1);
     rb_objc_define_method(rb_cPointer, "[]",
 	    (void *)rb_pointer_aref, 1);
     rb_objc_define_method(rb_cPointer, "[]=",
@@ -1016,7 +1025,7 @@
 
     // MacRuby extensions.
 
-    if (strcmp(typestr, "object") == 0) {
+    if (strcmp(typestr, "object") == 0 || strcmp(typestr, "id") == 0) {
 	return "@";
     }
 

Modified: MacRuby/branches/experimental/bridgesupport.h
===================================================================
--- MacRuby/branches/experimental/bridgesupport.h	2009-06-12 00:55:52 UTC (rev 1840)
+++ MacRuby/branches/experimental/bridgesupport.h	2009-06-12 03:24:28 UTC (rev 1841)
@@ -25,6 +25,8 @@
     VALUE klass;
 } rb_vm_bs_boxed_t;
 
+VALUE rb_pointer_new(const char *type_str, void *val);
+
 #endif /* __cplusplus */
 
 #endif /* __BRIDGESUPPORT_H_ */

Modified: MacRuby/branches/experimental/compiler.cpp
===================================================================
--- MacRuby/branches/experimental/compiler.cpp	2009-06-12 00:55:52 UTC (rev 1840)
+++ MacRuby/branches/experimental/compiler.cpp	2009-06-12 03:24:28 UTC (rev 1841)
@@ -86,6 +86,7 @@
     newArrayFunc = NULL;
     newStructFunc = NULL;
     newOpaqueFunc = NULL;
+    newPointerFunc = NULL;
     getStructFieldsFunc = NULL;
     getOpaqueDataFunc = NULL;
     getPointerPtrFunc = NULL;
@@ -4793,6 +4794,13 @@
     return Data_Wrap_Struct(klass, NULL, NULL, val);
 }
 
+extern "C"
+VALUE
+rb_vm_new_pointer(const char *type, void *val)
+{
+    return val == NULL ? Qnil : rb_pointer_new(type, val);
+}
+
 Value *
 RoxorCompiler::compile_new_struct(Value *klass, std::vector<Value *> &fields)
 {
@@ -4831,6 +4839,30 @@
 }
 
 Value *
+RoxorCompiler::compile_new_pointer(const char *type, Value *val)
+{
+    if (newPointerFunc == NULL) {
+	newPointerFunc = cast<Function>(module->getOrInsertFunction(
+		    "rb_vm_new_pointer", RubyObjTy, PtrTy, PtrTy, NULL));
+    }
+
+    std::vector<Value *> params;
+
+    GlobalVariable *gvar = compile_const_global_string(type);
+    std::vector<Value *> idxs;
+    idxs.push_back(ConstantInt::get(Type::Int32Ty, 0));
+    idxs.push_back(ConstantInt::get(Type::Int32Ty, 0));
+    Instruction *load = GetElementPtrInst::Create(gvar,
+	    idxs.begin(), idxs.end(), "", bb);
+    params.push_back(load);
+
+    params.push_back(val);
+
+    return CallInst::Create(newPointerFunc, params.begin(), params.end(),
+	    "", bb); 
+}
+
+Value *
 RoxorCompiler::compile_conversion_to_ruby(const char *type,
 					  const Type *llvm_type, Value *val)
 {
@@ -4941,6 +4973,8 @@
 		    Value *klass = ConstantInt::get(RubyObjTy, bs_boxed->klass);
 		    return compile_new_opaque(klass, val);
 		}
+
+		return compile_new_pointer(type + 1, val);
 	    }
 	    break; 
     }

Modified: MacRuby/branches/experimental/compiler.h
===================================================================
--- MacRuby/branches/experimental/compiler.h	2009-06-12 00:55:52 UTC (rev 1840)
+++ MacRuby/branches/experimental/compiler.h	2009-06-12 03:24:28 UTC (rev 1841)
@@ -116,6 +116,7 @@
 	Function *newArrayFunc;
 	Function *newStructFunc;
 	Function *newOpaqueFunc;
+	Function *newPointerFunc;
 	Function *getStructFieldsFunc;
 	Function *getOpaqueDataFunc;
 	Function *getPointerPtrFunc;
@@ -229,6 +230,7 @@
 	bool compile_lvars(ID *tbl);
 	Value *compile_new_struct(Value *klass, std::vector<Value *> &fields);
 	Value *compile_new_opaque(Value *klass, Value *val);
+	Value *compile_new_pointer(const char *type, Value *val);
 	void compile_get_struct_fields(Value *val, Value *buf,
 		rb_vm_bs_boxed_t *bs_boxed);
 	Value *compile_get_opaque_data(Value *val, rb_vm_bs_boxed_t *bs_boxed,

Modified: MacRuby/branches/experimental/spec/macruby/fixtures/method.m
===================================================================
--- MacRuby/branches/experimental/spec/macruby/fixtures/method.m	2009-06-12 00:55:52 UTC (rev 1840)
+++ MacRuby/branches/experimental/spec/macruby/fixtures/method.m	2009-06-12 03:24:28 UTC (rev 1841)
@@ -618,6 +618,26 @@
     return [o methodAcceptingNSRange:NSMakeRange(0, 42)];
 }
 
+- (BOOL)methodAcceptingObjPtr:(id *)p
+{
+    return *p == self;
+}
+
++ (BOOL)testMethodAcceptingObjPtr:(TestMethod *)o
+{
+    return [o methodAcceptingObjPtr:&o]; 
+}
+
+- (BOOL)methodAcceptingObjPtr2:(id *)p
+{
+    return p == NULL;
+}
+
++ (BOOL)testMethodAcceptingObjPtr2:(TestMethod *)o
+{
+    return [o methodAcceptingObjPtr2:NULL]; 
+}
+
 - (BOOL)methodAcceptingInt:(int)a1 float:(float)a2 double:(double)a3
 	short:(short)a4 NSPoint:(NSPoint)a5 NSRect:(NSRect)a6 char:(char)a7
 {

Modified: MacRuby/branches/experimental/spec/macruby/fixtures/method.rb
===================================================================
--- MacRuby/branches/experimental/spec/macruby/fixtures/method.rb	2009-06-12 00:55:52 UTC (rev 1840)
+++ MacRuby/branches/experimental/spec/macruby/fixtures/method.rb	2009-06-12 03:24:28 UTC (rev 1841)
@@ -55,6 +55,8 @@
   def methodAcceptingNSSize(a); super; end
   def methodAcceptingNSRect(a); super; end
   def methodAcceptingNSRange(a); super; end
+  def methodAcceptingObjPtr(a); super; end
+  def methodAcceptingObjPtr2(a); super; end
   def methodAcceptingInt(a, float:a2, double:a3, short:a4, NSPoint:a5,
                          NSRect:a6, char:a7); super; end
 end

Modified: MacRuby/branches/experimental/spec/macruby/language/objc_method_spec.rb
===================================================================
--- MacRuby/branches/experimental/spec/macruby/language/objc_method_spec.rb	2009-06-12 00:55:52 UTC (rev 1840)
+++ MacRuby/branches/experimental/spec/macruby/language/objc_method_spec.rb	2009-06-12 03:24:28 UTC (rev 1841)
@@ -623,6 +623,16 @@
     TestMethodOverride.testMethodAcceptingNSRange(@o).should == 1
   end
 
+  it "can overwrite an Objective-C method accepting a Pointer to an Object" do
+    p = Pointer.new(:object)
+    p[0] = @o
+    @o.methodAcceptingObjPtr(p).should == 1
+    TestMethodOverride.testMethodAcceptingObjPtr(@o).should == 1
+
+    @o.methodAcceptingObjPtr2(nil).should == 1
+    TestMethodOverride.testMethodAcceptingObjPtr2(@o).should == 1
+  end
+
   it "can overwrite a complex Objective-C method" do
     @o.methodAcceptingInt(42, float:42, double:42, short:42, NSPoint:NSPoint.new(42, 42), NSRect:NSRect.new(NSPoint.new(42, 42), NSSize.new(42, 42)), char:42).should == 1
     TestMethodOverride.testMethodAcceptingComplexTypes(@o).should == 1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090611/a5625a3a/attachment.html>


More information about the macruby-changes mailing list