Skip to content

Commit 0bbd4a7

Browse files
committed
Update wasm
1 parent 280c407 commit 0bbd4a7

3 files changed

Lines changed: 41 additions & 57 deletions

File tree

docs/ctod.js

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
function sendInput() {
2-
wasmSendString(document.getElementById("ctod-input").value, 0);
3-
}
41

52
/// exported so webassembly can send strings to JS
63
function ctodSendString(ptr, len) {
@@ -10,27 +7,36 @@ function ctodSendString(ptr, len) {
107

118
// Don't display errors while user is still typing
129
let timer;
10+
let lastAction = 'paste';
1311

14-
function onCtodInput(str) {
15-
res = wasmSendString(str, 0);
12+
function onCtodInput(target, action) {
13+
res = wasmSendString(target.value, 0);
1614

1715
if (res == null) {
1816
return; // don't set timeout, input too big
1917
}
2018

21-
clearTimeout(timer);
22-
timer = setTimeout(() => {
23-
wasmSendString(str, 1);
24-
}, /*msec*/ 500);
19+
if (action == 'paste' || lastAction != 'paste')
20+
{
21+
clearTimeout(timer);
22+
timer = setTimeout(() => {
23+
wasmSendString(target.value, 1);
24+
lastAction = 'none';
25+
}, /*msec*/ action == 'paste' ? 0 : 500);
26+
}
27+
28+
lastAction = action;
2529
}
2630

27-
async function initWasm() {
28-
wasmInstance = loadWasm('ctod.wasm', { ctodSendString });
29-
document.getElementById('ctod-input').addEventListener('input', (ev) => onCtodInput(ev.target.value));
31+
async function initWasm()
32+
{
33+
loadWasm('ctod.wasm', { ctodSendString });
34+
const inputField = document.getElementById('ctod-input');
35+
inputField.addEventListener('input', (ev) => onCtodInput(ev.target, 'input'));
36+
inputField.addEventListener('paste', (ev) => onCtodInput(ev.target, 'paste'));
3037
}
3138

3239
window.addEventListener('load', (event) => {
33-
3440
initWasm();
3541

3642
// Make the tab key insert a '\t' instead of changing focus

docs/ctod.wasm

-450 KB
Binary file not shown.

docs/wasm.js

Lines changed: 22 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,55 @@
1-
/*
2-
import { WASI } from 'wasi';
3-
4-
// https://nodejs.org/api/wasi.html
5-
const wasi = new WASI({
6-
args: argv,
7-
env,
8-
preopens: {}
9-
});
10-
*/
11-
121
// Stubs for WASI, needed because tree-sitter uses `fwrite(stderr, ...)` for error printing
132
function clock_time_get() { return 0; }
143
function fd_close() { return 0; }
154
function fd_seek() { return 0; }
165
function fd_write() { return 0; }
176
function proc_exit() { return 0; }
187

19-
// Some WASI binaries require:
20-
// const importObject = { wasi_unstable: wasi.wasiImport };
21-
// const importObject = { wasi_snapshot_preview1: wasi.wasiImport };
22-
238
// Our own glue code
24-
function jsConsoleLog(ptr, len) { console.log(toJsString(ptr, len)); }
25-
function jsAbort(ptr, len) { throw new Error(toJsString(ptr, len)) }
9+
function jsConsoleLog(len, ptr) { console.log(toJsString(ptr, len)); }
10+
function jsConsoleError(len, ptr) { console.error(toJsString(ptr, len)); }
11+
function jsAbort(len, ptr) { throw new Error(toJsString(ptr, len)); }
2612
function jsGetTimeMillis() { return new Date().getTime(); }
2713

28-
var wasmInstance;
14+
var wasm;
2915

3016
function toJsString(ptr, len) {
3117
try {
32-
var buffer = new Uint8Array(wasmInstance.exports.memory.buffer, ptr, len);
33-
return string = new TextDecoder().decode(buffer);
18+
var buffer = new Uint8Array(wasm.exports.memory.buffer, ptr, len);
19+
return new TextDecoder().decode(buffer);
3420
} catch (err) {
35-
return "eh?";
21+
console.error(err);
22+
return "";
3623
}
3724
}
3825

3926
/// Send strings from JS to webassembly
4027
function wasmSendString(str, type) {
41-
const bytes = new TextEncoder().encode(str); // Encode in utf-8
42-
// Copy the string into memory allocated in the WebAssembly
43-
const ptr = wasmInstance.exports.getStringMessageBuffer();
44-
const len = wasmInstance.exports.getStringMessageBufferLen();
45-
if (bytes.byteLength > len) {
28+
let buf = wasmStoreJsString(str, wasm.exports.getStringMessageBuffer(), wasm.exports.getStringMessageBufferLen())
29+
wasm.exports.receiveStringMessage(buffer.byteOffset, bytes.byteLength + 1, type);
30+
return buffer;
31+
}
32+
33+
function wasmStoreJsString(str, ptr, len) {
34+
const bytes = new TextEncoder().encode(str);
35+
if (bytes.byteLength > len)
36+
{
4637
alert("input too big, must be at most " + len + " bytes") // #meh
4738
return null;
4839
}
49-
const buffer = new Uint8Array(wasmInstance.exports.memory.buffer, ptr, bytes.byteLength + 1); // '0' terminator
40+
const buffer = new Uint8Array(wasm.exports.memory.buffer, ptr, bytes.byteLength + 1); // '0' terminator
5041
buffer.set(bytes);
5142
buffer[bytes.byteLength] = 0; // while Uint8Array is initialized to 0, don't rely on that
52-
wasmInstance.exports.receiveStringMessage(buffer.byteOffset, bytes.byteLength + 1, type);
5343
return buffer;
5444
}
5545

5646
async function loadWasm(fileName, imports) {
5747
const importObject = {
5848
wasi_snapshot_preview1: { clock_time_get, fd_close, fd_seek, fd_write, proc_exit },
59-
env: { ...imports, jsConsoleLog, jsAbort, jsGetTimeMillis }
49+
env: { ...imports, jsConsoleLog, jsConsoleError, jsAbort, jsGetTimeMillis }
6050
};
61-
const fetchPromise = new Promise(resolve => {
62-
var request = new XMLHttpRequest();
63-
request.open('GET', fileName);
64-
request.responseType = 'arraybuffer';
65-
request.onload = e => resolve(request.response);
66-
request.onerror = function () {
67-
resolve(undefined);
68-
console.error("Could not retrieve WebAssembly object");
69-
};
70-
request.send();
71-
})
7251

73-
const buffer = await fetchPromise;
74-
const module = await WebAssembly.compile(buffer);
75-
wasmInstance = await WebAssembly.instantiate(module, importObject);
76-
return wasmInstance;
52+
const { instance } = await WebAssembly.instantiateStreaming(fetch(fileName), importObject);
53+
wasm = instance;
54+
return instance;
7755
}

0 commit comments

Comments
 (0)