[macruby-changes] [2394] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Aug 26 18:51:00 PDT 2009


Revision: 2394
          http://trac.macosforge.org/projects/ruby/changeset/2394
Author:   lsansonetti at apple.com
Date:     2009-08-26 18:51:00 -0700 (Wed, 26 Aug 2009)
Log Message:
-----------
optimized rb_num_coerce_bin() calls + optimized complex.c to use the new runtime primitives

Modified Paths:
--------------
    MacRuby/trunk/TODO
    MacRuby/trunk/complex.c
    MacRuby/trunk/id.c
    MacRuby/trunk/id.h
    MacRuby/trunk/include/ruby/intern.h
    MacRuby/trunk/numeric.c
    MacRuby/trunk/string.c

Modified: MacRuby/trunk/TODO
===================================================================
--- MacRuby/trunk/TODO	2009-08-26 21:43:03 UTC (rev 2393)
+++ MacRuby/trunk/TODO	2009-08-27 01:51:00 UTC (rev 2394)
@@ -15,8 +15,10 @@
 [ ] merge stdlib from 1.9.2 trunk
 [ ] rubygems should work (modulo C extensions)
 [ ] most language/core/library specs should run (modulo a very few exceptions)
-[/] port all rb_define_method() calls to rb_objc_define_method().
+[/] port all rb_define_method() calls to rb_objc_define_method()
 [/] port all rb_funcall() calls to rb_vm_call()
+[/] port all rb_num_coerce_bin() calls to rb_objc_num_coerce_bin()
+[/] port all rb_obj_respond_to() calls to rb_vm_respond_to()
 
 For 0.5 (tentative):
 

Modified: MacRuby/trunk/complex.c
===================================================================
--- MacRuby/trunk/complex.c	2009-08-26 21:43:03 UTC (rev 2393)
+++ MacRuby/trunk/complex.c	2009-08-27 01:51:00 UTC (rev 2394)
@@ -8,6 +8,9 @@
 #include "ruby.h"
 #include <math.h>
 #include "ruby/re.h"
+#include "ruby/node.h"
+#include "vm.h"
+#include "id.h"
 
 #define NDEBUG
 #include <assert.h>
@@ -18,10 +21,10 @@
 
 VALUE rb_cComplex;
 
-static ID id_abs, id_abs2, id_arg, id_cmp, id_conj, id_convert,
-    id_denominator, id_divmod, id_eqeq_p, id_expt, id_fdiv,  id_floor,
-    id_idiv, id_imag, id_inspect, id_negate, id_numerator, id_quo,
-    id_real, id_real_p, id_to_f, id_to_i, id_to_r, id_to_s;
+static SEL sel_abs, sel_abs2, sel_arg, sel_cmp, sel_conj, sel_convert,
+    sel_denominator, sel_divmod, sel_expt, sel_fdiv,  sel_floor,
+    sel_idiv, sel_imag, sel_inspect, sel_negate, sel_numerator, sel_quo,
+    sel_real, sel_real_p, sel_to_f, sel_to_i, sel_to_r, sel_to_s;
 
 #define f_boolcast(x) ((x) ? Qtrue : Qfalse)
 
