-
Notifications
You must be signed in to change notification settings - Fork 1
/
small.js
78 lines (65 loc) · 2.55 KB
/
small.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
export {toBytes, toBase64};
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const bytesPerPage = 65536;
let wasm64 =
'AGFzbQEAAAABCgJgAX8AYAJ/fwACEwEHaW1wb3J0cwZtZW1vcnkCAAADAwIAAQcfAgxiYXNlNjQyYnl0' +
'ZXMAAAxieXRlczJiYXNlNjQAAQqzBAKUAgEDfwNAIAMgAkEDai0AACIBQQRqIAFBwABLQcUAbGsgAUHg' +
'AEtBBmxrIAFBK0ZBD2xqIAFBL0ZBDGxqIAItAAAiAUEEaiABQcAAS0HFAGxrIAFB4ABLQQZsayABQStG' +
'QQ9saiABQS9GQQxsakESdCACQQFqLQAAIgFBBGogAUHAAEtBxQBsayABQeAAS0EGbGsgAUErRkEPbGog' +
'AUEvRkEMbGpBDHRyIAJBAmotAAAiAUEEaiABQcAAS0HFAGxrIAFB4ABLQQZsayABQStGQQ9saiABQS9G' +
'QQxsakEGdHJyIgFBEHY6AAAgA0EBaiABQQh2OgAAIANBAmogAToAACADQQNqIQMgAkEEaiICIABJDQAL' +
'C5oCAQN/A0AgASADQQJqLQAAIAMtAABBEHQgA0EBai0AAEEIdHJyIgRBEnYiAkHBAGogAkEZS0EGbGog' +
'AkEzS0HLAGxrIAJBPkZBD2xrIAJBP0ZBDGxrOgAAIAFBAWogBEEMdkE/cSICQcEAaiACQRlLQQZsaiAC' +
'QTNLQcsAbGsgAkE+RkEPbGsgAkE/RkEMbGs6AAAgAUECaiAEQQZ2QT9xIgJBwQBqIAJBGUtBBmxqIAJB' +
'M0tBywBsayACQT5GQQ9sayACQT9GQQxsazoAACABQQNqIARBP3EiAkHBAGogAkEZS0EGbGogAkEzS0HL' +
'AGxrIAJBPkZBD2xrIAJBP0ZBDGxrOgAAIAFBBGohASADQQNqIgMgAEkNAAsL';
// meta: base64-decode the base64 decoder
// this takes ~0.2ms
let wasmStr = atob(wasm64);
let wasmBytes = new Uint8Array(
[...wasmStr].map((_, i) => wasmStr.charCodeAt(i))
);
// wasm takes ~1-2ms to compile
let wasmModule = WebAssembly.compile(wasmBytes);
async function toBytes(base64) {
base64 = base64.replace(/=/g, '');
let n = base64.length;
let rem = n % 4;
let k = rem && rem - 1;
let m = (n >> 2) * 3 + k;
let [{base642bytes}, memory] = await instantiate(n);
let encoded = new Uint8Array(memory.buffer, 0, n);
encoder.encodeInto(base64, encoded);
base642bytes(n);
return new Uint8Array(memory.buffer, 0, m);
}
async function toBase64(bytes) {
let m = bytes.length;
let k = m % 3;
let n = Math.floor(m / 3) * 4 + (k && k + 1);
let M = m + 2;
let N = Math.ceil(m / 3) * 4;
let [{bytes2base64}, memory] = await instantiate(M + N);
let decoded = new Uint8Array(memory.buffer, 0, M);
decoded.set(bytes);
decoded[m] = 0;
decoded[m + 1] = 0;
bytes2base64(m, M);
let encoded = new Uint8Array(memory.buffer, M, n);
let base64 = decoder.decode(encoded);
if (k === 1) base64 += '==';
if (k === 2) base64 += '=';
return base64;
}
// this takes ~0.1-0.5 ms after initial compile
async function instantiate(memSize) {
let memory = new WebAssembly.Memory({
initial: Math.ceil(memSize / bytesPerPage),
});
let compiled = await wasmModule;
let instance = await WebAssembly.instantiate(compiled, {
imports: {memory},
});
return [instance.exports, memory];
}