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

source_changes at macosforge.org source_changes at macosforge.org
Sat May 2 18:02:45 PDT 2009


Revision: 1517
          http://trac.macosforge.org/projects/ruby/changeset/1517
Author:   lsansonetti at apple.com
Date:     2009-05-02 18:02:45 -0700 (Sat, 02 May 2009)
Log Message:
-----------
adding more overwrite specs + fixed compilation of stubs returning a large struct

Modified Paths:
--------------
    MacRuby/branches/experimental/roxor.cpp
    MacRuby/branches/experimental/spec/macruby/fixtures/method.m
    MacRuby/branches/experimental/spec/macruby/fixtures/method.rb
    MacRuby/branches/experimental/spec/macruby/objc_method_spec.rb

Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp	2009-05-02 20:07:25 UTC (rev 1516)
+++ MacRuby/branches/experimental/roxor.cpp	2009-05-03 01:02:45 UTC (rev 1517)
@@ -6398,18 +6398,29 @@
 {
     char buf[100];
     const char *p = types;
+    std::vector<const Type *> f_types;
 
+    // Return value.
     p = GetFirstType(p, buf, sizeof buf);
     std::string ret_type(buf);
     const Type *f_ret_type = convert_type(buf);
+    const Type *f_sret_type = NULL;
+    if (GET_VM()->is_large_struct_type(f_ret_type)) {
+	// We are returning a large struct, we need to pass a pointer as the
+	// first argument to the structure data and return void to conform to
+	// the ABI.
+	f_types.push_back(PointerType::getUnqual(f_ret_type));
+	f_sret_type = f_ret_type;
+	f_ret_type = Type::VoidTy;
+    }
 
-    std::vector<const Type *> f_types;
     // self
     f_types.push_back(RubyObjTy);
     p = SkipFirstType(p);
     // sel
     f_types.push_back(PtrTy);
     p = SkipFirstType(p);
+    // Arguments.
     std::vector<std::string> arg_types;
     for (unsigned int i = 0; i < ruby_func->arg_size() - 2; i++) {
 	p = GetFirstType(p, buf, sizeof buf);
@@ -6417,31 +6428,44 @@
 	arg_types.push_back(buf);
     }
 
+    // Create the function.
     FunctionType *ft = FunctionType::get(f_ret_type, f_types, false);
     Function *f = cast<Function>(module->getOrInsertFunction("", ft));
     Function::arg_iterator arg = f->arg_begin();
 
     bb = BasicBlock::Create("EntryBlock", f);
 
+    Value *sret = NULL;
+    if (f_sret_type != NULL) {
+	sret = arg++;
+	f->addAttribute(0, Attribute::StructRet);
+    }
+
     std::vector<Value *> params;
     params.push_back(arg++); // self
     params.push_back(arg++); // sel
 
+    // Convert every incoming argument into Ruby type.
     for (unsigned int i = 0; i < ruby_func->arg_size() - 2; i++) {
 	Value *ruby_arg = compile_conversion_to_ruby(arg_types[i].c_str(),
 		f_types[i + 2], arg++);
 	params.push_back(ruby_arg);
     }
 
+    // Call the Ruby implementation.
     Value *ret_val = CallInst::Create(ruby_func, params.begin(),
 	    params.end(), "", bb);
 
+    // Convert the return value into Objective-C type (if any).
     if (f_ret_type != Type::VoidTy) {
 	ret_val = compile_conversion_to_c(ret_type.c_str(), ret_val,
 		new AllocaInst(f_ret_type, "", bb));
-
 	ReturnInst::Create(ret_val, bb);
     }
+    else if (sret != NULL) {
+	compile_conversion_to_c(ret_type.c_str(), ret_val, sret);
+	ReturnInst::Create(bb);
+    }
     else {
 	ReturnInst::Create(bb);
     }

Modified: MacRuby/branches/experimental/spec/macruby/fixtures/method.m
===================================================================
--- MacRuby/branches/experimental/spec/macruby/fixtures/method.m	2009-05-02 20:07:25 UTC (rev 1516)
+++ MacRuby/branches/experimental/spec/macruby/fixtures/method.m	2009-05-03 01:02:45 UTC (rev 1517)
@@ -255,51 +255,101 @@
     return 3.1415;
 }
 
++ (BOOL)testMethodReturningFloat:(TestMethod *)o
+{
+    return [o methodReturningFloat] == (float)3.1415;
+}
+
 - (double)methodReturningDouble
 {
     return 3.1415;
 }
 
++ (BOOL)testMethodReturningDouble:(TestMethod *)o
+{
+    return [o methodReturningDouble] == (double)3.1415;
+}
+
 - (SEL)methodReturningSEL
 {
     return @selector(foo:with:with:);
 }
 
++ (BOOL)testMethodReturningSEL:(TestMethod *)o
+{
+    return [o methodReturningSEL] == @selector(foo:with:with:);
+}
+
 - (SEL)methodReturningSEL2
 {
     return 0;
 }
 
++ (BOOL)testMethodReturningSEL2:(TestMethod *)o
+{
+    return [o methodReturningSEL2] == NULL;
+}
+
 - (const char *)methodReturningCharPtr
 {
     return "foo";
 }
 