@@ -29,35 +32,36 @@
 inline static VALUE \
 f_##n(VALUE x, VALUE y)\
 {\
-    return rb_funcall(x, op, 1, y);\
+    return rb_vm_call(x, op, 1, &y, false);\
 }
 
 #define fun1(n) \
 inline static VALUE \
 f_##n(VALUE x)\
 {\
-    return rb_funcall(x, id_##n, 0);\
+    return rb_vm_call(x, sel_##n, 0, NULL, false);\
 }
 
 #define fun2(n) \
 inline static VALUE \
 f_##n(VALUE x, VALUE y)\
 {\
-    return rb_funcall(x, id_##n, 1, y);\
+    return rb_vm_call(x, sel_##n, 1, &y, false);\
 }
 
 #define math1(n) \
 inline static VALUE \
 m_##n(VALUE x)\
 {\
-    return rb_funcall(rb_mMath, id_##n, 1, x);\
+    return rb_vm_call(rb_mMath, sel_##n, 1, &x, false);\
 }
 
 #define math2(n) \
 inline static VALUE \
 m_##n(VALUE x, VALUE y)\
 {\
-    return rb_funcall(rb_mMath, id_##n, 2, x, y);\
+    VALUE args[2]; args[0] = x; args[1] = y;\
+    return rb_vm_call(rb_mMath, sel_##n, 2, args, false);\
 }
 
 #define PRESERVE_SIGNEDZERO
@@ -71,7 +75,7 @@
     else if (FIXNUM_P(x) && FIX2LONG(x) == 0)
 	return y;
 #endif
-    return rb_funcall(x, '+', 1, y);
+    return rb_vm_call(x, selPLUS, 1, &y, false);
 }
 
 inline static VALUE
@@ -79,13 +83,15 @@
 {
     if (FIXNUM_P(x) && FIXNUM_P(y)) {
 	long c = FIX2LONG(x) - FIX2LONG(y);
-	if (c > 0)
+	if (c > 0) {
 	    c = 1;
-	else if (c < 0)
+	}
+	else if (c < 0) {
 	    c = -1;
+	}
 	return INT2FIX(c);
     }
-    return rb_funcall(x, id_cmp, 1, y);
+    return rb_vm_call(x, selCmp, 1, &y, false);
 }
 
 inline static VALUE
@@ -93,7 +99,7 @@
 {
     if (FIXNUM_P(y) && FIX2LONG(y) == 1)
 	return x;
-    return rb_funcall(x, '/', 1, y);
+    return rb_vm_call(x, selDIV, 1, &y, false);
 }
 
 inline static VALUE
@@ -101,7 +107,7 @@
 {
     if (FIXNUM_P(x) && FIXNUM_P(y))
 	return f_boolcast(FIX2LONG(x) > FIX2LONG(y));
-    return rb_funcall(x, '>', 1, y);
+    return rb_vm_call(x, selGT, 1, &y, false);
 }
 
 inline static VALUE
@@ -109,10 +115,10 @@
 {
     if (FIXNUM_P(x) && FIXNUM_P(y))
 	return f_boolcast(FIX2LONG(x) < FIX2LONG(y));
-    return rb_funcall(x, '<', 1, y);
+    return rb_vm_call(x, selLT, 1, &y, false);
 }
 
-binop(mod, '%')
+binop(mod, selMOD)
 
 inline static VALUE
 f_mul(VALUE x, VALUE y)
@@ -137,7 +143,7 @@
 	    return y;
     }
 #endif
-    return rb_funcall(x, '*', 1, y);
+    return rb_vm_call(x, selMULT, 1, &y, false);
 }
 
 inline static VALUE
@@ -147,7 +153,7 @@
     if (FIXNUM_P(y) && FIX2LONG(y) == 0)
 	return x;
 #endif
-    return rb_funcall(x, '-', 1, y);
+    return rb_vm_call(x, selMINUS, 1, &y, false);
 }
 
 fun1(abs)
@@ -173,9 +179,10 @@
 inline static VALUE
 f_eqeq_p(VALUE x, VALUE y)
 {
-    if (FIXNUM_P(x) && FIXNUM_P(y))
+    if (FIXNUM_P(x) && FIXNUM_P(y)) {
 	return f_boolcast(FIX2LONG(x) == FIX2LONG(y));
-    return rb_funcall(x, id_eqeq_p, 1, y);
+    }
+    return rb_vm_call(x, selEq, 1, &y, false);
 }
 
 fun2(expt)
@@ -186,9 +193,11 @@
 inline static VALUE
 f_negative_p(VALUE x)
 {
-    if (FIXNUM_P(x))
+    if (FIXNUM_P(x)) {
 	return f_boolcast(FIX2LONG(x) < 0);
-    return rb_funcall(x, '<', 1, ZERO);
+    }
+    VALUE v = ZERO;
+    return rb_vm_call(x, selLT, 1, &v, false);
 }
 
 #define f_positive_p(x) (!f_negative_p(x))
@@ -208,7 +217,8 @@
 	  return f_boolcast(FIXNUM_P(num) && FIX2LONG(num) == 0);
       }
     }
-    return rb_funcall(x, id_eqeq_p, 1, ZERO);
+    VALUE v = ZERO;
+    return rb_vm_call(x, selEq, 1, &v, false);
 }
 
 #define f_nonzero_p(x) (!f_zero_p(x))
@@ -230,7 +240,8 @@
 			    FIXNUM_P(den) && FIX2LONG(den) == 1);
       }
     }
-    return rb_funcall(x, id_eqeq_p, 1, ONE);
+    VALUE v = ONE;
+    return rb_vm_call(x, selEq, 1, &v, false);
 }
 
 inline static VALUE
