diff --git a/kernel/common/marshal.rb b/kernel/common/marshal.rb index 4f27d7ad52..66fe2ac25b 100644 --- a/kernel/common/marshal.rb +++ b/kernel/common/marshal.rb @@ -79,28 +79,13 @@ def __marshal__(ms) class Fixnum def __marshal__(ms) - "i#{ms.serialize_integer(self)}" + ms.serialize_integer(self, "i") end end class Bignum def __marshal__(ms) - str = (self < 0 ? 'l-' : 'l+') - cnt = 0 - num = self.abs - - while num != 0 - str << (num & 0xff).chr - num >>= 8 - cnt += 1 - end - - if cnt % 2 == 1 - str << "\0" - cnt += 1 - end - - str[0..1] + ms.serialize_integer(cnt / 2) + str[2..-1] + ms.serialize_bignum(self) end end @@ -799,7 +784,19 @@ def serialize_instance_variables_suffix(obj, force=false, end end - def serialize_integer(n) + def serialize_integer(n, prefix = nil) + if !Rubinius::L64 && n.is_a?(Fixnum) + prefix.to_s + serialize_fixnum(n) + else + if (n >> 31) == 0 or (n >> 31) == -1 + prefix.to_s + serialize_fixnum(n) + else + serialize_bignum(n) + end + end + end + + def serialize_fixnum(n) if n == 0 s = n.chr elsif n > 0 and n < 123 @@ -820,6 +817,25 @@ def serialize_integer(n) s end + def serialize_bignum(n) + str = (n < 0 ? 'l-' : 'l+') + cnt = 0 + num = n.abs + + while num != 0 + str << (num & 0xff).chr + num >>= 8 + cnt += 1 + end + + if cnt % 2 == 1 + str << "\0" + cnt += 1 + end + + str[0..1] + serialize_fixnum(cnt / 2) + str[2..-1] + end + def serialize_user_class(obj, cls) if obj.class != cls "C#{serialize(obj.class.name.to_sym)}"