Skip to content

Commit

Permalink
[js] Implement nqp::writenum and nqp::readnum
Browse files Browse the repository at this point in the history
  • Loading branch information
pmurias committed Dec 26, 2018
1 parent c3bdccf commit 9efaa01
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/vm/js/Operations.nqp
Expand Up @@ -1925,6 +1925,8 @@ class QAST::OperationsJS {
add_simple_op('writeuint', $T_VOID, [$T_OBJ, $T_INT, $T_UINT32, $T_INT], :side_effects);
add_simple_op('readint', $T_INT, [$T_OBJ, $T_INT, $T_INT]);
add_simple_op('readuint', $T_UINT32, [$T_OBJ, $T_INT, $T_INT]);
add_simple_op('writenum', $T_VOID, [$T_OBJ, $T_INT, $T_NUM, $T_INT], :side_effects);
add_simple_op('readnum', $T_NUM, [$T_OBJ, $T_INT, $T_INT]);

method add_hll_unbox($hll, $type, $method_name) {
unless nqp::existskey(%hll_unbox, $hll) {
Expand Down
63 changes: 60 additions & 3 deletions src/vm/js/nqp-runtime/core.js
Expand Up @@ -1138,15 +1138,23 @@ function sizeFromFlags(flags) {
} else if (sizeFlags == BINARY_SIZE_32_BIT) {
return 4;
} else if (sizeFlags == BINARY_SIZE_64_BIT) {
throw new NQPException('64bit writeint is not supported');
return 8;
} else {
throw new NQPException('unsupported flags: ' + flags);
}
}

function intSizeFromFlags(flags) {
const size = sizeFromFlags(flags);
if (size === 8) {
throw new NQPException('BINARY_SIZE_64_BIT for (u)ints is not supported');
}
return size;
}

function writeIntToBuffer(isSigned, buffer, offset, value, flags) {

const sizeInBytes = sizeFromFlags(flags);
const sizeInBytes = intSizeFromFlags(flags);
const lowlevelBuffer = Buffer.alloc(sizeInBytes);

const isBigEndian = isBigEndianFromFlags(flags);
Expand Down Expand Up @@ -1181,11 +1189,60 @@ op.writeuint = function(buffer, offset, value, flags) {
};

op.readuint = function(buffer, offset, flags) {
const sizeInBytes = sizeFromFlags(flags);
const sizeInBytes = intSizeFromFlags(flags);
const rawData = rawSlice(buffer, offset, offset + sizeInBytes / byteSize(buffer));
return isBigEndianFromFlags(flags) ? rawData.readUIntBE(0, sizeInBytes) : rawData.readUIntLE(0, sizeInBytes);
};

op.writenum = function(buffer, offset, value, flags) {
const isBigEndian = isBigEndianFromFlags(flags);

const sizeInBytes = sizeFromFlags(flags);
const lowlevelBuffer = Buffer.alloc(sizeInBytes);

if (sizeInBytes == 4) {
if (isBigEndian) {
lowlevelBuffer.writeFloatBE(value, 0);
} else {
lowlevelBuffer.writeFloatLE(value, 0);
}
} else if (sizeInBytes == 8) {
if (isBigEndian) {
lowlevelBuffer.writeDoubleBE(value, 0);
} else {
lowlevelBuffer.writeDoubleLE(value, 0);
}
} else {
throw new NQPException('unsupported size: ' + sizeInBytes*8 + 'bits');
}

writeBuffer(buffer, offset, lowlevelBuffer);

};

op.readnum = function(buffer, offset, flags) {
const sizeInBytes = sizeFromFlags(flags);
const rawData = rawSlice(buffer, offset, offset + sizeInBytes / byteSize(buffer));
const isBigEndian = isBigEndianFromFlags(flags);

if (sizeInBytes == 4) {
if (isBigEndian) {
return rawData.readFloatBE(0);
} else {
return rawData.readFloatLE(0);
}
} else if (sizeInBytes == 8) {
if (isBigEndian) {
return rawData.readDoubleBE(0);
} else {
return rawData.readDoubleLE(0);
}
} else {
throw new NQPException('unsupported size: ' + sizeInBytes*8 + 'bits');
}
};


op.encodeconf = function(str, encoding_, output, permissive) {
if (output.array.length) {
throw new NQPException('encode requires an empty array');
Expand Down

0 comments on commit 9efaa01

Please sign in to comment.