@@ -469,7 +480,7 @@
 static VALUE
 nucomp_f_complex(VALUE klass, SEL sel, int argc, VALUE *argv)
 {
-    return rb_funcall2(rb_cComplex, id_convert, argc, argv);
+    return rb_vm_call(rb_cComplex, sel_convert, argc, argv, false);
 }
 
 #define imp1(n) \
@@ -639,7 +650,7 @@
 
 inline static VALUE
 f_addsub(VALUE self, VALUE other,
-	 VALUE (*func)(VALUE, VALUE), ID id)
+	 VALUE (*func)(VALUE, VALUE), SEL op)
 {
     if (k_complex_p(other)) {
 	VALUE real, imag;
@@ -657,7 +668,7 @@
 	return f_complex_new2(CLASS_OF(self),
 			      (*func)(dat->real, other), dat->imag);
     }
-    return rb_num_coerce_bin(self, other, id);
+    return rb_objc_num_coerce_bin(self, other, op);
 }
 
 /*
@@ -669,7 +680,7 @@
 static VALUE
 nucomp_add(VALUE self, SEL sel, VALUE other)
 {
-    return f_addsub(self, other, f_add, '+');
+    return f_addsub(self, other, f_add, selPLUS);
 }
 
 /*
@@ -681,7 +692,7 @@
 static VALUE
 nucomp_sub(VALUE self, SEL sel, VALUE other)
 {
-    return f_addsub(self, other, f_sub, '-');
+    return f_addsub(self, other, f_sub, selMINUS);
 }
 
 /*
@@ -712,12 +723,12 @@
 			      f_mul(dat->real, other),
 			      f_mul(dat->imag, other));
     }
-    return rb_num_coerce_bin(self, other, '*');
+    return rb_objc_num_coerce_bin(self, other, selMULT);
 }
 
 inline static VALUE
 f_divide(VALUE self, VALUE other,
-	 VALUE (*func)(VALUE, VALUE), ID id)
+	 VALUE (*func)(VALUE, VALUE), SEL op)
 {
     if (k_complex_p(other)) {
 	int flo;
@@ -764,7 +775,7 @@
 			      (*func)(dat->real, other),
 			      (*func)(dat->imag, other));
     }
-    return rb_num_coerce_bin(self, other, id);
+    return rb_objc_num_coerce_bin(self, other, op);
 }
 
 #define rb_raise_zerodiv() rb_raise(rb_eZeroDivError, "divided by 0")
@@ -787,7 +798,7 @@
     if (f_zero_p(other)) {
 	rb_raise_zerodiv();
     }
-    return f_divide(self, other, f_quo, id_quo);
+    return f_divide(self, other, f_quo, sel_quo);
 }
 
 #define nucomp_quo nucomp_div
@@ -805,7 +816,7 @@
 static VALUE
 nucomp_fdiv(VALUE self, SEL sel, VALUE other)
 {
-    return f_divide(self, other, f_fdiv, id_fdiv);
+    return f_divide(self, other, f_fdiv, sel_fdiv);
 }
 
 static VALUE
@@ -930,7 +941,7 @@
 	return f_complex_polar(CLASS_OF(self), f_expt(r, other),
 			       f_mul(theta, other));
     }
-    return rb_num_coerce_bin(self, other, id_expt);
+    return rb_objc_num_coerce_bin(self, other, sel_expt);
 }
 
 /*
@@ -1848,30 +1859,29 @@
 {
     assert(fprintf(stderr, "assert() is now active\n"));
 
-    id_abs = rb_intern("abs");
-    id_abs2 = rb_intern("abs2");
-    id_arg = rb_intern("arg");
-    id_cmp = rb_intern("<=>");
-    id_conj = rb_intern("conj");
-    id_convert = rb_intern("convert");
-    id_denominator = rb_intern("denominator");
-    id_divmod = rb_intern("divmod");
-    id_eqeq_p = rb_intern("==");
-    id_expt = rb_intern("**");
-    id_fdiv = rb_intern("fdiv");
-    id_floor = rb_intern("floor");
-    id_idiv = rb_intern("div");
-    id_imag = rb_intern("imag");
-    id_inspect = rb_intern("inspect");
-    id_negate = rb_intern("-@");
-    id_numerator = rb_intern("numerator");
-    id_quo = rb_intern("quo");
-    id_real = rb_intern("real");
-    id_real_p = rb_intern("real?");
-    id_to_f = rb_intern("to_f");
-    id_to_i = rb_intern("to_i");
-    id_to_r = rb_intern("to_r");
-    id_to_s = rb_intern("to_s");
+    sel_abs = sel_registerName("abs");
+    sel_abs2 = sel_registerName("abs2");
+    sel_arg = sel_registerName("arg");
+    sel_cmp = sel_registerName("<=>");
+    sel_conj = sel_registerName("conj");
+    sel_convert = sel_registerName("convert");
+    sel_denominator = sel_registerName("denominator");
+    sel_divmod = sel_registerName("divmod:");
+    sel_expt = sel_registerName("**:");
+    sel_fdiv = sel_registerName("fdiv:");
+    sel_floor = sel_registerName("floor");
+    sel_idiv = sel_registerName("div:");
+    sel_imag = sel_registerName("imag");
+    sel_inspect = sel_registerName("inspect");
+    sel_negate = sel_registerName("-@");
+    sel_numerator = sel_registerName("numerator");
+    sel_quo = sel_registerName("quo:");
+    sel_real = sel_registerName("real");
+    sel_real_p = sel_registerName("real?");
+    sel_to_f = sel_registerName("to_f");
+    sel_to_i = sel_registerName("to_i");
+    sel_to_r = sel_registerName("to_r");
+    sel_to_s = sel_registerName("to_s");
 
     rb_cComplex = rb_define_class("Complex", rb_cNumeric);
 

Modified: MacRuby/trunk/id.c
===================================================================
--- MacRuby/trunk/id.c	2009-08-26 21:43:03 UTC (rev 2393)
+++ MacRuby/trunk/id.c	2009-08-27 01:51:00 UTC (rev 2394)
@@ -50,6 +50,7 @@
     selMOD = sel_registerName("%:");
     selEq = sel_registerName("==:");
     selNeq = sel_registerName("!=:");
+    selCmp = sel_registerName("<=>:");
     selLT = sel_registerName("<:");
     selLE = sel_registerName("<=:");
     selGT = sel_registerName(">:");

Modified: MacRuby/trunk/id.h
===================================================================
--- MacRuby/trunk/id.h	2009-08-26 21:43:03 UTC (rev 2393)
+++ MacRuby/trunk/id.h	2009-08-27 01:51:00 UTC (rev 2394)
@@ -60,6 +60,7 @@
 extern SEL selMOD;
 extern SEL selEq;
 extern SEL selNeq;
+extern SEL selCmp;
 extern SEL selLT;
 extern SEL selLE;
 extern SEL selGT;

Modified: MacRuby/trunk/include/ruby/intern.h
===================================================================
--- MacRuby/trunk/include/ruby/intern.h	2009-08-26 21:43:03 UTC (rev 2393)
+++ MacRuby/trunk/include/ruby/intern.h	2009-08-27 01:51:00 UTC (rev 2394)
@@ -410,7 +410,9 @@
 /* numeric.c */
 void rb_num_zerodiv(void);
 VALUE rb_num_coerce_bin(VALUE, VALUE, ID);
