Finished removing data classes, use packed tables directly

This commit is contained in:
Vitaly Puzrin 2014-03-13 03:10:51 +04:00
parent 8ce9f4fb3c
commit 8a49fcd212
3 changed files with 89 additions and 87 deletions

View file

@ -89,8 +89,8 @@ module.exports = function inflate_fast(strm, start) {
window = state.window; window = state.window;
hold = state.hold; hold = state.hold;
bits = state.bits; bits = state.bits;
lcode = state.lencode.data; lcode = state.lencode;
dcode = state.distcode.data; dcode = state.distcode;
lmask = (1 << state.lenbits) - 1; lmask = (1 << state.lenbits) - 1;
dmask = (1 << state.distbits) - 1; dmask = (1 << state.distbits) - 1;

View file

@ -100,28 +100,6 @@ function ZSWAP32(q) {
} }
function Code() {
this.op = 0; /* operation, extra bits, table bits */
this.bits = 0; /* bits in this part of the code */
this.val = 0; /* offset in table or code value */
}
function CodeTable(length) {
// Packed data: [ bits, op, value], 1byte + 1byte +2 bytes
this.data = utils.array32Create(length);
}
CodeTable.prototype.fill = function(idx, code) {
var packed = this.data[idx];
code.bits = packed >>> 24;
code.op = (packed >>> 16) & 0xff;
code.val = packed & 0xffff;
};
CodeTable.prototype.copy = function(table) {
utils.arraySet(this.data, table.data, 0, table.data.length, 0);
};
function InflateState() { function InflateState() {
this.mode = 0; /* current inflate mode */ this.mode = 0; /* current inflate mode */
this.last = false; /* true if processing last block */ this.last = false; /* true if processing last block */
@ -172,7 +150,7 @@ function InflateState() {
this.work = utils.array16Create(280); /* work area for code table building */ this.work = utils.array16Create(280); /* work area for code table building */
// TODO: 8 or 16 bits? // TODO: 8 or 16 bits?
this.codes = new CodeTable(ENOUGH); /* space for code tables */ this.codes = utils.array32Create(ENOUGH); /* space for code tables */
this.sane = 0; /* if false, allow invalid distance too far */ this.sane = 0; /* if false, allow invalid distance too far */
this.back = 0; /* bits back of last unprocessed length/lit */ this.back = 0; /* bits back of last unprocessed length/lit */
this.was = 0; /* initial length of match */ this.was = 0; /* initial length of match */
@ -210,8 +188,8 @@ function inflateResetKeep(strm) {
//state.lencode = state.distcode = state.next = state.codes; //state.lencode = state.distcode = state.next = state.codes;
//utils.arraySet(state.lencode,state.codes,0,state.codes.length,0); //utils.arraySet(state.lencode,state.codes,0,state.codes.length,0);
//utils.arraySet(state.distcode,state.codes,0,state.codes.length,0); //utils.arraySet(state.distcode,state.codes,0,state.codes.length,0);
state.lencode = new CodeTable(ENOUGH); state.lencode = utils.array32Create(ENOUGH);
state.distcode = new CodeTable(ENOUGH); state.distcode = utils.array32Create(ENOUGH);
state.sane = 1; state.sane = 1;
state.back = -1; state.back = -1;
@ -327,8 +305,8 @@ function fixedtables(state) {
if (virgin) { if (virgin) {
var sym, bits; var sym, bits;
lenfix = new CodeTable(512); lenfix = utils.array32Create(512);
distfix = new CodeTable(32); distfix = utils.array32Create(32);
/* literal/length table */ /* literal/length table */
sym = 0; sym = 0;
@ -426,7 +404,8 @@ function inflate(strm, flush) {
var copy; /* number of stored or match bytes to copy */ var copy; /* number of stored or match bytes to copy */
var from; /* where to copy match bytes from */ var from; /* where to copy match bytes from */
var from_source; var from_source;
var here = new Code(); /* current decoding table entry */ var here = 0; /* current decoding table entry */
var here_bits, here_op, here_val;
//var last; /* parent table entry */ //var last; /* parent table entry */
var last_bits, last_op, last_val; // paked "last" denormalized var last_bits, last_op, last_val; // paked "last" denormalized
var len; /* length to copy for repeats, bits to drop */ var len; /* length to copy for repeats, bits to drop */
@ -949,7 +928,8 @@ function inflate(strm, flush) {
//state.next = state.codes; //state.next = state.codes;
// TODO: // TODO:
//state.lencode = state.next; //state.lencode = state.next;
state.lencode.copy(state.codes); //state.lencode.copy(state.codes);
utils.arraySet(state.lencode, state.codes, 0, state.codes.length, 0);
state.lenbits = 7; state.lenbits = 7;
opts = new InfTableOptions(CODES, state.lens, 0, 19, state.lencode, 0, state.lenbits, state.work); opts = new InfTableOptions(CODES, state.lens, 0, 19, state.lencode, 0, state.lenbits, state.work);
@ -968,8 +948,12 @@ function inflate(strm, flush) {
case CODELENS: case CODELENS:
while (state.have < state.nlen + state.ndist) { while (state.have < state.nlen + state.ndist) {
for (;;) { for (;;) {
state.lencode.fill(hold & ((1 << state.lenbits) - 1), here);/*BITS(state.lenbits)*/ here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/
if ((here.bits) <= bits) { break; } here_bits = here >>> 24;
here_op = (here >>> 16) & 0xff;
here_val = here & 0xffff;
if ((here_bits) <= bits) { break; }
//--- PULLBYTE() ---// //--- PULLBYTE() ---//
if (have === 0) { break inf_leave; } if (have === 0) { break inf_leave; }
have--; have--;
@ -977,17 +961,17 @@ function inflate(strm, flush) {
bits += 8; bits += 8;
//---// //---//
} }
if (here.val < 16) { if (here_val < 16) {
//--- DROPBITS(here.bits) ---// //--- DROPBITS(here.bits) ---//
hold >>>= here.bits; hold >>>= here_bits;
bits -= here.bits; bits -= here_bits;
//---// //---//
state.lens[state.have++] = here.val; state.lens[state.have++] = here_val;
} }
else { else {
if (here.val === 16) { if (here_val === 16) {
//=== NEEDBITS(here.bits + 2); //=== NEEDBITS(here.bits + 2);
n = here.bits + 2; n = here_bits + 2;
while (bits < n) { while (bits < n) {
if (have === 0) { break inf_leave; } if (have === 0) { break inf_leave; }
have--; have--;
@ -996,8 +980,8 @@ function inflate(strm, flush) {
} }
//===// //===//
//--- DROPBITS(here.bits) ---// //--- DROPBITS(here.bits) ---//
hold >>>= here.bits; hold >>>= here_bits;
bits -= here.bits; bits -= here_bits;
//---// //---//
if (state.have === 0) { if (state.have === 0) {
strm.msg = 'invalid bit length repeat'; strm.msg = 'invalid bit length repeat';
@ -1011,9 +995,9 @@ function inflate(strm, flush) {
bits -= 2; bits -= 2;
//---// //---//
} }
else if (here.val === 17) { else if (here_val === 17) {
//=== NEEDBITS(here.bits + 3); //=== NEEDBITS(here.bits + 3);
n = here.bits + 3; n = here_bits + 3;
while (bits < n) { while (bits < n) {
if (have === 0) { break inf_leave; } if (have === 0) { break inf_leave; }
have--; have--;
@ -1022,8 +1006,8 @@ function inflate(strm, flush) {
} }
//===// //===//
//--- DROPBITS(here.bits) ---// //--- DROPBITS(here.bits) ---//
hold >>>= here.bits; hold >>>= here_bits;
bits -= here.bits; bits -= here_bits;
//---// //---//
len = 0; len = 0;
copy = 3 + (hold & 0x07);//BITS(3); copy = 3 + (hold & 0x07);//BITS(3);
@ -1034,7 +1018,7 @@ function inflate(strm, flush) {
} }
else { else {
//=== NEEDBITS(here.bits + 7); //=== NEEDBITS(here.bits + 7);
n = here.bits + 7; n = here_bits + 7;
while (bits < n) { while (bits < n) {
if (have === 0) { break inf_leave; } if (have === 0) { break inf_leave; }
have--; have--;
@ -1043,8 +1027,8 @@ function inflate(strm, flush) {
} }
//===// //===//
//--- DROPBITS(here.bits) ---// //--- DROPBITS(here.bits) ---//
hold >>>= here.bits; hold >>>= here_bits;
bits -= here.bits; bits -= here_bits;
//---// //---//
len = 0; len = 0;
copy = 11 + (hold & 0x7f);//BITS(7); copy = 11 + (hold & 0x7f);//BITS(7);
@ -1077,7 +1061,8 @@ function inflate(strm, flush) {
/* build code tables -- note: do not change the lenbits or distbits /* build code tables -- note: do not change the lenbits or distbits
values here (9 and 6) without reading the comments in inftrees.h values here (9 and 6) without reading the comments in inftrees.h
concerning the ENOUGH constants, which depend on those values */ concerning the ENOUGH constants, which depend on those values */
state.lencode.copy(state.codes); //state.lencode.copy(state.codes);
utils.arraySet(state.lencode, state.codes, 0, state.codes.length, 0);
state.lenbits = 9; state.lenbits = 9;
opts = new InfTableOptions(LENS, state.lens, 0, state.nlen,state.lencode,0, state.lenbits, state.work); opts = new InfTableOptions(LENS, state.lens, 0, state.nlen,state.lencode,0, state.lenbits, state.work);
@ -1093,7 +1078,8 @@ function inflate(strm, flush) {
} }
state.distbits = 6; state.distbits = 6;
state.distcode.copy(state.codes); //state.distcode.copy(state.codes);
utils.arraySet(state.distcode, state.codes, 0, state.codes.length, 0);
opts = new InfTableOptions(DISTS, state.lens, state.nlen, state.ndist, state.distcode,0, state.distbits, state.work); opts = new InfTableOptions(DISTS, state.lens, state.nlen, state.ndist, state.distcode,0, state.distbits, state.work);
ret = inflate_table(opts); ret = inflate_table(opts);
// state.next_index = opts.table_index; // state.next_index = opts.table_index;
@ -1141,8 +1127,12 @@ function inflate(strm, flush) {
} }
state.back = 0; state.back = 0;
for (;;) { for (;;) {
state.lencode.fill(hold & ((1 << state.lenbits) -1),here); /*BITS(state.lenbits)*/ here = state.lencode[hold & ((1 << state.lenbits) -1)]; /*BITS(state.lenbits)*/
if (here.bits <= bits) { break; } here_bits = here >>> 24;
here_op = (here >>> 16) & 0xff;
here_val = here & 0xffff;
if (here_bits <= bits) { break; }
//--- PULLBYTE() ---// //--- PULLBYTE() ---//
if (have === 0) { break inf_leave; } if (have === 0) { break inf_leave; }
have--; have--;
@ -1150,14 +1140,18 @@ function inflate(strm, flush) {
bits += 8; bits += 8;
//---// //---//
} }
if (here.op && (here.op & 0xf0) === 0) { if (here_op && (here_op & 0xf0) === 0) {
last_bits = here.bits; last_bits = here_bits;
last_op = here.op; last_op = here_op;
last_val = here.val; last_val = here_val;
for (;;) { for (;;) {
state.lencode.fill(last_val + here = state.lencode[last_val +
((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits), here); ((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)];
if ((last_bits + here.bits) <= bits) { break; } here_bits = here >>> 24;
here_op = (here >>> 16) & 0xff;
here_val = here & 0xffff;
if ((last_bits + here_bits) <= bits) { break; }
//--- PULLBYTE() ---// //--- PULLBYTE() ---//
if (have === 0) { break inf_leave; } if (have === 0) { break inf_leave; }
have--; have--;
@ -1172,30 +1166,30 @@ function inflate(strm, flush) {
state.back += last_bits; state.back += last_bits;
} }
//--- DROPBITS(here.bits) ---// //--- DROPBITS(here.bits) ---//
hold >>>= here.bits; hold >>>= here_bits;
bits -= here.bits; bits -= here_bits;
//---// //---//
state.back += here.bits; state.back += here_bits;
state.length = here.val; state.length = here_val;
if (here.op === 0) { if (here_op === 0) {
//Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
// "inflate: literal '%c'\n" : // "inflate: literal '%c'\n" :
// "inflate: literal 0x%02x\n", here.val)); // "inflate: literal 0x%02x\n", here.val));
state.mode = LIT; state.mode = LIT;
break; break;
} }
if (here.op & 32) { if (here_op & 32) {
//Tracevv((stderr, "inflate: end of block\n")); //Tracevv((stderr, "inflate: end of block\n"));
state.back = -1; state.back = -1;
state.mode = TYPE; state.mode = TYPE;
break; break;
} }
if (here.op & 64) { if (here_op & 64) {
strm.msg = 'invalid literal/length code'; strm.msg = 'invalid literal/length code';
state.mode = BAD; state.mode = BAD;
break; break;
} }
state.extra = here.op & 15; state.extra = here_op & 15;
state.mode = LENEXT; state.mode = LENEXT;
/* falls through */ /* falls through */
case LENEXT: case LENEXT:
@ -1222,8 +1216,12 @@ function inflate(strm, flush) {
/* falls through */ /* falls through */
case DIST: case DIST:
for (;;) { for (;;) {
state.distcode.fill(hold & ((1 << state.distbits) -1), here);/*BITS(state.distbits)*/ here = state.distcode[hold & ((1 << state.distbits) -1)];/*BITS(state.distbits)*/
if ((here.bits) <= bits) { break; } here_bits = here >>> 24;
here_op = (here >>> 16) & 0xff;
here_val = here & 0xffff;
if ((here_bits) <= bits) { break; }
//--- PULLBYTE() ---// //--- PULLBYTE() ---//
if (have === 0) { break inf_leave; } if (have === 0) { break inf_leave; }
have--; have--;
@ -1231,14 +1229,18 @@ function inflate(strm, flush) {
bits += 8; bits += 8;
//---// //---//
} }
if ((here.op & 0xf0) === 0) { if ((here_op & 0xf0) === 0) {
last_bits = here.bits; last_bits = here_bits;
last_op = here.op; last_op = here_op;
last_val = here.val; last_val = here_val;
for (;;) { for (;;) {
state.distcode.fill(last_val + here = state.distcode[last_val +
((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits), here); ((hold & ((1 << (last_bits + last_op)) -1))/*BITS(last.bits + last.op)*/ >> last_bits)];
if ((last_bits + here.bits) <= bits) { break; } here_bits = here >>> 24;
here_op = (here >>> 16) & 0xff;
here_val = here & 0xffff;
if ((last_bits + here_bits) <= bits) { break; }
//--- PULLBYTE() ---// //--- PULLBYTE() ---//
if (have === 0) { break inf_leave; } if (have === 0) { break inf_leave; }
have--; have--;
@ -1253,17 +1255,17 @@ function inflate(strm, flush) {
state.back += last_bits; state.back += last_bits;
} }
//--- DROPBITS(here.bits) ---// //--- DROPBITS(here.bits) ---//
hold >>>= here.bits; hold >>>= here_bits;
bits -= here.bits; bits -= here_bits;
//---// //---//
state.back += here.bits; state.back += here_bits;
if (here.op & 64) { if (here_op & 64) {
strm.msg = 'invalid distance code'; strm.msg = 'invalid distance code';
state.mode = BAD; state.mode = BAD;
break; break;
} }
state.offset = here.val; state.offset = here_val;
state.extra = (here.op) & 15; state.extra = (here_op) & 15;
state.mode = DISTEXT; state.mode = DISTEXT;
/* falls through */ /* falls through */
case DISTEXT: case DISTEXT:

View file

@ -120,13 +120,13 @@ module.exports = function inflate_table(opts)
//table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */ //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */
//table.bits[opts.table_index] = 1; //here.bits = (var char)1; //table.bits[opts.table_index] = 1; //here.bits = (var char)1;
//table.val[opts.table_index++] = 0; //here.val = (var short)0; //table.val[opts.table_index++] = 0; //here.val = (var short)0;
table.data[opts.table_index++] = (1 << 24) | (64 << 16) | 0; table[opts.table_index++] = (1 << 24) | (64 << 16) | 0;
//table.op[opts.table_index] = 64; //table.op[opts.table_index] = 64;
//table.bits[opts.table_index] = 1; //table.bits[opts.table_index] = 1;
//table.val[opts.table_index++] = 0; //table.val[opts.table_index++] = 0;
table.data[opts.table_index++] = (1 << 24) | (64 << 16) | 0; table[opts.table_index++] = (1 << 24) | (64 << 16) | 0;
opts.bits = 1; opts.bits = 1;
return 0; /* no symbols, but wait for decoding to report error */ return 0; /* no symbols, but wait for decoding to report error */
@ -256,7 +256,7 @@ module.exports = function inflate_table(opts)
min = fill; /* save offset to next table */ min = fill; /* save offset to next table */
do { do {
fill -= incr; fill -= incr;
table.data[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0; table[next + (huff >> drop) + fill] = (here_bits << 24) | (here_op << 16) | here_val |0;
} while (fill !== 0); } while (fill !== 0);
/* backwards increment the len-bit code huff */ /* backwards increment the len-bit code huff */
@ -310,7 +310,7 @@ module.exports = function inflate_table(opts)
/*table.op[low] = curr; /*table.op[low] = curr;
table.bits[low] = root; table.bits[low] = root;
table.val[low] = next - opts.table_index;*/ table.val[low] = next - opts.table_index;*/
table.data[low] = (root << 24) | (curr << 16) | (next - opts.table_index); table[low] = (root << 24) | (curr << 16) | (next - opts.table_index);
} }
} }
@ -321,7 +321,7 @@ module.exports = function inflate_table(opts)
//table.op[next + huff] = 64; /* invalid code marker */ //table.op[next + huff] = 64; /* invalid code marker */
//table.bits[next + huff] = len - drop; //table.bits[next + huff] = len - drop;
//table.val[next + huff] = 0; //table.val[next + huff] = 0;
table.data[next + huff] = ((len - drop) << 24) | (64 << 16) | 0; table[next + huff] = ((len - drop) << 24) | (64 << 16) | 0;
} }
/* set return parameters */ /* set return parameters */