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

source_changes at macosforge.org source_changes at macosforge.org
Thu May 28 01:06:03 PDT 2009


Revision: 1622
          http://trac.macosforge.org/projects/ruby/changeset/1622
Author:   lsansonetti at apple.com
Date:     2009-05-28 01:06:03 -0700 (Thu, 28 May 2009)
Log Message:
-----------
added support for overwriting an objc method that accepts an argument > 128bit (ABI wise) + added missing specs regarding to the overwriting of objc methods accepting arguments

Modified Paths:
--------------
    MacRuby/branches/experimental/compiler.cpp
    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/compiler.cpp
===================================================================
--- MacRuby/branches/experimental/compiler.cpp	2009-05-28 02:00:53 UTC (rev 1621)
+++ MacRuby/branches/experimental/compiler.cpp	2009-05-28 08:06:03 UTC (rev 1622)
@@ -5085,7 +5085,7 @@
     Value *argv_arg = arg++;
 
     // Arguments.
-    std::vector<int> byval_args;
+    std::vector<unsigned int> byval_args;
     int given_argc = 0;
     bool variadic = false;
     while ((p = GetFirstType(p, buf, sizeof buf)) != NULL && buf[0] != '\0') {
@@ -5105,9 +5105,9 @@
 	}
 
 	if (!variadic) {
-	    // In order to conform to the ABI, we must stop providing types once we
-	    // start dealing with variable arguments and instead mark the function as
-	    // variadic.
+	    // In order to conform to the ABI, we must stop providing types
+	    // once we start dealing with variable arguments and instead mark
+	    // the function as variadic.
 	    f_types.push_back(f_type);
 	}
 
@@ -5129,9 +5129,8 @@
     CallInst *imp_call = CallInst::Create(imp, params.begin(), params.end(),
 	    "", bb); 
 
-    for (std::vector<int>::iterator iter = byval_args.begin();
+    for (std::vector<unsigned int>::iterator iter = byval_args.begin();
 	 iter != byval_args.end(); ++iter) {
-	
 	imp_call->addAttribute(*iter, Attribute::ByVal);
     }
 
@@ -5230,9 +5229,18 @@
     p = SkipFirstType(p);
     // Arguments.
     std::vector<std::string> arg_types;
+    std::vector<unsigned int> byval_args;
     for (unsigned int i = 0; i < ruby_func->arg_size() - 2; i++) {
 	p = GetFirstType(p, buf, sizeof buf);
-	f_types.push_back(convert_type(buf));
+	const Type *t = convert_type(buf);
+	if (GET_VM()->is_large_struct_type(t)) {
+	    // We are passing a large struct, we need to mark this argument
+	    // with the byval attribute and configure the internal stub
+	    // call to pass a pointer to the structure, to conform to the ABI.
+	    t = PointerType::getUnqual(t);
+	    byval_args.push_back(f_types.size() + 1 /* retval */);
+	}
+	f_types.push_back(t);
 	arg_types.push_back(buf);
     }
 
@@ -5248,6 +5256,10 @@
 	sret = arg++;
 	f->addAttribute(0, Attribute::StructRet);
     }
+    for (std::vector<unsigned int>::iterator iter = byval_args.begin();
+	 iter != byval_args.end(); ++iter) {
+	f->addAttribute(*iter, Attribute::ByVal);
+    }
 
     std::vector<Value *> params;
     params.push_back(arg++); // self
@@ -5255,8 +5267,13 @@
 
     // Convert every incoming argument into Ruby type.
     for (unsigned int i = 0; i < ruby_func->arg_size() - 2; i++) {
+	Value *a = arg++;
+	if (std::find(byval_args.begin(), byval_args.end(), i + 3)
+	    != byval_args.end()) {
+	     a = new LoadInst(a, "", bb);
+	}
 	Value *ruby_arg = compile_conversion_to_ruby(arg_types[i].c_str(),
-		f_types[i + 2], arg++);
+		f_types[i + 2], a);
 	params.push_back(ruby_arg);
     }
 

Modified: MacRuby/branches/experimental/spec/macruby/fixtures/method.m
===================================================================
--- MacRuby/branches/experimental/spec/macruby/fixtures/method.m	2009-05-28 02:00:53 UTC (rev 1621)
+++ MacRuby/branches/experimental/spec/macruby/fixtures/method.m	2009-05-28 08:06:03 UTC (rev 1622)
@@ -355,132 +355,262 @@
     return obj == self;
 }
 
++ (BOOL)testMethodAcceptingSelf:(TestMethod *)o
+{
+    return [o methodAcceptingSelf:o];
+}
+
 - (BOOL)methodAcceptingSelfClass:(id)obj
 {
     return obj == [self class];
 }
 