+VALUE rb_objc_num_coerce_bin(VALUE x, VALUE Y, SEL sel);
 VALUE rb_num_coerce_cmp(VALUE, VALUE, ID);
+VALUE rb_objc_num_coerce_cmp(VALUE, VALUE, SEL sel);
 VALUE rb_num_coerce_relop(VALUE, VALUE, SEL);
 VALUE rb_float_new(double);
 VALUE rb_num2fix(VALUE);

Modified: MacRuby/trunk/numeric.c
===================================================================
--- MacRuby/trunk/numeric.c	2009-08-26 21:43:03 UTC (rev 2393)
+++ MacRuby/trunk/numeric.c	2009-08-27 01:51:00 UTC (rev 2394)
@@ -81,7 +81,7 @@
 }
 #endif
 
-static SEL sel_coerce, selDiv;
+static SEL sel_coerce, selDiv, selDivmod, selExp;
 static ID id_to_i, id_eq;
 
 VALUE rb_cNumeric;
@@ -224,6 +224,13 @@
 }
 
 VALUE
+rb_objc_num_coerce_bin(VALUE x, VALUE y, SEL sel)
+{
+    do_coerce(&x, &y, Qtrue);
+    return rb_vm_call(x, sel, 1, &y, false);
+}
+
+VALUE
 rb_num_coerce_cmp(VALUE x, VALUE y, ID func)
 {
     if (do_coerce(&x, &y, Qfalse)) {
@@ -233,6 +240,15 @@
 }
 
 VALUE
+rb_objc_num_coerce_cmp(VALUE x, VALUE y, SEL sel)
+{
+    if (do_coerce(&x, &y, Qfalse)) {
+	return rb_vm_call(x, sel, 1, &y, false);
+    }
+    return Qnil;
+}
+
+VALUE
 rb_num_coerce_relop(VALUE x, VALUE y, SEL sel)
 {
     VALUE c, x0 = x, y0 = y;
@@ -654,7 +670,7 @@
       case T_FLOAT:
 	return DOUBLE2NUM(RFLOAT_VALUE(x) + RFLOAT_VALUE(y));
       default:
-	return rb_num_coerce_bin(x, y, '+');
+	return rb_objc_num_coerce_bin(x, y, selPLUS);
     }
 }
 
