[macruby-changes] [1438] MacRuby/branches/experimental
source_changes at macosforge.org
source_changes at macosforge.org
Tue Apr 21 17:06:53 PDT 2009
Revision: 1438
http://trac.macosforge.org/projects/ruby/changeset/1438
Author: lsansonetti at apple.com
Date: 2009-04-21 17:06:53 -0700 (Tue, 21 Apr 2009)
Log Message:
-----------
some work on incoming c/objc arguments
Modified Paths:
--------------
MacRuby/branches/experimental/roxor.cpp
MacRuby/branches/experimental/spec/frozen/macruby/fixtures/method.bridgesupport
MacRuby/branches/experimental/spec/frozen/macruby/fixtures/method.m
MacRuby/branches/experimental/spec/frozen/macruby/method_spec.rb
Modified: MacRuby/branches/experimental/roxor.cpp
===================================================================
--- MacRuby/branches/experimental/roxor.cpp 2009-04-21 21:10:07 UTC (rev 1437)
+++ MacRuby/branches/experimental/roxor.cpp 2009-04-22 00:06:53 UTC (rev 1438)
@@ -4849,17 +4849,35 @@
extern "C"
void
-rb_vm_rval_to_ocval(VALUE val, void **ocval)
+rb_vm_rval_to_ocval(VALUE rval, id *ocval)
{
- *(id *)ocval = val == Qnil ? NULL : RB2OC(val);
+ *ocval = rval == Qnil ? NULL : RB2OC(rval);
}
extern "C"
void
-rb_vm_rval_to_ocsel(VALUE rval, void **ocval)
+rb_vm_rval_to_bool(VALUE rval, BOOL *ocval)
{
+ switch (TYPE(rval)) {
+ case T_FALSE:
+ case T_NIL:
+ *ocval = NO;
+ break;
+
+ default:
+ // All other types should be converted as true, to follow the Ruby
+ // semantics (where for example any integer is always true, even 0).
+ *ocval = YES;
+ break;
+ }
+}
+
+extern "C"
+void
+rb_vm_rval_to_ocsel(VALUE rval, SEL *ocval)
+{
if (NIL_P(rval)) {
- *(SEL *)ocval = NULL;
+ *ocval = NULL;
}
else {
const char *cstr;
@@ -4876,12 +4894,125 @@
default:
convert_error(_C_SEL, rval);
}
- *(SEL *)ocval = sel_registerName(cstr);
+ *ocval = sel_registerName(cstr);
}
}
+static inline long
+rval_to_long(VALUE rval)
+{
+ return NUM2LONG(rb_Integer(rval));
+}
+
+static inline long long
+rval_to_long_long(VALUE rval)
+{
+ return NUM2LL(rb_Integer(rval));
+}
+
+static inline double
+rval_to_double(VALUE rval)
+{
+ return RFLOAT_VALUE(rb_Float(rval));
+}
+
+extern "C"
+void
+rb_vm_rval_to_chr(VALUE rval, char *ocval)
+{
+ if (TYPE(rval) == T_STRING && RSTRING_LEN(rval) == 1) {
+ *ocval = (char)RSTRING_PTR(rval)[0];
+ }
+ else {
+ *ocval = (char)rval_to_long(rval);
+ }
+}
+
+extern "C"
+void
+rb_vm_rval_to_uchr(VALUE rval, unsigned char *ocval)
+{
+ if (TYPE(rval) == T_STRING && RSTRING_LEN(rval) == 1) {
+ *ocval = (unsigned char)RSTRING_PTR(rval)[0];
+ }
+ else {
+ *ocval = (unsigned char)rval_to_long(rval);
+ }
+}
+
+extern "C"
+void
+rb_vm_rval_to_short(VALUE rval, short *ocval)
+{
+ *ocval = (short)rval_to_long(rval);
+}
+
+extern "C"
+void
+rb_vm_rval_to_ushort(VALUE rval, unsigned short *ocval)
+{
+ *ocval = (unsigned short)rval_to_long(rval);
+}
+
+extern "C"
+void
+rb_vm_rval_to_int(VALUE rval, int *ocval)
+{
+ *ocval = (int)rval_to_long(rval);
+}
+
+extern "C"
+void
+rb_vm_rval_to_uint(VALUE rval, unsigned int *ocval)
+{
+ *ocval = (unsigned int)rval_to_long(rval);
+}
+
+extern "C"
+void
+rb_vm_rval_to_long(VALUE rval, long *ocval)
+{
+ *ocval = (long)rval_to_long(rval);
+}
+
+extern "C"
+void
+rb_vm_rval_to_ulong(VALUE rval, unsigned long *ocval)
+{
+ *ocval = (unsigned long)rval_to_long(rval);
+}
+
+extern "C"
+void
+rb_vm_rval_to_long_long(VALUE rval, long long *ocval)
+{
+ *ocval = (long long)rval_to_long_long(rval);
+}
+
+extern "C"
+void
+rb_vm_rval_to_ulong_long(VALUE rval, unsigned long long *ocval)
+{
+ *ocval = (unsigned long long)rval_to_long_long(rval);
+}
+
+extern "C"
+void
+rb_vm_rval_to_double(VALUE rval, double *ocval)
+{
+ *ocval = (double)rval_to_double(rval);
+}
+
+extern "C"
+void
+rb_vm_rval_to_float(VALUE rval, float *ocval)
+{
+ *ocval = (float)rval_to_double(rval);
+}
+
Value *
-RoxorCompiler::compile_conversion_to_c(const char *type, Value *val, Value *slot)
+RoxorCompiler::compile_conversion_to_c(const char *type, Value *val,
+ Value *slot)
{
const char *func_name = NULL;
@@ -4891,6 +5022,58 @@
func_name = "rb_vm_rval_to_ocval";
break;
+ case _C_BOOL:
+ func_name = "rb_vm_rval_to_bool";
+ break;
+
+ case _C_CHR:
+ func_name = "rb_vm_rval_to_chr";
+ break;
+
+ case _C_UCHR:
+ func_name = "rb_vm_rval_to_uchr";
+ break;
+
+ case _C_SHT:
+ func_name = "rb_vm_rval_to_short";
+ break;
+
+ case _C_USHT:
+ func_name = "rb_vm_rval_to_ushort";
+ break;
+
+ case _C_INT:
+ func_name = "rb_vm_rval_to_int";
+ break;
+
+ case _C_UINT:
+ func_name = "rb_vm_rval_to_uint";
+ break;
+
+ case _C_LNG:
+ func_name = "rb_vm_rval_to_long";
+ break;
+
+ case _C_ULNG:
+ func_name = "rb_vm_rval_to_ulong";
+ break;
+
+ case _C_LNG_LNG:
+ func_name = "rb_vm_rval_to_long_long";
+ break;
+
+ case _C_ULNG_LNG:
+ func_name = "rb_vm_rval_to_ulong_long";
+ break;
+
+ case _C_FLT:
+ func_name = "rb_vm_rval_to_float";
+ break;
+
+ case _C_DBL:
+ func_name = "rb_vm_rval_to_double";
+ break;
+
case _C_SEL:
func_name = "rb_vm_rval_to_ocsel";
break;
@@ -4948,6 +5131,13 @@
extern "C"
VALUE
+rb_vm_sel_to_rval(SEL sel)
+{
+ return sel == 0 ? Qnil : ID2SYM(rb_intern(sel_getName(sel)));
+}
+
+extern "C"
+VALUE
rb_vm_new_struct(VALUE klass, int argc, ...)
{
assert(argc > 0);
@@ -5051,6 +5241,10 @@
func_name = "rb_float_new";
break;
+ case _C_SEL:
+ func_name = "rb_vm_sel_to_rval";
+ break;
+
case _C_STRUCT_B:
rb_vm_bs_boxed_t *bs_boxed = GET_VM()->find_bs_struct(type);
if (bs_boxed != NULL) {
Modified: MacRuby/branches/experimental/spec/frozen/macruby/fixtures/method.bridgesupport
===================================================================
--- MacRuby/branches/experimental/spec/frozen/macruby/fixtures/method.bridgesupport 2009-04-21 21:10:07 UTC (rev 1437)
+++ MacRuby/branches/experimental/spec/frozen/macruby/fixtures/method.bridgesupport 2009-04-22 00:06:53 UTC (rev 1438)
@@ -8,5 +8,11 @@
<method selector='methodReturningNO'>
<retval type='B'/>
</method>
+ <method selector='methodAcceptingTrueBOOL:'>
+ <arg index='0' type='B'/>
+ </method>
+ <method selector='methodAcceptingFalseBOOL:'>
+ <arg index='0' type='B'/>
+ </method>
</class>
</signatures>
Modified: MacRuby/branches/experimental/spec/frozen/macruby/fixtures/method.m
===================================================================
--- MacRuby/branches/experimental/spec/frozen/macruby/fixtures/method.m 2009-04-21 21:10:07 UTC (rev 1437)
+++ MacRuby/branches/experimental/spec/frozen/macruby/fixtures/method.m 2009-04-22 00:06:53 UTC (rev 1438)
@@ -141,6 +141,16 @@
return 3.1415;
}
+- (SEL)methodReturningSEL
+{
+ return @selector(foo:with:with:);
+}
+
+- (SEL)methodReturningSEL2
+{
+ return 0;
+}
+
- (NSPoint)methodReturningNSPoint
{
return NSMakePoint(1, 2);
@@ -161,6 +171,106 @@
return NSMakeRange(0, 42);
}
+- (BOOL)methodAcceptingSelf:(id)obj
+{
+ return obj == self;
+}
+
+- (BOOL)methodAcceptingSelfClass:(id)obj
+{
+ return obj == [self class];
+}
+
+- (BOOL)methodAcceptingNil:(id)obj
+{
+ return obj == nil;
+}
+
+- (BOOL)methodAcceptingTrue:(id)obj
+{
+ return obj == (id)kCFBooleanTrue;
+}
+
+- (BOOL)methodAcceptingFalse:(id)obj
+{
+ return obj == (id)kCFBooleanFalse;
+}
+
+- (BOOL)methodAcceptingFixnum:(id)obj
+{
+ return [obj intValue] == 42;
+}
+
+- (BOOL)methodAcceptingChar:(char)c
+{
+ return c == 42;
+}
+
+- (BOOL)methodAcceptingUnsignedChar:(unsigned char)c
+{
+ return c == 42;
+}
+
+- (BOOL)methodAcceptingShort:(short)c
+{
+ return c == 42;
+}
+
+- (BOOL)methodAcceptingUnsignedShort:(unsigned short)c
+{
+ return c == 42;
+}
+
+- (BOOL)methodAcceptingInt:(int)c
+{
+ return c == 42;
+}
+
+- (BOOL)methodAcceptingUnsignedInt:(unsigned int)c
+{
+ return c == 42;
+}
+
+- (BOOL)methodAcceptingLong:(long)c
+{
+ return c == 42;
+}
+
+- (BOOL)methodAcceptingUnsignedLong:(unsigned long)c
+{
+ return c == 42;
+}
+
+- (BOOL)methodAcceptingTrueBOOL:(BOOL)b
+{
+ return b == YES;
+}
+
+- (BOOL)methodAcceptingFalseBOOL:(BOOL)b
+{
+ return b == NO;
+}
+
+- (BOOL)methodAcceptingSEL:(SEL)sel
+{
+ return sel == @selector(foo:with:with:);
+}
+
+- (BOOL)methodAcceptingSEL2:(SEL)sel
+{
+ return sel == 0;
+}
+
+- (BOOL)methodAcceptingFloat:(float)f
+{
+ return f > 3.1414 && f < 3.1416;
+}
+
+- (BOOL)methodAcceptingDouble:(double)d
+{
+ return d > 3.1414 && d < 3.1416;
+}
+
@end
void
Modified: MacRuby/branches/experimental/spec/frozen/macruby/method_spec.rb
===================================================================
--- MacRuby/branches/experimental/spec/frozen/macruby/method_spec.rb 2009-04-21 21:10:07 UTC (rev 1437)
+++ MacRuby/branches/experimental/spec/frozen/macruby/method_spec.rb 2009-04-22 00:06:53 UTC (rev 1438)
@@ -182,46 +182,35 @@
o.methodReturningNO.should == false
end
- it "returning 'char' returns a Fixnum in Ruby" do
+ it "returning 'char' or 'unsigned char' returns a Fixnum in Ruby" do
o = TestMethod.new
o.methodReturningChar.should == 42
o.methodReturningChar2.should == -42
+ o.methodReturningUnsignedChar.should == 42
end
- it "returning 'unsigned char' returns a Fixnum in Ruby" do
+ it "returning 'short' or 'unsigned short' returns a Fixnum in Ruby" do
o = TestMethod.new
- o.methodReturningUnsignedChar.should == 42
- end
-
- it "returning 'short' returns a Fixnum in Ruby" do
- o = TestMethod.new
o.methodReturningShort.should == 42
o.methodReturningShort2.should == -42
- end
-
- it "returning 'unsigned short' returns a Fixnum in Ruby" do
- o = TestMethod.new
o.methodReturningUnsignedShort.should == 42
end
- it "returning 'int' returns a Fixnum in Ruby" do
+ it "returning 'int' or 'unsigned int' returns a Fixnum in Ruby" do
o = TestMethod.new
o.methodReturningInt.should == 42
o.methodReturningInt2.should == -42
- end
-
- it "returning 'unsigned int' returns a Fixnum in Ruby" do
- o = TestMethod.new
o.methodReturningUnsignedInt.should == 42
end
- it "returning 'long' returns a Fixnum if possible in Ruby" do
+ it "returning 'long' or 'unsigned long' returns a Fixnum if possible in Ruby" do
o = TestMethod.new
o.methodReturningLong.should == 42
o.methodReturningLong2.should == -42
+ o.methodReturningUnsignedLong.should == 42
end
- it "returning 'long' returns a Bignum if it cannot fix in a Fixnum in Ruby" do
+ it "returning 'long' or 'unsigned long' returns a Bignum if it cannot fix in a Fixnum in Ruby" do
o = TestMethod.new
o.methodReturningLong3.should ==
(RUBY_ARCH == 'x86_64' ? 4611686018427387904 : 1073741824)
@@ -229,15 +218,6 @@
o.methodReturningLong4.should ==
(RUBY_ARCH == 'x86_64' ? -4611686018427387905 : -1073741825)
o.methodReturningLong4.class.should == Bignum
- end
-
- it "returning 'unsigned long' returns a Fixnum if possible in Ruby" do
- o = TestMethod.new
- o.methodReturningUnsignedLong.should == 42
- end
-
- it "returning 'unsigned long' returns a Bignum if it cannot fix in a Fixnum in Ruby" do
- o = TestMethod.new
o.methodReturningUnsignedLong2.should ==
(RUBY_ARCH == 'x86_64' ? 4611686018427387904 : 1073741824)
o.methodReturningUnsignedLong2.class.should == Bignum
@@ -255,6 +235,14 @@
o.methodReturningDouble.class.should == Float
end
+ it "returning 'SEL' returns a Symbol or nil in Ruby" do
+ o = TestMethod.new
+ o.methodReturningSEL.class.should == Symbol
+ o.methodReturningSEL.should == :'foo:with:with:'
+ o.methodReturningSEL2.class.should == NilClass
+ o.methodReturningSEL2.should == nil
+ end
+
it "returning 'NSPoint' returns an NSPoint boxed object in Ruby" do
o = TestMethod.new
b = o.methodReturningNSPoint
@@ -296,4 +284,130 @@
b.length.class.should == Fixnum
b.length.should == 42
end
+
+ it "accepting the receiver as 'id' should receive the exact same object" do
+ o = TestMethod.new
+ o.methodAcceptingSelf(o).should == 1
+ end
+
+ it "accepting the receiver's class as 'id' should receive the exact same object" do
+ o = TestMethod.new
+ o.methodAcceptingSelfClass(o.class).should == 1
+ end
+
+ it "accepting 'nil' as 'id' should receive Objective-C's nil" do
+ o = TestMethod.new
+ o.methodAcceptingNil(nil).should == 1
+ end
+
+ it "accepting 'true' as 'id; should receive CF's kCFBooleanTrue" do
+ o = TestMethod.new
+ o.methodAcceptingTrue(true).should == 1
+ end
+
+ it "accepting 'false' as 'id' should receive CF's kCFBooleanFalse" do
+ o = TestMethod.new
+ o.methodAcceptingFalse(false).should == 1
+ end
+
+ it "accepting a Fixnum as 'id' should receive a Fixnum boxed object" do
+ o = TestMethod.new
+ o.methodAcceptingFixnum(42).should == 1
+ end
+
+ it "accepting nil or false as 'BOOL' should receive NO, any other object should receive YES" do
+ o = TestMethod.new
+ o.methodAcceptingFalseBOOL(nil).should == 1
+ o.methodAcceptingFalseBOOL(false).should == 1
+
+ o.methodAcceptingTrueBOOL(true).should == 1
+ o.methodAcceptingTrueBOOL(0).should == 1
+ o.methodAcceptingTrueBOOL(123).should == 1
+ o.methodAcceptingTrueBOOL('foo').should == 1
+ o.methodAcceptingTrueBOOL(Object.new).should == 1
+ end
+
+ it "accepting a Fixnum-compatible object as 'char', 'unsigned char', 'short', 'unsigned short', 'int', 'unsigned int', 'long', 'unsigned long' should receive the converted data, or raise an exception" do
+ o = TestMethod.new
+ o.methodAcceptingChar(42).should == 1
+ o.methodAcceptingUnsignedChar(42).should == 1
+ o.methodAcceptingShort(42).should == 1
+ o.methodAcceptingUnsignedShort(42).should == 1
+ o.methodAcceptingInt(42).should == 1
+ o.methodAcceptingUnsignedInt(42).should == 1
+ o.methodAcceptingLong(42).should == 1
+ o.methodAcceptingUnsignedLong(42).should == 1
+
+ o.methodAcceptingChar(42.0).should == 1
+ o.methodAcceptingUnsignedChar(42.0).should == 1
+ o.methodAcceptingShort(42.0).should == 1
+ o.methodAcceptingUnsignedShort(42.0).should == 1
+ o.methodAcceptingInt(42.0).should == 1
+ o.methodAcceptingUnsignedInt(42.0).should == 1
+ o.methodAcceptingLong(42.0).should == 1
+ o.methodAcceptingUnsignedLong(42.0).should == 1
+
+ o2 = Object.new
+ def o2.to_i; 42; end
+
+ o.methodAcceptingChar(o2).should == 1
+ o.methodAcceptingUnsignedChar(o2).should == 1
+ o.methodAcceptingShort(o2).should == 1
+ o.methodAcceptingUnsignedShort(o2).should == 1
+ o.methodAcceptingInt(o2).should == 1
+ o.methodAcceptingUnsignedInt(o2).should == 1
+ o.methodAcceptingLong(o2).should == 1
+ o.methodAcceptingUnsignedLong(o2).should == 1
+
+ lambda { o.methodAcceptingChar(nil) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingUnsignedChar(nil) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingShort(nil) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingUnsignedShort(nil) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingInt(nil) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingUnsignedInt(nil) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingLong(nil) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingUnsignedLong(nil) }.should raise_error(TypeError)
+
+ lambda { o.methodAcceptingChar(Object.new) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingUnsignedChar(Object.new) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingShort(Object.new) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingUnsignedShort(Object.new) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingInt(Object.new) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingUnsignedInt(Object.new) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingLong(Object.new) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingUnsignedLong(Object.new) }.should raise_error(TypeError)
+ end
+
+ it "accepting a one-character string as 'char' or 'unsigned char' should receive the first character" do
+ o = TestMethod.new
+ o.methodAcceptingChar('*').should == 1
+ o.methodAcceptingUnsignedChar('*').should == 1
+ end
+
+ it "accepting a String, Symbol or nil as 'SEL' should receive the appropriate selector" do
+ o = TestMethod.new
+ o.methodAcceptingSEL(:'foo:with:with:').should == 1
+ o.methodAcceptingSEL('foo:with:with:').should == 1
+ o.methodAcceptingSEL2(nil).should == 1
+
+ lambda { o.methodAcceptingSEL(123) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingSEL(Object.new) }.should raise_error(TypeError)
+ end
+
+ it "accepting a Float-compatible object as 'float' or 'double' should receive the appropriate data" do
+ o = TestMethod.new
+ o.methodAcceptingFloat(3.1415).should == 1
+ o.methodAcceptingDouble(3.1415).should == 1
+
+ o2 = Object.new
+ def o2.to_f; 3.1415; end
+
+ o.methodAcceptingFloat(o2).should == 1
+ o.methodAcceptingDouble(o2).should == 1
+
+ lambda { o.methodAcceptingFloat(nil) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingDouble(nil) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingFloat(Object.new) }.should raise_error(TypeError)
+ lambda { o.methodAcceptingDouble(Object.new) }.should raise_error(TypeError)
+ end
end
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090421/14bfc847/attachment-0001.html>
More information about the macruby-changes
mailing list