++ (BOOL)testMethodAcceptingSelfClass:(TestMethod *)o
+{
+    return [o methodAcceptingSelfClass:[o class]];
+}
+
 - (BOOL)methodAcceptingNil:(id)obj
 {
     return obj == nil;
 }
 
++ (BOOL)testMethodAcceptingNil:(TestMethod *)o
+{
+    return [o methodAcceptingNil:nil];
+}
+
 - (BOOL)methodAcceptingTrue:(id)obj
 {
     return obj == (id)kCFBooleanTrue;
 }
 
++ (BOOL)testMethodAcceptingTrue:(TestMethod *)o
+{
+    return [o methodAcceptingTrue:(id)kCFBooleanTrue];
+}
+
 - (BOOL)methodAcceptingFalse:(id)obj
 {
     return obj == (id)kCFBooleanFalse;
 }
 
++ (BOOL)testMethodAcceptingFalse:(TestMethod *)o
+{
+    return [o methodAcceptingFalse:(id)kCFBooleanFalse];
+}
+
 - (BOOL)methodAcceptingFixnum:(id)obj
 {
     return [obj intValue] == 42;
 }
 
++ (BOOL)testMethodAcceptingFixnum:(TestMethod *)o
+{
+    return [o methodAcceptingFixnum:[NSNumber numberWithInt:42]];
+}
+
 - (BOOL)methodAcceptingChar:(char)c
 {
     return c == 42;
 }
 
++ (BOOL)testMethodAcceptingChar:(TestMethod *)o
+{
+    return [o methodAcceptingChar:42];
+}
+
 - (BOOL)methodAcceptingUnsignedChar:(unsigned char)c
 {
     return c == 42;
 }
 
++ (BOOL)testMethodAcceptingUnsignedChar:(TestMethod *)o
+{
+    return [o methodAcceptingUnsignedChar:42];
+}
+
 - (BOOL)methodAcceptingShort:(short)c
 {
     return c == 42;
 }
 
++ (BOOL)testMethodAcceptingShort:(TestMethod *)o
+{
+    return [o methodAcceptingShort:42];
+}
+
 - (BOOL)methodAcceptingUnsignedShort:(unsigned short)c
 {
     return c == 42;
 }
 
++ (BOOL)testMethodAcceptingUnsignedShort:(TestMethod *)o
+{
+    return [o methodAcceptingUnsignedShort:42];
+}
+
 - (BOOL)methodAcceptingInt:(int)c
 {
     return c == 42;
 }
 
++ (BOOL)testMethodAcceptingInt:(TestMethod *)o
+{
+    return [o methodAcceptingInt:42];
+}
+
 - (BOOL)methodAcceptingUnsignedInt:(unsigned int)c
 {
     return c == 42;
 }
 
++ (BOOL)testMethodAcceptingUnsignedInt:(TestMethod *)o
+{
+    return [o methodAcceptingUnsignedInt:42];
+}
+
 - (BOOL)methodAcceptingLong:(long)c
 {
     return c == 42;
 }
 
++ (BOOL)testMethodAcceptingLong:(TestMethod *)o
+{
+    return [o methodAcceptingLong:42];
+}
+
 - (BOOL)methodAcceptingUnsignedLong:(unsigned long)c
 {
     return c == 42;
 }
 
++ (BOOL)testMethodAcceptingUnsignedLong:(TestMethod *)o
+{
+    return [o methodAcceptingUnsignedLong:42];
+}
+
 - (BOOL)methodAcceptingTrueBOOL:(BOOL)b
 {
     return b == YES;
 }
 
++ (BOOL)testMethodAcceptingTrueBOOL:(TestMethod *)o
+{
+    return [o methodAcceptingTrueBOOL:YES];
+}
+
 - (BOOL)methodAcceptingFalseBOOL:(BOOL)b
 {
     return b == NO;
 }
 
++ (BOOL)testMethodAcceptingFalseBOOL:(TestMethod *)o
+{
+    return [o methodAcceptingFalseBOOL:NO];
+}
+
 - (BOOL)methodAcceptingSEL:(SEL)sel
 {
     return sel == @selector(foo:with:with:);
 }
 
++ (BOOL)testMethodAcceptingSEL:(TestMethod *)o
+{
+    return [o methodAcceptingSEL:@selector(foo:with:with:)];
+}
+
 - (BOOL)methodAcceptingSEL2:(SEL)sel
 {
     return sel == 0;
 }
 
++ (BOOL)testMethodAcceptingSEL2:(TestMethod *)o
+{
+    return [o methodAcceptingSEL2:0];
+}
+
 - (BOOL)methodAcceptingCharPtr:(const char *)s
 {
     return strcmp(s, "foo") == 0;
 }
 
++ (BOOL)testMethodAcceptingCharPtr:(TestMethod *)o
+{
+    return [o methodAcceptingCharPtr:"foo"];
+}
+
 - (BOOL)methodAcceptingCharPtr2:(const char *)s
 {
     return s == NULL;
 }
 