@@ -677,7 +693,7 @@
       case T_FLOAT:
 	return DOUBLE2NUM(RFLOAT_VALUE(x) - RFLOAT_VALUE(y));
       default:
-	return rb_num_coerce_bin(x, y, '-');
+	return rb_objc_num_coerce_bin(x, y, selMINUS);
     }
 }
 
@@ -700,7 +716,7 @@
       case T_FLOAT:
 	return DOUBLE2NUM(RFLOAT_VALUE(x) * RFLOAT_VALUE(y));
       default:
-	return rb_num_coerce_bin(x, y, '*');
+	return rb_objc_num_coerce_bin(x, y, selMULT);
     }
 }
 
@@ -728,7 +744,7 @@
       case T_FLOAT:
 	return DOUBLE2NUM(RFLOAT_VALUE(x) / RFLOAT_VALUE(y));
       default:
-	return rb_num_coerce_bin(x, y, '/');
+	return rb_objc_num_coerce_bin(x, y, selDIV);
     }
 }
 
@@ -793,7 +809,7 @@
 	fy = RFLOAT_VALUE(y);
 	break;
       default:
-	return rb_num_coerce_bin(x, y, '%');
+	return rb_objc_num_coerce_bin(x, y, selMOD);
     }
     flodivmod(RFLOAT_VALUE(x), fy, 0, &mod);
     return DOUBLE2NUM(mod);
@@ -839,7 +855,7 @@
 	fy = RFLOAT_VALUE(y);
 	break;
       default:
-	return rb_num_coerce_bin(x, y, rb_intern("divmod"));
+	return rb_objc_num_coerce_bin(x, y, selDivmod);
     }
     flodivmod(RFLOAT_VALUE(x), fy, &div, &mod);
     a = dbl2ival(div);
@@ -866,7 +882,7 @@
       case T_FLOAT:
 	return DOUBLE2NUM(pow(RFLOAT_VALUE(x), RFLOAT_VALUE(y)));
       default:
-	return rb_num_coerce_bin(x, y, rb_intern("**"));
+	return rb_objc_num_coerce_bin(x, y, selExp);
     }
 }
 
@@ -2187,7 +2203,7 @@
       case T_FLOAT:
 	return DOUBLE2NUM((double)FIX2LONG(x) + RFLOAT_VALUE(y));
       default:
-	return rb_num_coerce_bin(x, y, '+');
+	return rb_objc_num_coerce_bin(x, y, selPLUS);
     }
 }
 
@@ -2221,7 +2237,7 @@
       case T_FLOAT:
 	return DOUBLE2NUM((double)FIX2LONG(x) - RFLOAT_VALUE(y));
       default:
-	return rb_num_coerce_bin(x, y, '-');
+	return rb_objc_num_coerce_bin(x, y, selMINUS);
     }
 }
 
@@ -2280,7 +2296,7 @@
       case T_FLOAT:
 	return DOUBLE2NUM((double)FIX2LONG(x) * RFLOAT_VALUE(y));
       default:
-	return rb_num_coerce_bin(x, y, '*');
+	return rb_objc_num_coerce_bin(x, y, selMULT);
     }
 }
 
@@ -2342,7 +2358,7 @@
 }
 
 static VALUE
