[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