++ (BOOL)testMethodReturningCharPtr:(TestMethod *)o
+{
+    return strcmp([o methodReturningCharPtr], "foo") == 0;
+}
+
 - (const char *)methodReturningCharPtr2
 {
     return NULL;
 }
 
++ (BOOL)testMethodReturningCharPtr2:(TestMethod *)o
+{
+    return [o methodReturningCharPtr2] == NULL;
+}
+
 - (NSPoint)methodReturningNSPoint
 {
     return NSMakePoint(1, 2);
 }
 
++ (BOOL)testMethodReturningNSPoint:(TestMethod *)o
+{
+    return NSEqualPoints([o methodReturningNSPoint], NSMakePoint(1, 2));
+}
+
 - (NSSize)methodReturningNSSize
 {
     return NSMakeSize(3, 4);
 }
 
++ (BOOL)testMethodReturningNSSize:(TestMethod *)o
+{
+    return NSEqualSizes([o methodReturningNSSize], NSMakeSize(3, 4));
+}
+
 - (NSRect)methodReturningNSRect
 {
     return NSMakeRect(1, 2, 3, 4);
 }
 
++ (BOOL)testMethodReturningNSRect:(TestMethod *)o
+{
+    return NSEqualRects([o methodReturningNSRect], NSMakeRect(1, 2, 3, 4));
+}
+
 - (NSRange)methodReturningNSRange
 {
     return NSMakeRange(0, 42);
 }
 
++ (BOOL)testMethodReturningNSRange:(TestMethod *)o
+{
+    return NSEqualRanges([o methodReturningNSRange], NSMakeRange(0, 42));
+}
+
 - (BOOL)methodAcceptingSelf:(id)obj
 {
     return obj == self;

Modified: MacRuby/branches/experimental/spec/macruby/fixtures/method.rb
===================================================================
--- MacRuby/branches/experimental/spec/macruby/fixtures/method.rb	2009-05-02 20:07:25 UTC (rev 1516)
+++ MacRuby/branches/experimental/spec/macruby/fixtures/method.rb	2009-05-03 01:02:45 UTC (rev 1517)
@@ -18,4 +18,14 @@
   def methodReturningLong; 42; end
   def methodReturningLong2; -42; end
   def methodReturningUnsignedLong; 42; end
+  def methodReturningFloat; 3.1415; end
+  def methodReturningDouble; 3.1415; end
+  def methodReturningSEL; :'foo:with:with:'; end
+  def methodReturningSEL2; nil; end
+  def methodReturningCharPtr; 'foo'; end
+  def methodReturningCharPtr2; nil; end
+  def methodReturningNSPoint; NSPoint.new(1, 2); end
+  def methodReturningNSSize; NSSize.new(3, 4); end
+  def methodReturningNSRect; NSRect.new(NSPoint.new(1, 2), NSSize.new(3, 4)); end
+  def methodReturningNSRange; NSRange.new(0, 42); end
 end

Modified: MacRuby/branches/experimental/spec/macruby/objc_method_spec.rb
===================================================================
--- MacRuby/branches/experimental/spec/macruby/objc_method_spec.rb	2009-05-02 20:07:25 UTC (rev 1516)
+++ MacRuby/branches/experimental/spec/macruby/objc_method_spec.rb	2009-05-03 01:02:45 UTC (rev 1517)
@@ -475,4 +475,45 @@
     TestMethodOverride.testMethodReturningLong2(@o).should == 1
     TestMethodOverride.testMethodReturningUnsignedLong(@o).should == 1
   end
+
+  it "can overwrite an Objective-C method returning 'float' or 'double'" do
+    @o.methodReturningFloat.should == 3.1415
+    @o.methodReturningDouble.should == 3.1415
+    TestMethodOverride.testMethodReturningFloat(@o).should == 1
+    TestMethodOverride.testMethodReturningDouble(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method returning 'SEL'" do
+    @o.methodReturningSEL.should == :'foo:with:with:'
+    @o.methodReturningSEL2.should == nil
+    TestMethodOverride.testMethodReturningSEL(@o).should == 1
+    TestMethodOverride.testMethodReturningSEL2(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method returning 'char *'" do
+    @o.methodReturningCharPtr.should == 'foo'
+    @o.methodReturningCharPtr2.should == nil
+    TestMethodOverride.testMethodReturningCharPtr(@o).should == 1
+    TestMethodOverride.testMethodReturningCharPtr2(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method returning 'NSPoint'" do
+    @o.methodReturningNSPoint.should == NSPoint.new(1, 2)
+    TestMethodOverride.testMethodReturningNSPoint(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method returning 'NSSize'" do
+    @o.methodReturningNSSize.should == NSSize.new(3, 4)
+    TestMethodOverride.testMethodReturningNSSize(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method returning 'NSRect'" do
+    @o.methodReturningNSRect.should == NSRect.new(NSPoint.new(1, 2), NSSize.new(3, 4))
+    TestMethodOverride.testMethodReturningNSRect(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method returning 'NSRange'" do
+    @o.methodReturningNSRange.should == NSRange.new(0, 42)
+    TestMethodOverride.testMethodReturningNSRange(@o).should == 1
+  end
 end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090502/241e7ec1/attachment.html>


More information about the macruby-changes mailing list