Skip to content

Commit

Permalink
[js] Fix variable length integer serialization/deserialization.
Browse files Browse the repository at this point in the history
  • Loading branch information
pmurias committed Nov 4, 2015
1 parent c2d1459 commit c332679
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 10 deletions.
9 changes: 6 additions & 3 deletions src/vm/js/nqp-runtime/deserialization.js
Expand Up @@ -232,16 +232,19 @@ BinaryCursor.prototype.varint = function() {
return result;
}

result = first << 8 * need;
result = (first & 0x0F) << 8 * need;

var shift_places = 0;
for (var i = 0; i < need; i++) {
var byte = buffer.readUInt8(this.offset++);
result |= (byte << shift_places);
shift_places += 8;
}
result = result << (64 - 4 - 8 * need);
result = result >> (64 - 4 - 8 * need);

if (need < 4) {
result = result << (64 - 4 - 8 * need);
result = result >> (64 - 4 - 8 * need);
}

return result;
};
Expand Down
2 changes: 1 addition & 1 deletion src/vm/js/nqp-runtime/nqp-int.js
@@ -1,5 +1,5 @@
function NQPInt(value) {
this.value = value;
this.value = value|0;
}

NQPInt.prototype.Int = function(ctx) {
Expand Down
2 changes: 1 addition & 1 deletion src/vm/js/nqp-runtime/reprs.js
Expand Up @@ -653,7 +653,7 @@ P6bigint.prototype.type_object_for = function(HOW) {
});

this._STable.addInternalMethod('$$get_int', function() {
return this.value.toNumber();
return this.value.toNumber()|0;
});

this._STable.addInternalMethod('$$set_bignum', function(value) {
Expand Down
14 changes: 9 additions & 5 deletions src/vm/js/nqp-runtime/serialization.js
@@ -1,6 +1,7 @@
var Hash = require('./hash.js');
var CodeRef = require('./code-ref.js');
var NQPInt = require('./nqp-int.js');
var Int64 = require('node-int64');

var op = {};
exports.op = op;
Expand Down Expand Up @@ -111,16 +112,21 @@ BinaryWriteCursor.prototype.varint = function(value) {
this.I64(value);
} else {
var rest = storage_needed - 1;
var nybble = value >> 8 * rest;
var nybble = rest == 4 ? 0 : value >> 8 * rest;

/* All the other high bits should be the same as the top bit of the
nybble we keep. Or we have a bug. */

console.assert((nybble >> 3) == 0 || (nybble >> 3) == ~0);

this.I8((rest << 4) | (nybble & 0xF));

var tmp = new Int64(value).toBuffer();
this.growToHold(rest);
this.buffer.writeIntLE(value, this.offset, rest, true);
for (var i = 0; i < rest; i++) {
this.buffer[this.offset+i] = tmp[8-(i+1)];
}

this.offset += rest;
}
};
Expand Down Expand Up @@ -297,9 +303,7 @@ BinaryWriteCursor.prototype.ref = function(ref) {
// discrim = REFVAR_VM_NULL;
// }
else if (ref instanceof NQPInt) {
// HACK
ref = ref.value;
discrim = REFVAR_VM_NUM;
discrim = REFVAR_VM_INT;
}
else if (typeof ref == 'number') {
discrim = REFVAR_VM_NUM;
Expand Down
14 changes: 14 additions & 0 deletions t/js/varint.js
Expand Up @@ -32,6 +32,20 @@ check(30, [159]);
check(126, [255]);
check(200, [16,200]);
check(-200, [31,56]);
check(653, [18,141]);
check(668, [18,156]);
check(-4096, [47,0,240]);
check(10000, [32,16,39]);
check(-10000, [47,240,216]);
check(1000000, [48,64,66,15]);
check(-33554432, [62,0,0,0]);
check(134217724, [55,252,255,255]);
check(-134217724, [56,4,0,0]);
check(134217725, [55,253,255,255]);
check(-134217725, [56,3,0,0]);
check(134217726, [55,254,255,255]);
check(-134217726, [56,2,0,0]);
check(134217727, [55,255,255,255]);
check(-134217727, [56,1,0,0]);
check(134217728, [64,0,0,0,8]);
check(2147483647, [64,255,255,255,127]);

0 comments on commit c332679

Please sign in to comment.