Permalink
Browse files

Perl 5.6.2 should be good now (albeit forced to 32-bit sometimes)

  • Loading branch information...
1 parent bbc6e32 commit 147719070c03dc76cf3053c931a772f6a8d457a7 @danaj committed Nov 28, 2011
View
@@ -21,25 +21,10 @@ WriteMakefile(
'Mouse::Role' => '0.58',
},
- # 64-bit seems broken in Perl 5.6.2 on the 32-bit systems I have (and at
- # least one CPAN Tester shows the same). Try:
- # perl -e 'die if 18446744073709550593 == ~0'
- # That inexplicably dies on 64-bit 5.6.2. It works fine on 5.8.0 and later.
+ # I have not tested with any version of Perl previous to 5.6.2. v5.6.2
+ # does work, though is forced to 32-bit if it detects 64-bit arithmetic is
+ # broken. Data::BitStream::XS works fine on 5.6.2 because it is using C
+ # for the bit operations.
#
- # Most of the module can be made to work by forcing maxbits to 32 if we're
- # pre-5.8.0 (which I have done). However there is a lot of work to do in
- # the Code modules. I've made enough changes so only the range tests fail.
- # Basically it all works fine unless you're using a 64-bit pre-5.8.0 Perl
- # on a 32-bit system compiled with 64-bit ints, and want to store 0xFFFFFFFF
- # with interesting codes such as Gamma, Omega, etc.
- #
- # Given the age of 5.6.2, I've decided the best solution for now is to
- # require a more modern (only 10 years old) Perl.
- # I have not tested any of the 5.7.x versions.
- #
- # Note: Data::BitStream::XS works fine on 5.6.2 because it is using C for
- # these operations. You should be ok either using that module, or
- # using this module with D::B::XS installed.
- #
- MIN_PERL_VERSION => 5.8.0,
+ # MIN_PERL_VERSION => 5.8.0,
);
View
9 README
@@ -1,4 +1,4 @@
-Data-BitStream version 0.04
+Data-BitStream version 0.05
===========================
A Mouse/Moose class providing read/write access to bit streams. This includes
@@ -51,8 +51,11 @@ Here are instructions and benchmarks for using Moo:
https://gist.github.com/1259851
I have tested this using perl versions 5.8.0, 5.8.9, 5.10.1, 5.12.4, 5.14.1,
-and 5.15.2. Perl 5.6.2 works on 64-bit systems, and 32-bit systems not using
-64-bit integers.
+and 5.15.2.
+
+It also works with Perl 5.6.2, with a caveat. On 32-bit O/S, 64-bit Perl can
+have broken arithmetic (two unequal 64-bit numbers will compare as equal). We
+force maxbits to 32 if it looks like it won't work with 64.
COPYRIGHT AND LICENCE
View
@@ -114,6 +114,11 @@ BEGIN {
die "Config says 64-bit Perl, but int is $notzero" if ((~0 >> 16) >> 16) != 0xFFFFFFFF;
}
+ # 64-bit seems broken in Perl 5.6.2 on the 32-bit system I have (and at
+ # least one CPAN Tester shows the same). Try:
+ # perl -e 'die if 18446744073709550593 == ~0'
+ # That inexplicably dies on 64-bit 5.6.2. It works fine on 5.8.0 and later.
+ #
# Direct method, pre-5.8.0 Perls.
# $_host_word_size = 32 if $] < 5.008;
# Detect the symptoms (should allow 5.6.2 on 64-bit O/S to work fine):
@@ -122,11 +127,9 @@ BEGIN {
}
$_all_ones = ($_host_word_size == 32) ? 0xFFFFFFFF : ~0;
- # Unfortunately this needs changes in a lot of the Code modules to pass the
- # range tests. They're hard-coding ~0 a lot for maxval.
}
use constant maxbits => $_host_word_size;
-use constant allones => $_all_ones;
+use constant maxval => $_all_ones;
sub rewind {
my $self = shift;
@@ -316,12 +319,12 @@ sub put_unary1 {
foreach my $val (@_) {
warn "Trying to write large unary value ($val)" if $val > 10_000_000;
if ($val < maxbits) {
- $self->write($val+1, allones << 1);
+ $self->write($val+1, maxval << 1);
} else {
my $nbits = $val % maxbits;
my $nwords = ($val-$nbits) / maxbits;
- $self->write(maxbits, allones) for (1 .. $nwords);
- $self->write($nbits+1, allones << 1);
+ $self->write(maxbits, maxval) for (1 .. $nwords);
+ $self->write($nbits+1, maxval << 1);
}
}
1;
@@ -352,7 +355,7 @@ sub get_unary1 { # You ought to override this.
my $word = $self->read(maxbits, 'readahead');
last unless defined $word;
- while ($word == allones) {
+ while ($word == maxval) {
die "read off end of stream" unless $self->skip(maxbits);
$val += maxbits;
$word = $self->read(maxbits, 'readahead');
@@ -60,11 +60,12 @@ sub put_boldivigna {
($maxhk, $hparams) = _hparam_map($k, $self->maxbits);
$hp_cache[$k] = [$maxhk, $hparams];
}
+ my $maxval = $self->maxval;
foreach my $v (@_) {
die "Value must be >= 0" unless $v >= 0;
- if ($v == ~0) {
+ if ($v == $maxval) {
$self->put_unary( ($maxhk/$k)+1 );
next;
}
@@ -113,7 +114,7 @@ sub get_boldivigna {
my $h = $self->get_unary();
last unless defined $h;
if ($h > ($maxhk/$k)) {
- push @vals, ~0;
+ push @vals, $self->maxval;
next;
}
my ($s, $threshold) = @{$hparams->[$h]};
@@ -26,11 +26,13 @@ requires qw(maxbits read write put_gamma get_gamma);
sub put_delta {
my $self = shift;
+ my $maxbits = $self->maxbits;
+ my $maxval = $self->maxval;
foreach my $val (@_) {
die "Value must be >= 0" unless $val >= 0;
- if ($val == ~0) {
- $self->put_gamma($self->maxbits);
+ if ($val == $maxval) {
+ $self->put_gamma($maxbits);
} else {
my $base = 0;
{ my $v = $val+1; $base++ while ($v >>= 1); }
@@ -54,7 +56,7 @@ sub get_delta {
my $base = $self->get_gamma();
last unless defined $base;
if ($base == $maxbits) {
- push @vals, ~0;
+ push @vals, $self->maxval;
} elsif ($base > $maxbits) {
# Skip back to the start of the invalid gamma value
my $glen = 1; $glen += 2 while ( $base >= ((2 << ($glen>>1))-1) );
@@ -33,6 +33,7 @@ requires qw(maxbits read write put_unary get_unary);
sub put_gamma {
my $self = shift;
die "write while reading" unless $self->writing;
+ my $maxval = $self->maxval;
foreach my $val (@_) {
die "value must be >= 0" unless $val >= 0;
@@ -47,7 +48,7 @@ sub put_gamma {
if ($val == 0) { $self->write(1, 1); }
elsif ($val == 1) { $self->write(3, 2); } # optimization
elsif ($val == 2) { $self->write(3, 3); } # optimization
- elsif ($val == ~0) { $self->put_unary($self->maxbits); }
+ elsif ($val == $maxval) { $self->put_unary($self->maxbits); }
else {
my $base = 0;
{ my $v = $val+1; $base++ while ($v >>= 1); }
@@ -78,7 +79,7 @@ sub get_gamma {
if ($base == 0) { push @vals, 0; }
elsif ($base == 1) { push @vals, (2 | $self->read(1))-1; } # optimization
elsif ($base == 2) { push @vals, (4 | $self->read(2))-1; } # optimization
- elsif ($base == $maxbits) { push @vals, ~0; }
+ elsif ($base == $maxbits) { push @vals, $self->maxval; }
elsif ($base > $maxbits) {
$self->skip(-($base+1));
die "code error: Gamma base $base";
@@ -31,12 +31,14 @@ sub _base_of { my $d = shift; my $base = 0; $base++ while ($d >>= 1); $base; }
sub put_omega {
my $self = shift;
+ my $maxval = $self->maxval;
+ my $maxbits = $self->maxbits;
foreach my $v (@_) {
my $val = $v;
die "Value must be >= 0" unless $val >= 0;
- if ($val == ~0) { # write special code for maxval
- if ($self->maxbits > 32) {
+ if ($val == $maxval) { # write special code for maxval
+ if ($maxbits > 32) {
$self->write(13, 0x1681); # 1 0 1 10 1 000000 1
} else {
$self->write(12, 0x0AC1); # 1 0 1 01 1 00000 1
@@ -132,7 +134,7 @@ sub get_omega {
}
}
do {
- if ($val == $maxbits) { push @vals, ~0; next; }
+ if ($val == $maxbits) { push @vals, $self->maxval; next; }
$val = (1 << $val) | $self->read($val);
} while ($first_bit = $self->read(1));
@@ -196,14 +196,15 @@ sub put_gamma {
my $rstr = $self->_strref;
my $len = $self->len;
+ my $maxval = $self->maxval;
foreach my $val (@_) {
die "value must be >= 0" unless $val >= 0;
my $vstr;
if ($val == 0) { $vstr = '1'; }
elsif ($val == 1) { $vstr = '010'; }
elsif ($val == 2) { $vstr = '011'; }
- elsif ($val == ~0) { $vstr = '0' x $self->maxbits . '1'; }
+ elsif ($val == $maxval) { $vstr = '0' x $self->maxbits . '1'; }
else {
my $base = 0;
{ my $v = $val+1; $base++ while ($v >>= 1); }
@@ -243,7 +244,7 @@ sub get_gamma {
my $base = $onepos - $pos;
$pos = $onepos + 1;
if ($base == 0) { push @vals, 0; }
- elsif ($base == $self->maxbits) { push @vals, ~0; }
+ elsif ($base == $self->maxbits) { push @vals, $self->maxval; }
else {
my $vstr = substr($$rstr, $pos, $base);
$pos += $base;
@@ -225,6 +225,7 @@ sub put_gamma {
my $len = $self->len;
my $rvec = $self->_vecref;
+ my $maxval = $self->maxval;
foreach my $val (@_) {
die "value must be >= 0" unless $val >= 0;
@@ -236,7 +237,7 @@ sub put_gamma {
vec($$rvec, $wpos, 32) |= (1 << ((32-$bpos) - 1));
$len++;
next;
- } elsif ($val == ~0) { # Encode ~0 as unary maxbits
+ } elsif ($val == $maxval) { # Encode ~0 as unary maxbits
$len += $self->maxbits;
$wpos = $len >> 5; # / 32
$bpos = $len & 0x1F; # % 32
View
@@ -8,11 +8,14 @@ use lib qw(t/lib);
use BitStreamTest;
my $maxval = ~0;
-# Force maxval to 0xFFFFFFFF if the stream is 32-bit.
+my $skip64 = 0; # allows skipping certain tests if we're on broken 64-bit.
{
+ # Force maxval to 0xFFFFFFFF if the stream is 32-bit.
my $stream = new_stream('String');
$maxval = 0xFFFFFFFF if $stream->maxbits == 32;
+ $skip64 = 1 if ($] < 5.008) && ($maxval < ~0);
}
+
my @maxdata = (0, 1, 2, 33, 65, 129,
($maxval >> 1) - 2,
($maxval >> 1) - 1,
@@ -37,10 +40,15 @@ plan tests => scalar @implementations * scalar @encodings;
foreach my $type (@implementations) {
foreach my $encoding (@encodings) {
-
- my $stream = stream_encode_array($type, $encoding, @maxdata);
- my @v = stream_decode_array($encoding, $stream);
- is_deeply( \@v, \@maxdata, "$type: $encoding range patterns");
-
+ SKIP: {
+ # All fixed up, so no need to skip anything right now.
+ # skip "Skipping range test: broken 64-bit Perl", 1
+ # if $skip64 && ($encoding =~ /^(Gamma|Delta|Omega|BVZeta)\b/);
+
+ #print STDERR "starting $type $encoding\n";
+ my $stream = stream_encode_array($type, $encoding, @maxdata);
+ my @v = stream_decode_array($encoding, $stream);
+ is_deeply( \@v, \@maxdata, "$type: $encoding range patterns");
+ }
}
}

0 comments on commit 1477190

Please sign in to comment.