++ (BOOL)testMethodAcceptingCharPtr2:(TestMethod *)o
+{
+    return [o methodAcceptingCharPtr2:NULL];
+}
+
 - (BOOL)methodAcceptingFloat:(float)f
 {
     return f > 3.1414 && f < 3.1416;
 }
 
++ (BOOL)testMethodAcceptingFloat:(TestMethod *)o
+{
+    return [o methodAcceptingFloat:3.1415];
+}
+
 - (BOOL)methodAcceptingDouble:(double)d
 {
     return d > 3.1414 && d < 3.1416;
 }
 
++ (BOOL)testMethodAcceptingDouble:(TestMethod *)o
+{
+    return [o methodAcceptingDouble:3.1415];
+}
+
 - (BOOL)methodAcceptingNSPoint:(NSPoint)p
 {
     return p.x == 1 && p.y == 2;
 }
 
++ (BOOL)testMethodAcceptingNSPoint:(TestMethod *)o
+{
+    return [o methodAcceptingNSPoint:NSMakePoint(1, 2)];
+}
+
 - (BOOL)methodAcceptingNSSize:(NSSize)s
 {
     return s.width == 3 && s.height == 4;
 }
 
++ (BOOL)testMethodAcceptingNSSize:(TestMethod *)o
+{
+    return [o methodAcceptingNSSize:NSMakeSize(3, 4)];
+}
+
 - (BOOL)methodAcceptingNSRect:(NSRect)r
 {
     return r.origin.x == 1 && r.origin.y == 2 && r.size.width == 3
 	&& r.size.height == 4;
 }
 
++ (BOOL)testMethodAcceptingNSRect:(TestMethod *)o
+{
+    return [o methodAcceptingNSRect:NSMakeRect(1, 2, 3, 4)];
+}
+
 - (BOOL)methodAcceptingNSRange:(NSRange)r
 {
     return r.location == 0 && r.length == 42;
 }
 
++ (BOOL)testMethodAcceptingNSRange:(TestMethod *)o
+{
+    return [o methodAcceptingNSRange:NSMakeRange(0, 42)];
+}
+
 - (BOOL)methodAcceptingInt:(int)a1 float:(float)a2 double:(double)a3
 	short:(short)a4 NSPoint:(NSPoint)a5 NSRect:(NSRect)a6 char:(char)a7
 {
@@ -491,6 +621,13 @@
 	&& a7 == 42;
 }
 
