Skip to content

Commit

Permalink
Encoding: use Wasm to get a SharedArrayBuffer instance
Browse files Browse the repository at this point in the history
For #22358.
  • Loading branch information
annevk committed Mar 20, 2020
1 parent 374da1f commit 9774d70
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 23 deletions.
44 changes: 31 additions & 13 deletions encoding/encodeInto.any.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
function createBuffer(type, length = 0) {
if (type === "ArrayBuffer") {
return new ArrayBuffer(length);
} else {
// See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()`
// WebAssembly.Memory's size is in multiples of 64 KiB
return new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer;
}
}

function createViewWithBuffer(type, length) {
if (type === "ArrayBuffer") {
return new Uint8Array(new ArrayBuffer(length));
} else {
return new Uint8Array(createBuffer(type), 0, length);
}
}

[
{
"input": "Hi",
Expand Down Expand Up @@ -77,15 +95,15 @@
["ArrayBuffer", "SharedArrayBuffer"].forEach(arrayBufferOrSharedArrayBuffer => {
test(() => {
// Setup
const bufferLength = testData.destinationLength + destinationData.bufferIncrease,
destinationOffset = destinationData.destinationOffset,
destinationLength = testData.destinationLength,
destinationFiller = destinationData.filler,
encoder = new TextEncoder(),
buffer = new self[arrayBufferOrSharedArrayBuffer](bufferLength),
view = new Uint8Array(buffer, destinationOffset, destinationLength),
fullView = new Uint8Array(buffer),
control = new Array(bufferLength);
const bufferLength = testData.destinationLength + destinationData.bufferIncrease;
const destinationOffset = destinationData.destinationOffset;
const destinationLength = testData.destinationLength;
const destinationFiller = destinationData.filler;
const encoder = new TextEncoder();
const buffer = createBuffer(arrayBufferOrSharedArrayBuffer, bufferLength);
const view = new Uint8Array(buffer, destinationOffset, destinationLength);
const fullView = new Uint8Array(buffer);
const control = new Array(bufferLength);
let byte = destinationFiller;
for (let i = 0; i < bufferLength; i++) {
if (destinationFiller === "random") {
Expand All @@ -105,6 +123,8 @@
// Remainder
assert_equals(result.read, testData.read);
assert_equals(result.written, testData.written.length);
// This will not check the entire buffer allocated by WebAssembly.Memory, but we'll trust
// that this is sufficient.
for (let i = 0; i < bufferLength; i++) {
if (i < destinationOffset || i >= (destinationOffset + testData.written.length)) {
assert_equals(fullView[i], control[i]);
Expand All @@ -128,19 +148,17 @@
Float64Array].forEach(view => {
["ArrayBuffer", "SharedArrayBuffer"].forEach((arrayBufferOrSharedArrayBuffer) => {
test(() => {
assert_throws_js(TypeError, () => new TextEncoder().encodeInto("", new view(new self[arrayBufferOrSharedArrayBuffer](0))));
assert_throws_js(TypeError, () => new TextEncoder().encodeInto("", createViewWithBuffer(arrayBufferOrSharedArrayBuffer, 0)));
}, "Invalid encodeInto() destination: " + view.name + ", backed by: " + arrayBufferOrSharedArrayBuffer);
});
});

["ArrayBuffer", "SharedArrayBuffer"].forEach((arrayBufferOrSharedArrayBuffer) => {
test(() => {
assert_throws_js(TypeError, () => new TextEncoder().encodeInto("", new self[arrayBufferOrSharedArrayBuffer](10)));
assert_throws_js(TypeError, () => new TextEncoder().encodeInto("", createBuffer(arrayBufferOrSharedArrayBuffer, 10)));
}, "Invalid encodeInto() destination: " + arrayBufferOrSharedArrayBuffer);
});



test(() => {
const buffer = new ArrayBuffer(10),
view = new Uint8Array(buffer);
Expand Down
19 changes: 15 additions & 4 deletions encoding/streams/decode-utf8.any.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,22 @@
'use strict';

["ArrayBuffer", "SharedArrayBuffer"].forEach((arrayBufferOrSharedArrayBuffer) => {
const inputChunkData = [73, 32, 240, 159, 146, 153, 32, 115, 116,
114, 101, 97, 109, 115]
const inputChunkData = [73, 32, 240, 159, 146, 153, 32, 115, 116, 114, 101, 97, 109, 115];

const emptyChunk = new Uint8Array(new self[arrayBufferOrSharedArrayBuffer](0));
const inputChunk = new Uint8Array(new self[arrayBufferOrSharedArrayBuffer](inputChunkData.length));
function createViewWithBuffer(type, length) {
if (type === "ArrayBuffer") {
return new Uint8Array(new ArrayBuffer(length));
} else {
// See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()`
// WebAssembly.Memory's size is in multiples of 64 KiB
const size = (length === 0) ? 0 : 1;
const buffer = new WebAssembly.Memory({ shared:true, initial:size, maximum:size }).buffer;
return new Uint8Array(buffer, 0, length);
}
}

const emptyChunk = createViewWithBuffer(arrayBufferOrSharedArrayBuffer, 0);
const inputChunk = createViewWithBuffer(arrayBufferOrSharedArrayBuffer, inputChunkData.length);

inputChunk.set(inputChunkData);

Expand Down
21 changes: 16 additions & 5 deletions encoding/textdecoder-copy.any.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
function createViewWithBuffer(type, length) {
if (type === "ArrayBuffer") {
return new Uint8Array(new ArrayBuffer(length));
} else {
// See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()`
// WebAssembly.Memory's size is in multiples of 64 KiB
const buffer = new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer;
return new Uint8Array(buffer, 0, length);
}
}

["ArrayBuffer", "SharedArrayBuffer"].forEach(arrayBufferOrSharedArrayBuffer => {
test(() => {
const buf = new self[arrayBufferOrSharedArrayBuffer](2),
view = new Uint8Array(buf),
buf2 = new self[arrayBufferOrSharedArrayBuffer](2),
view2 = new Uint8Array(buf2),
decoder = new TextDecoder("utf-8");
const view = createViewWithBuffer(arrayBufferOrSharedArrayBuffer, 2);
const buf = view.buffer;
const view2 = createViewWithBuffer(arrayBufferOrSharedArrayBuffer, 2);
const buf2 = view2.buffer;
const decoder = new TextDecoder("utf-8");
view[0] = 0xEF;
view[1] = 0xBB;
view2[0] = 0xBF;
Expand Down
13 changes: 12 additions & 1 deletion encoding/textdecoder-streaming.any.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ var octets = {
0xDF,0xFF]
};

function createViewWithBuffer(type, length) {
if (type === "ArrayBuffer") {
return new Uint8Array(new ArrayBuffer(length));
} else {
// See https://github.com/whatwg/html/issues/5380 for why not `new SharedArrayBuffer()`
// WebAssembly.Memory's size is in multiples of 64 KiB
const buffer = new WebAssembly.Memory({ shared:true, initial:1, maximum:1 }).buffer;
return new Uint8Array(buffer, 0, length);
}
}

["ArrayBuffer", "SharedArrayBuffer"].forEach((arrayBufferOrSharedArrayBuffer) => {
Object.keys(octets).forEach(function(encoding) {
for (var len = 1; len <= 5; ++len) {
Expand All @@ -28,7 +39,7 @@ var octets = {
var sub = [];
for (var j = i; j < encoded.length && j < i + len; ++j)
sub.push(encoded[j]);
var uintArray = new Uint8Array(new self[arrayBufferOrSharedArrayBuffer](sub.length));
var uintArray = createViewWithBuffer(arrayBufferOrSharedArrayBuffer, sub.length);
uintArray.set(sub);
out += decoder.decode(uintArray, {stream: true});
}
Expand Down

0 comments on commit 9774d70

Please sign in to comment.