[macruby-changes] [2388] MacRuby/trunk/numeric.c

source_changes at macosforge.org source_changes at macosforge.org
Tue Aug 25 21:47:37 PDT 2009


Revision: 2388
          http://trac.macosforge.org/projects/ruby/changeset/2388
Author:   lsansonetti at apple.com
Date:     2009-08-25 21:47:33 -0700 (Tue, 25 Aug 2009)
Log Message:
-----------
optimized some parts of Numeric to use the new VM primitives

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

Modified: MacRuby/trunk/numeric.c
===================================================================
--- MacRuby/trunk/numeric.c	2009-08-26 03:12:07 UTC (rev 2387)
+++ MacRuby/trunk/numeric.c	2009-08-26 04:47:33 UTC (rev 2388)
@@ -81,7 +81,7 @@
 }
 #endif
 
-static SEL sel_coerce;
+static SEL sel_coerce, selDiv;
 static ID id_to_i, id_eq;
 
 VALUE rb_cNumeric;
@@ -152,7 +152,6 @@
     rb_raise(rb_eZeroDivError, "divided by 0");
 }
 
-
 /*
  *  call-seq:
  *     num.coerce(numeric)   => array
@@ -227,8 +226,9 @@
 VALUE
 rb_num_coerce_cmp(VALUE x, VALUE y, ID func)
 {
-    if (do_coerce(&x, &y, Qfalse))
+    if (do_coerce(&x, &y, Qfalse)) {
 	return rb_funcall(x, func, 1, y);
+    }
     return Qnil;
 }
 
@@ -299,7 +299,7 @@
     zero = INT2FIX(0);
     do_coerce(&zero, &num, Qtrue);
 
-    return rb_funcall(zero, '-', 1, num);
+    return rb_vm_call(zero, selMINUS, 1, &num, false);
 }
 
 /*
@@ -312,7 +312,7 @@
 static VALUE
 num_quo(VALUE x, SEL sel, VALUE y)
 {
-    return rb_funcall(rb_rational_raw1(x), '/', 1, y);
+    return rb_vm_call(rb_rational_raw1(x), selDIV, 1, &y, false);
 }
 
 
@@ -326,7 +326,7 @@
 static VALUE
 num_fdiv(VALUE x, SEL sel, VALUE y)
 {
-    return rb_funcall(rb_Float(x), '/', 1, y);
+    return rb_vm_call(rb_Float(x), selDIV, 1, &y, false);
 }
 
 
@@ -344,8 +344,10 @@
 static VALUE
 num_div(VALUE x, SEL sel, VALUE y)
 {
-    if (rb_equal(INT2FIX(0), y)) rb_num_zerodiv();
-    return num_floor(rb_funcall(x, '/', 1, y), 0);
+    if (rb_equal(INT2FIX(0), y)) {
+	rb_num_zerodiv();
+    }
+    return num_floor(rb_vm_call(x, selDIV, 1, &y, false), 0);
 }
 
 
@@ -393,7 +395,7 @@
 static VALUE
 num_divmod(VALUE x, SEL sel, VALUE y)
 {
-    return rb_assoc_new(num_div(x, 0, y), rb_funcall(x, '%', 1, y));
+    return rb_assoc_new(num_div(x, 0, y), rb_vm_call(x, selMOD, 1, &y, false));
 }
 
 /*
@@ -407,9 +409,9 @@
 static VALUE
 num_modulo(VALUE x, SEL sel, VALUE y)
 {
-      return rb_funcall(x, '-', 1,
-              rb_funcall(y, '*', 1,
-              rb_funcall(x, rb_intern("div"), 1, y)));
+    VALUE tmp1 = rb_vm_call(x, selDiv, 1, &y, false);
+    VALUE tmp2 = rb_vm_call(y, selMULT, 1, &tmp1, false);
+    return rb_vm_call(x, selMINUS, 1, &tmp2, false);
 }
 
 /*
@@ -427,14 +429,15 @@
 static VALUE
 num_remainder(VALUE x, SEL sel, VALUE y)
 {
-    VALUE z = rb_funcall(x, '%', 1, y);
+    VALUE z = rb_vm_call(x, selMOD, 1, &y, false);
 
+    VALUE zero = INT2FIX(0);
     if ((!rb_equal(z, INT2FIX(0))) &&
-	((RTEST(rb_funcall(x, '<', 1, INT2FIX(0))) &&
-	  RTEST(rb_funcall(y, '>', 1, INT2FIX(0)))) ||
-	 (RTEST(rb_funcall(x, '>', 1, INT2FIX(0))) &&
-	  RTEST(rb_funcall(y, '<', 1, INT2FIX(0)))))) {
-	return rb_funcall(z, '-', 1, y);
+	((RTEST(rb_vm_call(x, selLT, 1, &zero, false)) &&
+	  RTEST(rb_vm_call(y, selGT, 1, &zero, false))) ||
+	 (RTEST(rb_vm_call(x, selGT, 1, &zero, false)) &&
+	  RTEST(rb_vm_call(y, selLT, 1, &zero, false))))) {
+	return rb_vm_call(z, selMINUS, 1, &y, false);
     }
     return z;
 }
@@ -495,7 +498,8 @@
 static VALUE
 num_abs(VALUE num, SEL sel)
 {
-    if (RTEST(rb_funcall(num, '<', 1, INT2FIX(0)))) {
+    VALUE zero = INT2FIX(0);
+    if (RTEST(rb_vm_call(num, selLT, 1, &zero, false))) {
 	return rb_funcall(num, rb_intern("-@"), 0);
     }
     return num;
@@ -731,7 +735,7 @@
 static VALUE
 flo_quo(VALUE x, SEL sel, VALUE y)
 {
-    return rb_funcall(x, '/', 1, y);
+    return rb_vm_call(x, selDIV, 1, &y, false);
 }
 
 static void
@@ -1569,19 +1573,22 @@
     }
     else {
 	VALUE i = from;
-	ID cmp;
+	SEL cmp;
 
-	if (RTEST(rb_funcall(step, '>', 1, INT2FIX(0)))) {
-	    cmp = '>';
+	VALUE zero = INT2FIX(0);
+	if (RTEST(rb_vm_call(step, selGT, 1, &zero, false))) {
+	    cmp = selGT;
 	}
 	else {
-	    cmp = '<';
+	    cmp = selLT;
 	}
 	for (;;) {
-	    if (RTEST(rb_funcall(i, cmp, 1, to))) break;
+	    if (RTEST(rb_vm_call(i, cmp, 1, &to, false))) {
+		break;
+	    }
 	    rb_yield(i);
 	    RETURN_IF_BROKEN();
-	    i = rb_funcall(i, '+', 1, step);
+	    i = rb_vm_call(i, selPLUS, 1, &step, false);
 	}
     }
     return from;
@@ -1679,7 +1686,7 @@
 {
     unsigned long num = rb_num2ulong(val);
 
-    if (RTEST(rb_funcall(INT2FIX(0), '<', 1, val))) {
+    if (RTEST(rb_vm_call(INT2FIX(0), selLT, 1, &val, false))) {
 	check_uint(num);
     }
     return num;
@@ -1844,7 +1851,8 @@
 static VALUE
 int_odd_p(VALUE num, SEL sel)
 {
-    if (rb_funcall(num, '%', 1, INT2FIX(2)) != INT2FIX(0)) {
+    VALUE two = INT2FIX(2);
+    if (rb_vm_call(num, selMOD, 1, &two, false) != INT2FIX(0)) {
 	return Qtrue;
     }
     return Qfalse;
@@ -1860,10 +1868,7 @@
 static VALUE
 int_even_p(VALUE num, SEL sel)
 {
-    if (rb_funcall(num, '%', 1, INT2FIX(2)) == INT2FIX(0)) {
-	return Qtrue;
-    }
-    return Qfalse;
+    return int_odd_p(num, 0) == Qtrue ? Qfalse : Qtrue;
 }
 
 /*
@@ -1902,7 +1907,8 @@
 	long i = FIX2LONG(num) + 1;
 	return LONG2NUM(i);
     }
-    return rb_funcall(num, '+', 1, INT2FIX(1));
+    VALUE one = INT2FIX(1);
+    return rb_vm_call(num, selPLUS, 1, &one, false);
 }
 
 /*
@@ -1922,7 +1928,8 @@
 	long i = FIX2LONG(num) - 1;
 	return LONG2NUM(i);
     }
-    return rb_funcall(num, '-', 1, INT2FIX(1));
+    VALUE one = INT2FIX(1);
+    return rb_vm_call(num, selMINUS, 1, &one, false);
 }
 
 /*
@@ -2282,7 +2289,9 @@
 {
     long div, mod;
 
-    if (y == 0) rb_num_zerodiv();
+    if (y == 0) {
+	rb_num_zerodiv();
+    }
     if (y < 0) {
 	if (x < 0)
 	    div = -x / -y;
@@ -2342,25 +2351,27 @@
 	return LONG2NUM(div);
     }
     switch (TYPE(y)) {
-      case T_BIGNUM:
-	x = rb_int2big(FIX2LONG(x));
-	return rb_big_div(x, y);
-      case T_FLOAT:
-	{
-	    double div;
+	case T_BIGNUM:
+	    x = rb_int2big(FIX2LONG(x));
+	    return rb_big_div(x, y);
+	case T_FLOAT:
+	    {
+		double div;
 
-	    if (op == '/') {
-		div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
-		return DOUBLE2NUM(div);
+		if (op == '/') {
+		    div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
+		    return DOUBLE2NUM(div);
+		}
+		else {
+		    if (RFLOAT_VALUE(y) == 0) {
+			rb_num_zerodiv();
+		    }
+		    div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
+		    return rb_dbl2big(floor(div));
+		}
 	    }
-	    else {
-		if (RFLOAT_VALUE(y) == 0) rb_num_zerodiv();
-		div = (double)FIX2LONG(x) / RFLOAT_VALUE(y);
-		return rb_dbl2big(floor(div));
-	    }
-	}
-      default:
-	return rb_num_coerce_bin(x, y, op);
+	default:
+	    return rb_num_coerce_bin(x, y, op);
     }
 }
 
@@ -2518,47 +2529,70 @@
     if (FIXNUM_P(y)) {
 	long b = FIX2LONG(y);
 
-	if (b < 0)
+	if (b < 0) {
 	  return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
+	}
 
-	if (b == 0) return INT2FIX(1);
-	if (b == 1) return x;
+	if (b == 0) {
+	    return INT2FIX(1);
+	}
+	if (b == 1) {
+	    return x;
+	}
 	if (a == 0) {
-	    if (b > 0) return INT2FIX(0);
+	    if (b > 0) {
+		return INT2FIX(0);
+	    }
 	    return DOUBLE2NUM(1.0 / zero);
 	}
-	if (a == 1) return INT2FIX(1);
+	if (a == 1) {
+	    return INT2FIX(1);
+	}
 	if (a == -1) {
-	    if (b % 2 == 0)
+	    if (b % 2 == 0) {
 		return INT2FIX(1);
-	    else 
+	    }
+	    else {
 		return INT2FIX(-1);
+	    }
 	}
 	return int_pow(a, b);
     }
+    VALUE zerov = INT2FIX(0);
     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);
+	  }
+	  if (a == 0) {
+	      return INT2FIX(0);
+	  }
+	  if (a == 1) {
+	      return INT2FIX(1);
+	  }
+	  if (a == -1) {
+	      if (int_even_p(y, 0)) {
+		  return INT2FIX(1);
+	      }
+	      return INT2FIX(-1);
+	  }
+	  x = rb_int2big(FIX2LONG(x));
+	  return rb_big_pow(x, y);
 
-	if (rb_funcall(y, '<', 1, INT2FIX(0)))
-	  return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
+      case T_FLOAT:
+	  if (RFLOAT_VALUE(y) == 0.0) {
+	      return DOUBLE2NUM(1.0);
+	  }
+	  if (a == 0) {
+	      return DOUBLE2NUM(RFLOAT_VALUE(y) < 0 ? (1.0 / zero) : 0.0);
+	  }
+	  if (a == 1) {
+	      return DOUBLE2NUM(1.0);
+	  }
+	  return DOUBLE2NUM(pow((double)a, RFLOAT_VALUE(y)));
 
-	if (a == 0) return INT2FIX(0);
-	if (a == 1) return INT2FIX(1);
-	if (a == -1) {
-	    if (int_even_p(y, 0)) return INT2FIX(1);
-	    else return INT2FIX(-1);
-	}
-	x = rb_int2big(FIX2LONG(x));
-	return rb_big_pow(x, y);
-      case T_FLOAT:
-	if (RFLOAT_VALUE(y) == 0.0) return DOUBLE2NUM(1.0);
-	if (a == 0) {
-	    return DOUBLE2NUM(RFLOAT_VALUE(y) < 0 ? (1.0 / zero) : 0.0);
-	}
-	if (a == 1) return DOUBLE2NUM(1.0);
-	return DOUBLE2NUM(pow((double)a, RFLOAT_VALUE(y)));
       default:
-	return rb_num_coerce_bin(x, y, rb_intern("**"));
+	  return rb_num_coerce_bin(x, y, rb_intern("**"));
     }
 }
 
@@ -3000,10 +3034,11 @@
     else {
 	VALUE i = from, c;
 
-	while (!(c = rb_funcall(i, '>', 1, to))) {
+	while (!(c = rb_vm_call(i, selGT, 1, &to, false))) {
 	    rb_yield(i);
 	    RETURN_IF_BROKEN();
-	    i = rb_funcall(i, '+', 1, INT2FIX(1));
+	    VALUE one = INT2FIX(1);
+	    i = rb_vm_call(i, selPLUS, 1, &one, false);
 	}
 	if (NIL_P(c)) rb_cmperr(i, to);
     }
@@ -3041,10 +3076,11 @@
     else {
 	VALUE i = from, c;
 
-	while (!(c = rb_funcall(i, '<', 1, to))) {
+	while (!(c = rb_vm_call(i, selLT, 1, &to, false))) {
 	    rb_yield(i);
 	    RETURN_IF_BROKEN();
-	    i = rb_funcall(i, '-', 1, INT2FIX(1));
+	    VALUE one = INT2FIX(1);
+	    i = rb_vm_call(i, selMINUS, 1, &one, false);
 	}
 	if (NIL_P(c)) rb_cmperr(i, to);
     }
@@ -3085,12 +3121,13 @@
 	VALUE i = INT2FIX(0);
 
 	for (;;) {
-	    if (!RTEST(rb_funcall(i, '<', 1, num))) {
+	    if (!RTEST(rb_vm_call(i, selLT, 1, &num, false))) {
 		break;
 	    }
 	    rb_yield(i);
 	    RETURN_IF_BROKEN();
-	    i = rb_funcall(i, '+', 1, INT2FIX(1));
+	    VALUE one = INT2FIX(1);
+	    i = rb_vm_call(i, selPLUS, 1, &one, false);
 	}
     }
     return num;
@@ -3124,11 +3161,12 @@
 	if (neg) x = -x;
 	return LONG2NUM(x);
     }
-    h = rb_funcall(f, '/', 1, INT2FIX(2));
-    r = rb_funcall(num, '%', 1, f);
-    n = rb_funcall(num, '-', 1, r);
-    if (!RTEST(rb_funcall(r, '<', 1, h))) {
-	n = rb_funcall(n, '+', 1, f);
+    VALUE two = INT2FIX(2);
+    h = rb_vm_call(f, selDIV, 1, &two, false);
+    r = rb_vm_call(num, selMOD, 1, &f, false);
+    n = rb_vm_call(num, selMINUS, 1, &r, false);
+    if (!RTEST(rb_vm_call(r, selLT, 1, &h, false))) {
+	n = rb_vm_call(n, selPLUS, 1, &f, false);
     }
     return n;
 }
@@ -3277,6 +3315,7 @@
 Init_Numeric(void)
 {
     sel_coerce = sel_registerName("coerce:");
+    selDiv = sel_registerName("div:");
     id_to_i = rb_intern("to_i");
     id_eq = rb_intern("==");
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090825/9f6c76af/attachment-0001.html>


More information about the macruby-changes mailing list