From: Ton Hospel Date: Sun, 13 Mar 2005 15:07:41 +0000 (+0000) Subject: pp_pack.c, simplifying genpacksizetables X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=a7a3cfaaf49bbb73e31b47977f7340aaabd17dcb;p=p5sagit%2Fp5-mst-13.2.git pp_pack.c, simplifying genpacksizetables Message-Id: p4raw-id: //depot/perl@24038 --- diff --git a/genpacksizetables.pl b/genpacksizetables.pl index 0fffe9b..5872e86 100755 --- a/genpacksizetables.pl +++ b/genpacksizetables.pl @@ -4,103 +4,85 @@ use strict; use Encode; -my @lines = grep { - s/#.*//; - /\S/; -} ; +sub make_text { + my ($chrmap, $letter, $unpredictable, $nocsum, $size, $condition) = @_; + my $text = " /* $letter */ $size"; + $text .= " | PACK_SIZE_UNPREDICTABLE" if $unpredictable; + $text .= " | PACK_SIZE_CANNOT_CSUM" if $nocsum; + $text .= ","; -sub addline { - my ($arrays, $chrmap, $letter, $arrayname, $unpredictable, $nocsum, $size, - $condition) = @_; - my $line = "/* $letter */ $size"; - $line .= " | PACK_SIZE_UNPREDICTABLE" if $unpredictable; - $line .= " | PACK_SIZE_CANNOT_CSUM" if $nocsum; - $line .= ","; - # And then the hack - $line = [$condition, $line] if $condition; - $arrays->{$arrayname}->[ord $chrmap->{$letter}] = $line; - # print ord $chrmap->{$letter}, " $line\n"; + if ($condition) { + $condition = join " && ", map {"defined($_)"} split ' ', $condition; + $text = "#if $condition +$text +#else + 0, +#endif"; + } + return $text; } -sub output_tables { - my %arrays; - - my $chrmap = shift; - foreach (@_) { - my ($letter, $shriek, $unpredictable, $nocsum, $size, $condition) - = /^([A-Za-z])(!?)\t(\S*)\t(\S*)\t([^\t\n]+)(?:\t+(.*))?$/; - die "Can't parse '$_'" unless $size; +sub make_tables { + my %arrays; - if (defined $condition) { - $condition = join " && ", map {"defined($_)"} split ' ', $condition; - } - unless ($size =~ s/^=//) { - $size = "sizeof($size)"; - } + my $chrmap = shift; + foreach (@_) { + my ($letter, $shriek, $unpredictable, $nocsum, $size, $condition) = + /^([A-Za-z])(!?)\t(\S*)\t(\S*)\t([^\t\n]+)(?:\t+(.*))?$/ or + die "Can't parse '$_'"; - addline (\%arrays, $chrmap, $letter, $shriek ? 'shrieking' : 'normal', - $unpredictable, $nocsum, $size, $condition); - } + $size = "sizeof($size)" unless $size =~ s/^=//; - my %earliest; - foreach my $arrayname (sort keys %arrays) { - my $array = $arrays{$arrayname}; - die "No defined entries in $arrayname" unless $array->[$#$array]; - # Find the first used entry - my $earliest = 0; - $earliest++ while (!$array->[$earliest]); - # Remove all the empty elements. - splice @$array, 0, $earliest; - print "unsigned char size_${arrayname}[", scalar @$array, "] = {\n"; - my @lines; - foreach (@$array) { - # Remove the assumption here that the last entry isn't conditonal - if (ref $_) { - push @lines, - ["#if $_->[0]", " $_->[1]", "#else", " 0,", "#endif"]; - } else { - push @lines, $_ ? " $_" : " 0,"; - } + $arrays{$shriek ? 'shrieking' : 'normal'}{ord $chrmap->{$letter}} = + make_text($chrmap, $letter, + $unpredictable, $nocsum, $size, $condition); } - # remove the last, annoying, comma - my $last = $lines[$#lines]; - my $got; - foreach (ref $last ? @$last : $last) { - $got += s/,$//; + + my $text = "const packprops_t packprops[512] = {\n"; + foreach my $arrayname (qw(normal shrieking)) { + my $array = $arrays{$arrayname} || + die "No defined entries in $arrayname"; + $text .= " /* $arrayname */\n"; + for my $ch (0..255) { + $text .= $array->{$ch} || " 0,"; + $text .= "\n"; + } } - die "Last entry had no commas" unless $got; - print map {"$_\n"} ref $_ ? @$_ : $_ foreach @lines; - print "};\n"; - $earliest{$arrayname} = $earliest; - } + # Join "0," entries together + 1 while $text =~ s/\b0,\s*\n\s*0,/0, 0,/g; + # But split them up again if the sequence gets too long + $text =~ s/((?:\b0, ){15}0,) /$1\n /g; + # Clean up final , + $text =~ s/,$//; + $text .= "};"; + return $text; +} - print "struct packsize_t packsize[2] = {\n"; +my @lines = grep { + s/#.*//; + /\S/; +} ; - my @lines; - foreach (qw(normal shrieking)) { - my $array = $arrays{$_}; - push @lines, " {size_$_, $earliest{$_}, " . (scalar @$array) . "},"; - } - # remove the last, annoying, comma - chop $lines[$#lines]; - print "$_\n" foreach @lines; - print "};\n"; -} +my %asciimap = map {chr $_, chr $_} 0..255; +my %ebcdicmap = map {chr $_, Encode::encode("posix-bc", chr $_)} 0..255; -my %asciimap = (map {chr $_, chr $_} 0..255); -my %ebcdicmap = (map {chr $_, Encode::encode ("posix-bc", chr $_)} 0..255); +print <<"EOC"; +/* These tables are regenerated by genpacksizetables.pl (and then hand pasted + in). You're unlikely ever to need to regenerate them. */ -print <<'EOC'; +#if TYPE_IS_SHRIEKING != 0x100 + ++++shriek offset should be 256 +#endif + +typedef U8 packprops_t; #if 'J'-'I' == 1 /* ASCII */ -EOC -output_tables (\%asciimap, @lines); -print <<'EOC'; +@{[make_tables (\%asciimap, @lines)]} #else /* EBCDIC (or bust) */ +@{[make_tables (\%ebcdicmap, @lines)]} +#endif EOC -output_tables (\%ebcdicmap, @lines); -print "#endif\n"; __DATA__ #Symbol unpredictable diff --git a/pp_pack.c b/pp_pack.c index 3c00743..e62f56d 100644 --- a/pp_pack.c +++ b/pp_pack.c @@ -314,213 +314,253 @@ S_mul128(pTHX_ SV *sv, U8 m) #define PACK_SIZE_UNPREDICTABLE 0x40 /* Not a fixed size element */ #define PACK_SIZE_MASK 0x3F - -struct packsize_t { - const unsigned char *array; - int first; - int size; -}; - -#define PACK_SIZE_NORMAL 0 -#define PACK_SIZE_SHRIEKING 1 - /* These tables are regenerated by genpacksizetables.pl (and then hand pasted in). You're unlikely ever to need to regenerate them. */ + +#if TYPE_IS_SHRIEKING != 0x100 + ++++shriek offset should be 256 +#endif + +typedef U8 packprops_t; #if 'J'-'I' == 1 /* ASCII */ -unsigned char size_normal[53] = { - /* C */ sizeof(unsigned char), +const packprops_t packprops[512] = { + /* normal */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + /* C */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE, #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE) - /* D */ LONG_DOUBLESIZE, + /* D */ LONG_DOUBLESIZE, #else - 0, + 0, #endif - 0, - /* F */ NVSIZE, - 0, 0, - /* I */ sizeof(unsigned int), - /* J */ UVSIZE, - 0, - /* L */ SIZE32, - 0, - /* N */ SIZE32, - 0, 0, + 0, + /* F */ NVSIZE, + 0, 0, + /* I */ sizeof(unsigned int), + /* J */ UVSIZE, + 0, + /* L */ SIZE32, + 0, + /* N */ SIZE32, + 0, 0, #if defined(HAS_QUAD) - /* Q */ sizeof(Uquad_t), + /* Q */ sizeof(Uquad_t), #else - 0, + 0, #endif - 0, - /* S */ SIZE16, - 0, - /* U */ sizeof(char) | PACK_SIZE_UNPREDICTABLE, - /* V */ SIZE32, - /* W */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* c */ sizeof(char), - /* d */ sizeof(double), - 0, - /* f */ sizeof(float), - 0, 0, - /* i */ sizeof(int), - /* j */ IVSIZE, - 0, - /* l */ SIZE32, - 0, - /* n */ SIZE16, - 0, - /* p */ sizeof(char *) | PACK_SIZE_CANNOT_CSUM, + 0, + /* S */ SIZE16, + 0, + /* U */ sizeof(char) | PACK_SIZE_UNPREDICTABLE, + /* V */ SIZE32, + /* W */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* c */ sizeof(char), + /* d */ sizeof(double), + 0, + /* f */ sizeof(float), + 0, 0, + /* i */ sizeof(int), + /* j */ IVSIZE, + 0, + /* l */ SIZE32, + 0, + /* n */ SIZE16, + 0, + /* p */ sizeof(char *) | PACK_SIZE_CANNOT_CSUM, #if defined(HAS_QUAD) - /* q */ sizeof(Quad_t), + /* q */ sizeof(Quad_t), #else - 0, + 0, #endif - 0, - /* s */ SIZE16, - 0, 0, - /* v */ SIZE16, - /* w */ sizeof(char) | PACK_SIZE_UNPREDICTABLE | PACK_SIZE_CANNOT_CSUM, -}; -unsigned char size_shrieking[46] = { - /* I */ sizeof(unsigned int), - 0, 0, - /* L */ sizeof(unsigned long), - 0, + 0, + /* s */ SIZE16, + 0, 0, + /* v */ SIZE16, + /* w */ sizeof(char) | PACK_SIZE_UNPREDICTABLE | PACK_SIZE_CANNOT_CSUM, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + /* shrieking */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* I */ sizeof(unsigned int), + 0, 0, + /* L */ sizeof(unsigned long), + 0, #if defined(PERL_PACK_CAN_SHRIEKSIGN) - /* N */ SIZE32, + /* N */ SIZE32, #else - 0, + 0, #endif - 0, 0, 0, 0, - /* S */ sizeof(unsigned short), - 0, 0, + 0, 0, 0, 0, + /* S */ sizeof(unsigned short), + 0, 0, #if defined(PERL_PACK_CAN_SHRIEKSIGN) - /* V */ SIZE32, + /* V */ SIZE32, #else - 0, + 0, #endif - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* i */ sizeof(int), - 0, 0, - /* l */ sizeof(long), - 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + /* i */ sizeof(int), + 0, 0, + /* l */ sizeof(long), + 0, #if defined(PERL_PACK_CAN_SHRIEKSIGN) - /* n */ SIZE16, + /* n */ SIZE16, #else - 0, + 0, #endif - 0, 0, 0, 0, - /* s */ sizeof(short), - 0, 0, + 0, 0, 0, 0, + /* s */ sizeof(short), + 0, 0, #if defined(PERL_PACK_CAN_SHRIEKSIGN) - /* v */ SIZE16 + /* v */ SIZE16, #else - 0 + 0, #endif -}; -struct packsize_t packsize[2] = { - {size_normal, 67, 53}, - {size_shrieking, 73, 46} + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #else /* EBCDIC (or bust) */ -unsigned char size_normal[100] = { - /* c */ sizeof(char), - /* d */ sizeof(double), - 0, - /* f */ sizeof(float), - 0, 0, - /* i */ sizeof(int), - 0, 0, 0, 0, 0, 0, 0, - /* j */ IVSIZE, - 0, - /* l */ SIZE32, - 0, - /* n */ SIZE16, - 0, - /* p */ sizeof(char *) | PACK_SIZE_CANNOT_CSUM, +const packprops_t packprops[512] = { + /* normal */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + /* c */ sizeof(char), + /* d */ sizeof(double), + 0, + /* f */ sizeof(float), + 0, 0, + /* i */ sizeof(int), + 0, 0, 0, 0, 0, 0, 0, + /* j */ IVSIZE, + 0, + /* l */ SIZE32, + 0, + /* n */ SIZE16, + 0, + /* p */ sizeof(char *) | PACK_SIZE_CANNOT_CSUM, #if defined(HAS_QUAD) - /* q */ sizeof(Quad_t), + /* q */ sizeof(Quad_t), #else - 0, + 0, #endif - 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* s */ SIZE16, - 0, 0, - /* v */ SIZE16, - /* w */ sizeof(char) | PACK_SIZE_UNPREDICTABLE | PACK_SIZE_CANNOT_CSUM, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, - /* C */ sizeof(unsigned char), + 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* s */ SIZE16, + 0, 0, + /* v */ SIZE16, + /* w */ sizeof(char) | PACK_SIZE_UNPREDICTABLE | PACK_SIZE_CANNOT_CSUM, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* C */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE, #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE) - /* D */ LONG_DOUBLESIZE, + /* D */ LONG_DOUBLESIZE, #else - 0, + 0, #endif - 0, - /* F */ NVSIZE, - 0, 0, - /* I */ sizeof(unsigned int), - 0, 0, 0, 0, 0, 0, 0, - /* J */ UVSIZE, - 0, - /* L */ SIZE32, - 0, - /* N */ SIZE32, - 0, 0, + 0, + /* F */ NVSIZE, + 0, 0, + /* I */ sizeof(unsigned int), + 0, 0, 0, 0, 0, 0, 0, + /* J */ UVSIZE, + 0, + /* L */ SIZE32, + 0, + /* N */ SIZE32, + 0, 0, #if defined(HAS_QUAD) - /* Q */ sizeof(Uquad_t), + /* Q */ sizeof(Uquad_t), #else - 0, + 0, #endif - 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* S */ SIZE16, - 0, - /* U */ sizeof(char) | PACK_SIZE_UNPREDICTABLE, - /* V */ SIZE32, - /* W */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE, -}; -unsigned char size_shrieking[93] = { - /* i */ sizeof(int), - 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* l */ sizeof(long), - 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* S */ SIZE16, + 0, + /* U */ sizeof(char) | PACK_SIZE_UNPREDICTABLE, + /* V */ SIZE32, + /* W */ sizeof(unsigned char) | PACK_SIZE_UNPREDICTABLE, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* shrieking */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* i */ sizeof(int), + 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* l */ sizeof(long), + 0, #if defined(PERL_PACK_CAN_SHRIEKSIGN) - /* n */ SIZE16, + /* n */ SIZE16, #else - 0, + 0, #endif - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* s */ sizeof(short), - 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* s */ sizeof(short), + 0, 0, #if defined(PERL_PACK_CAN_SHRIEKSIGN) - /* v */ SIZE16, + /* v */ SIZE16, #else - 0, + 0, #endif - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* I */ sizeof(unsigned int), - 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* L */ sizeof(unsigned long), - 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, + /* I */ sizeof(unsigned int), + 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* L */ sizeof(unsigned long), + 0, #if defined(PERL_PACK_CAN_SHRIEKSIGN) - /* N */ SIZE32, + /* N */ SIZE32, #else - 0, + 0, #endif - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* S */ sizeof(unsigned short), - 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* S */ sizeof(unsigned short), + 0, 0, #if defined(PERL_PACK_CAN_SHRIEKSIGN) - /* V */ SIZE32 + /* V */ SIZE32, #else - 0 + 0, #endif -}; -struct packsize_t packsize[2] = { - {size_normal, 131, 100}, - {size_shrieking, 137, 93} + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #endif @@ -701,9 +741,6 @@ S_measure_struct(pTHX_ tempsym_t* symptr) while (next_symbol(symptr)) { I32 len; int star, size; - int which = (symptr->code & TYPE_IS_SHRIEKING) ? - PACK_SIZE_SHRIEKING : PACK_SIZE_NORMAL; - int offset = TYPE_NO_MODIFIERS(symptr->code) - packsize[which].first; switch (symptr->howlen) { case e_star: @@ -716,11 +753,7 @@ S_measure_struct(pTHX_ tempsym_t* symptr) break; } - if ((offset >= 0) && (offset < packsize[which].size)) - size = packsize[which].array[offset] & PACK_SIZE_MASK; - else - size = 0; - + size = packprops[TYPE_NO_ENDIANNESS(symptr->code)] & PACK_SIZE_MASK; if (!size) { /* endianness doesn't influence the size of a type */ switch(TYPE_NO_ENDIANNESS(symptr->code)) { @@ -1151,6 +1184,7 @@ S_unpack_rec(pTHX_ tempsym_t* symptr, char *s, char *strbeg, char *strend, char bool utf8 = (symptr->flags & FLAG_PARSE_UTF8) ? 1 : 0; while (next_symbol(symptr)) { + packprops_t props; I32 len, ai32; I32 datumtype = symptr->code; /* do first one only unless in list context @@ -1174,32 +1208,22 @@ S_unpack_rec(pTHX_ tempsym_t* symptr, char *s, char *strbeg, char *strend, char explicit_length = TRUE; redo_switch: beyond = s >= strend; - { - struct packsize_t *pack_props = - &packsize[(symptr->code & TYPE_IS_SHRIEKING) ? - PACK_SIZE_SHRIEKING : PACK_SIZE_NORMAL]; - const int rawtype = TYPE_NO_MODIFIERS(datumtype); - int offset = rawtype - pack_props->first; - - if (offset >= 0 && offset < pack_props->size) { - /* Data about this template letter */ - unsigned char data = pack_props->array[offset]; - - if (data) { - /* data nonzero means we can process this letter. */ - long size = data & PACK_SIZE_MASK; - long howmany = (strend - s) / size; - if (len > howmany) - len = howmany; - - if (!checksum || (data & PACK_SIZE_CANNOT_CSUM)) { - if (len && unpack_only_one) len = 1; - EXTEND(SP, len); - EXTEND_MORTAL(len); - } - } + + props = packprops[TYPE_NO_ENDIANNESS(datumtype)]; + if (props) { + /* props nonzero means we can process this letter. */ + long size = props & PACK_SIZE_MASK; + long howmany = (strend - s) / size; + if (len > howmany) + len = howmany; + + if (!checksum || (props & PACK_SIZE_CANNOT_CSUM)) { + if (len && unpack_only_one) len = 1; + EXTEND(SP, len); + EXTEND_MORTAL(len); } } + switch(TYPE_NO_ENDIANNESS(datumtype)) { default: Perl_croak(aTHX_ "Invalid type '%c' in unpack", (int)TYPE_NO_MODIFIERS(datumtype) ); @@ -2435,23 +2459,13 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) } if (len) { - struct packsize_t *pack_props = - &packsize[(symptr->code & TYPE_IS_SHRIEKING) ? - PACK_SIZE_SHRIEKING : PACK_SIZE_NORMAL]; - const int rawtype = TYPE_NO_MODIFIERS(datumtype); - int offset = rawtype - pack_props->first; - - if (offset >= 0 && offset < pack_props->size) { - /* Data about this template letter */ - unsigned char data = pack_props->array[offset]; - - if (data && !(data & PACK_SIZE_UNPREDICTABLE)) { - /* We can process this letter. */ - STRLEN size = data & PACK_SIZE_MASK; - GROWING(utf8, cat, start, cur, (STRLEN) len * size); - } - } + packprops_t props = packprops[TYPE_NO_ENDIANNESS(datumtype)]; + if (props && !(props & PACK_SIZE_UNPREDICTABLE)) { + /* We can process this letter. */ + STRLEN size = props & PACK_SIZE_MASK; + GROWING(utf8, cat, start, cur, (STRLEN) len * size); + } } /* Look ahead for next symbol. Do we have code/code? */