++ (BOOL)testMethodAcceptingComplexTypes:(TestMethod *)o
+{
+    return [o methodAcceptingInt:42 float:42 double:42.0 short:42
+	NSPoint:NSMakePoint(42, 42) NSRect:NSMakeRect(42, 42, 42, 42)
+	char:42];
+}
+
 - (BOOL)methodAcceptingIntPtr:(int *)ptr
 {
     BOOL ok = ptr[0] == 42;

Modified: MacRuby/branches/experimental/spec/macruby/fixtures/method.rb
===================================================================
--- MacRuby/branches/experimental/spec/macruby/fixtures/method.rb	2009-05-28 02:00:53 UTC (rev 1621)
+++ MacRuby/branches/experimental/spec/macruby/fixtures/method.rb	2009-05-28 08:06:03 UTC (rev 1622)
@@ -28,4 +28,33 @@
   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
+
+  def methodAcceptingSelf(a); super; end
+  def methodAcceptingSelfClass(a); super; end
+  def methodAcceptingNil(a); super; end
+  def methodAcceptingTrue(a); super; end
+  def methodAcceptingFalse(a); super; end
+  def methodAcceptingFixnum(a); super; end
+  def methodAcceptingChar(a); super; end
+  def methodAcceptingUnsignedChar(a); super; end
+  def methodAcceptingShort(a); super; end
+  def methodAcceptingUnsignedShort(a); super; end
+  def methodAcceptingInt(a); super; end
+  def methodAcceptingUnsignedInt(a); super; end
+  def methodAcceptingLong(a); super; end
+  def methodAcceptingUnsignedLong(a); super; end
+  def methodAcceptingTrueBOOL(a); super; end
+  def methodAcceptingFalseBOOL(a); super; end
+  def methodAcceptingSEL(a); super; end
+  def methodAcceptingSEL2(a); super; end
+  def methodAcceptingCharPtr(a); super; end
+  def methodAcceptingCharPtr2(a); super; end
+  def methodAcceptingFloat(a); super; end
+  def methodAcceptingDouble(a); super; end
+  def methodAcceptingNSPoint(a); super; end
+  def methodAcceptingNSSize(a); super; end
+  def methodAcceptingNSRect(a); super; end
+  def methodAcceptingNSRange(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-05-28 02:00:53 UTC (rev 1621)
+++ MacRuby/branches/experimental/spec/macruby/language/objc_method_spec.rb	2009-05-28 08:06:03 UTC (rev 1622)
@@ -516,4 +516,115 @@
     @o.methodReturningNSRange.should == NSRange.new(0, 42)
     TestMethodOverride.testMethodReturningNSRange(@o).should == 1
   end
+
+  it "can overwrite an Objective-C method accepting self" do
+    @o.methodAcceptingSelf(@o).should == 1
+    TestMethodOverride.testMethodAcceptingSelf(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting self class" do
+    @o.methodAcceptingSelfClass(@o.class).should == 1
+    TestMethodOverride.testMethodAcceptingSelfClass(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting nil" do
+    @o.methodAcceptingNil(nil).should == 1
+    TestMethodOverride.testMethodAcceptingNil(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting true/false (as id)" do
+    @o.methodAcceptingTrue(true).should == 1
+    @o.methodAcceptingFalse(false).should == 1
+    TestMethodOverride.testMethodAcceptingTrue(@o).should == 1
+    TestMethodOverride.testMethodAcceptingFalse(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting a fixnum (as id)" do
+    @o.methodAcceptingFixnum(42).should == 1
+    TestMethodOverride.testMethodAcceptingFixnum(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting 'char' or 'unsigned char'" do
+    @o.methodAcceptingChar(42).should == 1
+    @o.methodAcceptingUnsignedChar(42).should == 1
+    TestMethodOverride.testMethodAcceptingChar(@o).should == 1
+    TestMethodOverride.testMethodAcceptingUnsignedChar(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting 'short' or 'unsigned short'" do
+    @o.methodAcceptingShort(42).should == 1
+    @o.methodAcceptingUnsignedShort(42).should == 1
+    TestMethodOverride.testMethodAcceptingShort(@o).should == 1
+    TestMethodOverride.testMethodAcceptingUnsignedShort(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting 'int' or 'unsigned int'" do
+    @o.methodAcceptingInt(42).should == 1
+    @o.methodAcceptingUnsignedInt(42).should == 1
+    TestMethodOverride.testMethodAcceptingInt(@o).should == 1
+    TestMethodOverride.testMethodAcceptingUnsignedInt(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting 'long' or 'unsigned long'" do
+    @o.methodAcceptingLong(42).should == 1
+    @o.methodAcceptingUnsignedLong(42).should == 1
+    TestMethodOverride.testMethodAcceptingLong(@o).should == 1
+    TestMethodOverride.testMethodAcceptingUnsignedLong(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting true/false (as BOOL)" do
+    @o.methodAcceptingTrueBOOL(true).should == 1
+    @o.methodAcceptingFalseBOOL(false).should == 1
+    TestMethodOverride.testMethodAcceptingTrueBOOL(@o).should == 1
+    TestMethodOverride.testMethodAcceptingFalseBOOL(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting 'SEL'" do
+    @o.methodAcceptingSEL(:'foo:with:with:').should == 1
+    @o.methodAcceptingSEL2(nil).should == 1
+    TestMethodOverride.testMethodAcceptingSEL(@o).should == 1
+    TestMethodOverride.testMethodAcceptingSEL2(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting 'char *'" do
+    @o.methodAcceptingCharPtr('foo').should == 1
+    @o.methodAcceptingCharPtr2(nil).should == 1
+    TestMethodOverride.testMethodAcceptingCharPtr(@o).should == 1
+    TestMethodOverride.testMethodAcceptingCharPtr2(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting 'float'" do
+    @o.methodAcceptingFloat(3.1415).should == 1
+    TestMethodOverride.testMethodAcceptingFloat(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting 'double'" do
+    @o.methodAcceptingDouble(3.1415).should == 1
+    TestMethodOverride.testMethodAcceptingDouble(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting 'NSPoint'" do
+    @o.methodAcceptingNSPoint(NSPoint.new(1, 2)).should == 1
+    TestMethodOverride.testMethodAcceptingNSPoint(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting 'NSSize'" do
+    @o.methodAcceptingNSSize(NSSize.new(3, 4)).should == 1
+    TestMethodOverride.testMethodAcceptingNSSize(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting 'NSRect'" do
+    @o.methodAcceptingNSRect(NSRect.new(NSPoint.new(1, 2), NSSize.new(3, 4))).should == 1
+    TestMethodOverride.testMethodAcceptingNSRect(@o).should == 1
+  end
+
+  it "can overwrite an Objective-C method accepting 'NSRange'" do
+    @o.methodAcceptingNSRange(NSRange.new(0, 42)).should == 1
+    TestMethodOverride.testMethodAcceptingNSRange(@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
+  end
 end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090528/965ac727/attachment-0001.html>


More information about the macruby-changes mailing list