[macruby-changes] [373] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Sat Jul 12 23:02:07 PDT 2008


Revision: 373
          http://trac.macosforge.org/projects/ruby/changeset/373
Author:   lsansonetti at apple.com
Date:     2008-07-12 23:02:07 -0700 (Sat, 12 Jul 2008)
Log Message:
-----------
Numeric is now a subclass of NSNumber

Modified Paths:
--------------
    MacRuby/trunk/numeric.c
    MacRuby/trunk/objc.m

Modified: MacRuby/trunk/numeric.c
===================================================================
--- MacRuby/trunk/numeric.c	2008-07-11 12:34:50 UTC (rev 372)
+++ MacRuby/trunk/numeric.c	2008-07-13 06:02:07 UTC (rev 373)
@@ -3098,6 +3098,78 @@
     return Qtrue;
 }
 
+#if WITH_OBJC
+static const char *
+imp_rb_float_objCType(void *rcv, SEL sel)
+{
+    return "d";
+}
+
+static const char *
+imp_rb_integer_objCType(void *rcv, SEL sel)
+{
+    return "q";
+}
+
+static void
+imp_rb_float_getValue(void *rcv, SEL sel, void *buffer)
+{
+    double v = RFLOAT_VALUE(rcv);
+    *(double *)buffer = v;
+}
+
+static void
+imp_rb_integer_getValue(void *rcv, SEL sel, void *buffer)
+{
+    long long v = NUM2LL(rcv);
+    *(long long *)buffer = v;
+}
+
+static double
+imp_rb_float_doubleValue(void *rcv, SEL sel)
+{
+    return RFLOAT_VALUE(rcv);
+}
+
+static long long
+imp_rb_integer_longLongValue(void *rcv, SEL sel)
+{
+    return NUM2LL(rcv);
+}
+
+static inline void
+rb_objc_install_method(Class klass, SEL sel, IMP imp)
+{
+    Method method = class_getInstanceMethod(klass, sel);
+    assert(method != NULL);
+    assert(class_addMethod(klass, sel, imp, method_getTypeEncoding(method)));
+}
+
+static void
+rb_install_nsnumber_float_primitives(void)
+{
+    Class klass = RCLASS_OCID(rb_cFloat);
+    rb_objc_install_method(klass, sel_registerName("objCType"),
+	    (IMP)imp_rb_float_objCType);
+    rb_objc_install_method(klass, sel_registerName("getValue:"), 
+	    (IMP)imp_rb_float_getValue);
+    rb_objc_install_method(klass, sel_registerName("doubleValue"), 
+	    (IMP)imp_rb_float_doubleValue);
+}
+
+static void
+rb_install_nsnumber_integer_primitives(void)
+{
+    Class klass = RCLASS_OCID(rb_cNumeric);
+    rb_objc_install_method(klass, sel_registerName("objCType"),
+	    (IMP)imp_rb_integer_objCType);
+    rb_objc_install_method(klass, sel_registerName("getValue:"), 
+	    (IMP)imp_rb_integer_getValue);
+    rb_objc_install_method(klass, sel_registerName("longLongValue"), 
+	    (IMP)imp_rb_integer_longLongValue);
+}
+#endif
+
 void
 Init_Numeric(void)
 {
@@ -3117,7 +3189,12 @@
 
     rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eStandardError);
     rb_eFloatDomainError = rb_define_class("FloatDomainError", rb_eRangeError);
+#if WITH_OBJC
+    rb_cNumeric = rb_define_class("Numeric",
+        rb_objc_import_class((void*)objc_getClass("NSNumber")));
+#else
     rb_cNumeric = rb_define_class("Numeric", rb_cObject);
+#endif
 
     rb_define_method(rb_cNumeric, "singleton_method_added", num_sadded, 1);
     rb_include_module(rb_cNumeric, rb_mComparable);
@@ -3275,4 +3352,9 @@
     rb_define_method(rb_cFloat, "nan?",      flo_is_nan_p, 0);
     rb_define_method(rb_cFloat, "infinite?", flo_is_infinite_p, 0);
     rb_define_method(rb_cFloat, "finite?",   flo_is_finite_p, 0);
