Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fixed String#sum to accept bits argument greater than 64 (logic impor…

…ted from 1.9 upstream sources)

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@4470 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
commit e59fe57f80414bf21c91ae413046e311bd1c37f8 1 parent 87fa641
Laurent Sansonetti authored
Showing with 37 additions and 9 deletions.
  1. +1 −0  id.c
  2. +1 −0  id.h
  3. +35 −9 string.c
1  id.c
View
@@ -48,6 +48,7 @@ Init_id(void)
selMULT = sel_registerName("*:");
selDIV = sel_registerName("/:");
selMOD = sel_registerName("%:");
+ selAND = sel_registerName("&:");
selEq = sel_registerName("==:");
selNeq = sel_registerName("!=:");
selCmp = sel_registerName("<=>:");
1  id.h
View
@@ -58,6 +58,7 @@ extern SEL selMINUS;
extern SEL selMULT;
extern SEL selDIV;
extern SEL selMOD;
+extern SEL selAND;
extern SEL selEq;
extern SEL selNeq;
extern SEL selCmp;
44 string.c
View
@@ -5514,6 +5514,12 @@ rstr_tr_s(VALUE str, SEL sel, VALUE src, VALUE repl)
* checksum.
*/
+static inline VALUE
+rb_vm_call_simple(VALUE rcv, SEL sel, VALUE arg)
+{
+ return rb_vm_call(rcv, sel, 1, &arg);
+}
+
static VALUE
rstr_sum(VALUE str, SEL sel, int argc, VALUE *argv)
{
@@ -5524,19 +5530,39 @@ rstr_sum(VALUE str, SEL sel, int argc, VALUE *argv)
bits = NUM2INT(vbits);
}
- if (bits >= sizeof(long) * CHAR_BIT) {
- rb_raise(rb_eArgError, "bits argument too big");
- }
-
- unsigned long sum = 0;
+ VALUE sum = INT2FIX(0);
+ unsigned long sum0 = 0;
for (long i = 0; i < RSTR(str)->length_in_bytes; i++) {
- sum += (unsigned char)RSTR(str)->data.bytes[i];
+ if (FIXNUM_MAX - UCHAR_MAX < sum0) {
+ sum = rb_vm_call_simple(sum, selPLUS, LONG2FIX(sum0));
+ sum0 = 0;
+ }
+ sum0 += (unsigned char)RSTR(str)->data.bytes[i];
+ }
+ if (bits == 0) {
+ if (sum0 != 0) {
+ sum = rb_vm_call_simple(sum, selPLUS, LONG2FIX(sum0));
+ }
}
- if (bits != 0) {
- sum &= (((unsigned long)1) << bits) - 1;
+ else {
+ if (sum == INT2FIX(0)) {
+ if (bits < (int)sizeof(long) * CHAR_BIT) {
+ sum0 &= (((unsigned long)1) << bits) - 1;
+ }
+ sum = LONG2FIX(sum0);
+ }
+ else {
+ if (sum0 != 0) {
+ sum = rb_vm_call_simple(sum, selPLUS, LONG2FIX(sum0));
+ }
+
+ VALUE mod = rb_vm_call_simple(INT2FIX(1), selLTLT, INT2FIX(bits));
+ mod = rb_vm_call_simple(mod, selMINUS, INT2FIX(1));
+ sum = rb_vm_call_simple(sum, selAND, mod);
+ }
}
- return rb_int2inum(sum);
+ return sum;
}
/*
Please sign in to comment.
Something went wrong with that request. Please try again.