-fix_divide(VALUE x, VALUE y, ID op)
+fix_divide(VALUE x, VALUE y, SEL op)
 {
     if (FIXNUM_P(y)) {
 	long div;
@@ -2358,7 +2374,7 @@
 	    {
 		double div;
 
-		if (op == '/') {
+		if (op == selDIV) {
 		    div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
 		    return DOUBLE2NUM(div);
 		}
@@ -2371,7 +2387,7 @@
 		}
 	    }
 	default:
-	    return rb_num_coerce_bin(x, y, op);
+	    return rb_objc_num_coerce_bin(x, y, op);
     }
 }
 
@@ -2387,7 +2403,7 @@
 static VALUE
 fix_div(VALUE x, SEL sel, VALUE y)
 {
-    return fix_divide(x, y, '/');
+    return fix_divide(x, y, selDIV);
 }
 
 /*
@@ -2400,7 +2416,7 @@
 static VALUE
 fix_idiv(VALUE x, SEL sel, VALUE y)
 {
-    return fix_divide(x, y, rb_intern("div"));
+    return fix_divide(x, y, selDiv);
 }
 
 /*
@@ -2433,7 +2449,7 @@
 	    return DOUBLE2NUM(mod);
 	}
       default:
-	return rb_num_coerce_bin(x, y, '%');
+	return rb_objc_num_coerce_bin(x, y, selMOD);
     }
 }
 
@@ -2468,7 +2484,7 @@
 	    return rb_assoc_new(a, b);
 	}
       default:
-	return rb_num_coerce_bin(x, y, rb_intern("divmod"));
+	return rb_objc_num_coerce_bin(x, y, selDivmod);
     }
 }
 
@@ -2530,7 +2546,7 @@
 	long b = FIX2LONG(y);
 
 	if (b < 0) {
-	  return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
+	  return rb_vm_call(rb_rational_raw1(x), selExp, 1, &y, false);
 	}
 
 	if (b == 0) {
@@ -2562,7 +2578,7 @@
     switch (TYPE(y)) {
       case T_BIGNUM:
 	  if (rb_vm_call(y, selLT, 1, &zerov, false)) {
-	      return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
+	      return rb_vm_call(rb_rational_raw1(x), selExp, 1, &y, false);
 	  }
 	  if (a == 0) {
 	      return INT2FIX(0);
@@ -2592,7 +2608,7 @@
 	  return DOUBLE2NUM(pow((double)a, RFLOAT_VALUE(y)));
 
       default:
-	  return rb_num_coerce_bin(x, y, rb_intern("**"));
+	  return rb_objc_num_coerce_bin(x, y, selExp);
     }
 }
 
@@ -3316,6 +3332,9 @@
 {
     sel_coerce = sel_registerName("coerce:");
     selDiv = sel_registerName("div:");
+    selDivmod = sel_registerName("divmod:");
+    selExp = sel_registerName("**:");
+
     id_to_i = rb_intern("to_i");
     id_eq = rb_intern("==");
 

Modified: MacRuby/trunk/string.c
===================================================================
--- MacRuby/trunk/string.c	2009-08-26 21:43:03 UTC (rev 2393)
+++ MacRuby/trunk/string.c	2009-08-27 01:51:00 UTC (rev 2394)
@@ -565,6 +565,11 @@
 	s = rb_str_to_str(s);
 	*ptr = s;
     }
+#if 0 // Apparently not needed...
+    else if (CLASS_OF(s) == rb_cByteString) {
+	s = (VALUE)rb_bytestring_resolve_cfstring(s);
+    }
+#endif
     return s;
 }
 
@@ -5392,6 +5397,12 @@
     return v;
 }
 
+static VALUE
+bytestring_from_data(VALUE klass, SEL sel, VALUE data)
+{
+    return rb_bytestring_new_with_cfdata((CFMutableDataRef)data);
+}
+
 static void inline
 rb_bytestring_copy_cfstring_content(VALUE bstr, CFStringRef str)
 {
@@ -5765,6 +5776,9 @@
     rb_cByteString = rb_define_class("ByteString", rb_cNSMutableString);
     RCLASS_SET_VERSION_FLAG(rb_cByteString, RCLASS_IS_STRING_SUBCLASS);
 
+    rb_objc_define_method(*(VALUE *)rb_cString, "__new_bytestring__",
+	    bytestring_from_data, 1);
+
     rb_objc_install_method2((Class)rb_cByteString, "isEqual:",
 	    (IMP)imp_rb_bytestring_isEqual);
     rb_objc_install_method2((Class)rb_cByteString, "length",
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090826/f942ea2c/attachment-0001.html>


More information about the macruby-changes mailing list