+
+#if WITH_OBJC
+    rb_install_nsnumber_integer_primitives();
+    rb_install_nsnumber_float_primitives();
+#endif
 }

Modified: MacRuby/trunk/objc.m
===================================================================
--- MacRuby/trunk/objc.m	2008-07-11 12:34:50 UTC (rev 372)
+++ MacRuby/trunk/objc.m	2008-07-13 06:02:07 UTC (rev 373)
@@ -401,88 +401,54 @@
     return NULL;
 }
 
-static bool
+bool
 rb_objc_rval_to_ocid(VALUE rval, void **ocval, bool force_nsnil)
 {
-    if (!rb_special_const_p(rval) && rb_objc_is_non_native(rval)) {
-	*(id *)ocval = (id)rval;
-	return true;
-    }
-
-    switch (TYPE(rval)) {
-	case T_STRING:
-	case T_ARRAY:
-	case T_HASH:
-	case T_OBJECT:
-	    *(id *)ocval = (id)rval;
-	    return true;
-
-	case T_CLASS:
-	case T_MODULE:
-	    *(id *)ocval = (id)RCLASS_OCID(rval);
-	    return true;
-
-	case T_NIL:
-	    if (force_nsnil) {
-		static id snull = nil;
-		if (snull == nil)
-		    snull = [NSNull null];
-		*(id *)ocval = snull;
-	    }
-	    else {
-		*(id *)ocval = NULL;
-	    }
-	    return true;
-
-	case T_TRUE:
-	case T_FALSE:
-	{
-	    char v = RTEST(rval);
-	    *(id *)ocval = (id)CFNumberCreate(NULL, kCFNumberCharType, &v);
-	    CFMakeCollectable(*(id *)ocval);
-	    return true;
+    if (SPECIAL_CONST_P(rval)) {
+	if (rval == Qtrue) {
+	    *(id *)ocval = (id)kCFBooleanTrue;
 	}
-
-	case T_FLOAT:
-	{
-	    double v = RFLOAT_VALUE(rval);
-	    *(id *)ocval = (id)CFNumberCreate(NULL, kCFNumberDoubleType, &v);
-	    CFMakeCollectable(*(id *)ocval);
-	    return true;
-	}	
-
-	case T_FIXNUM:
-	case T_BIGNUM:
-	{
-	    if (FIXNUM_P(rval)) {
-		long v = FIX2LONG(rval);
-		*(id *)ocval = (id)CFNumberCreate(NULL, kCFNumberLongType, &v);
+	else if (rval == Qfalse) {
+	    *(id *)ocval = (id)kCFBooleanFalse;
+	}
+	else if (rval == Qnil) {
+	    *(id *)ocval = force_nsnil ? (id)kCFNull : nil;
+	}
+	else if (SYMBOL_P(rval)) {
+	    *(id *)ocval = (id)rb_id2str(SYM2ID(rval));
+	}
+	else if (FIXNUM_P(rval)) {
+#define FIXNUM_CFNUMBER_CACHE_SIZE 2000
+	    static void *fixnum_cfnumber_cache[FIXNUM_CFNUMBER_CACHE_SIZE];
+	    static bool fixnum_cfnumber_cache_init = false;
+	    long v = FIX2LONG(rval);
+	    CFNumberRef number;
+	    if (!fixnum_cfnumber_cache_init) {
+		memset(fixnum_cfnumber_cache, 0, sizeof(void *) * FIXNUM_CFNUMBER_CACHE_SIZE);
+		fixnum_cfnumber_cache_init = true;
 	    }
+	    /* cache -500..1500 */
+	    if (v >= -500 && v < 1500) {
+		number = fixnum_cfnumber_cache[v+500];
+		if (number == NULL) {
+		    number = CFNumberCreate(NULL, kCFNumberLongType, &v);
+		    fixnum_cfnumber_cache[v+500] = (void *)number;
+		}
+	    }
 	    else {
-#if HAVE_LONG_LONG
-		long long v = NUM2LL(rval);
-		*(id *)ocval = 
-		    (id)CFNumberCreate(NULL, kCFNumberLongLongType, &v);
-#else
-		long v = NUM2LONG(rval);
-		*(id *)ocval = (id)CFNumberCreate(NULL, kCFNumberLongType, &v);
-#endif
+		number = CFNumberCreate(NULL, kCFNumberLongType, &v);
+		CFMakeCollectable(number);	
 	    }
-	    CFMakeCollectable(*(id *)ocval);
-	    return true;
+	    *(id *)ocval = (id)number;
 	}
-
-	case T_SYMBOL:
-	{
-	    ID name = SYM2ID(rval);
-	    *(id *)ocval = (id)CFStringCreateWithCString(NULL, rb_id2name(name),
-		kCFStringEncodingASCII); /* XXX this is temporary */
-	    CFMakeCollectable(*(id *)ocval);
-	    return true;
-	}
     }
-
-    return false;
+    else if (class_isMetaClass(*(Class *)rval)) {
+	*(id *)ocval = (id)RCLASS_OCID(rval);
+    }
+    else {
+	*(id *)ocval = (id)rval;
+    }
+    return true;
 }
 
 static bool
@@ -749,7 +715,7 @@
     if (st_lookup(bs_cftypes, (st_data_t)octype, NULL))
 	octype = "@";
 
-    if (*octype != _C_BOOL) {
+    if (*octype != _C_BOOL && *octype != _C_ID) {
 	if (rval == Qtrue)
 	    rval = INT2FIX(1);
 	else if (rval == Qfalse)
@@ -998,6 +964,14 @@
 	    *rbval = UINT2NUM(*(unsigned long *)ocval);
 	    break;
 
+	case _C_LNG_LNG:
+	    *rbval = LL2NUM(*(long long *)ocval);
+	    break;
+
+	case _C_ULNG_LNG:
+	    *rbval = ULL2NUM(*(unsigned long long *)ocval);
+	    break;
+
 	case _C_FLT:
 	    *rbval = rb_float_new((double)(*(float *)ocval));
 	    break;
@@ -1288,18 +1262,18 @@
 	}
 	ctx->selector = sel_registerName(selname);
 
-	ctx->bs_method = rb_bs_find_method(*(Class *)rcv, ctx->selector);
-	ctx->method = class_getInstanceMethod(*(Class *)rcv, ctx->selector); 
-	assert(ctx->method != NULL);
-	ctx->cif = NULL;
-	ctx->imp = NULL;
-	ctx->klass = klass;
+	ctx->bs_method = rb_bs_find_method(*(Class *)ocrcv, ctx->selector);
 	GC_WB(&rb_current_cfunc_node->u3.value, ctx);
     }
     else {
 	ctx = (struct objc_ruby_closure_context *)
 	    rb_current_cfunc_node->u3.value;
     }
+    ctx->method = class_getInstanceMethod(*(Class *)ocrcv, ctx->selector); 
+    assert(ctx->method != NULL);
+    ctx->cif = NULL;
+    ctx->imp = NULL;
+    ctx->klass = klass;
 
     if (super_call) {
 	Class sklass = klass;
@@ -2624,9 +2598,9 @@
 
     /* Boxed */
     klass = RCLASS_OCID(rb_cBoxed);
-    rb_objc_override_method(klass, @selector(objCType), 
+    rb_objc_install_method(klass, @selector(objCType), 
 	(IMP)imp_rb_boxed_objCType);
-    rb_objc_override_method(klass, @selector(getValue:), 
+    rb_objc_install_method(klass, @selector(getValue:), 
 	(IMP)imp_rb_boxed_getValue);
 }
 
@@ -2815,8 +2789,9 @@
 
 	if (!class_addMethod(RCLASS_OCID(recv), sel_registerName(buf), 
 			     (IMP)rb_objc_ib_outlet_imp, "v@:@"))
-	    rb_raise(rb_eArgError, "can't register `%s' as an IB outlet",
-		     symname);
+	    rb_raise(rb_eArgError, 
+		     "can't register `%s' (method %s) as an IB outlet",
+		     symname, buf);
     }
     return recv;
 }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macruby-changes/attachments/20080712/a9c14efd/attachment.html 


More information about the macruby-changes mailing list