let kmodule;let parent, proc; // parent and child processlet mem;let zombie = 0;let sharedArray;let sharedLock; let wasmImport = { env: { log_writeln: (fd, buffer, n) => console.log(stringAt(buffer, n)), tty_read: (fd, buffer, n) => { let consumer = Atomics.load(sharedLock, 0); while (Atomics.load(sharedLock, 1) == consumer) { Atomics.wait(sharedLock, 1, consumer, 1000000); } let array = new Uint8Array(mem.buffer, buffer, n); let j = 0; let producer = Atomics.load(sharedLock, 1); let size = sharedArray.length; while (j < n && consumer < producer) { //console.log(consumer+" read="+sharedArray[consumer]); array[j++] = sharedArray[(consumer++) % size]; } Atomics.store(sharedLock, 0, consumer); return j; }, tty_write: (fd, buffer, n) => { var data = stringAt(buffer, n); //TODO: translate \n when converting from Uint8 array instead of current separate step data = data.replace(/\n/gi, "\r\n"); sharedLock[2] = buffer; sharedLock[3] = n; postMessage(data);//t.io.print(data); return n; }, clock_gettime: (clock_id, timespec) => { return -1; }, osfork: () => { if (zombie) throw ("cannot fork"); const buf = proc.exports.memory.buffer; const mem = parent.exports.memory mem.grow((buf.byteLength - mem.buffer.byteLength) / 65536) const dest = new Uint32Array(mem.buffer); dest.set(new Uint32Array(buf)); zombie++; return 0; // thread returns as parent process }, osexec: (cmd, argc, argv) => { try { const func = proc.exports[cmd+"_main"]; func(argc, argv); } catch (e) { if (zombie) { const p = proc; proc = parent; parent = p; zombie--; } } }, osreboot: (cmd, argv) => { throw ("reboot: "+cmd); }, _exit: (status) => { throw "_exit: status="+status; }, cleanexit: (status) => { throw "exit: status="+status; }, sysfault: (buffer, ptr) => { var msg = (new TextDecoder().decode(new Uint8Array(mem.buffer, buffer, 30))); throw ("sys: "+msg+" "+(ptr|0)); }, js_call0: (call_nr) => { console.log("sys_call: nr="+call_nr) return -1; }, js_call1: (call_nr, a) => { console.log("sys_call: nr="+call_nr+" a=0x"+a.toString(16)) return -1; }, js_call2: (call_nr, a, b) => { console.log("sys_call: nr="+call_nr+" a=0x"+a.toString(16)+" b=0x"+b.toString(16)) return -1; }, js_call3: (call_nr, a, b, c) => { console.log("sys_call: nr="+call_nr+" a=0x"+a.toString(16)+" b0x="+b.toString(16)+" c=0x"+c.toString(16)) return -1; }, js_call4: (call_nr, a, b, c, d) => { console.log("sys_call: nr="+call_nr+" a="+a+" b="+b+" c="+c+" d="+d) return -1; }, js_call5: (call_nr, a, b, c, d, e) => { console.log("sys_call: nr="+call_nr+" a="+a+" b="+b+" c="+c+" d="+d+" e="+e) return -1; }, js_call6: (call_nr, a, b, c, d, e, f) => { console.log("sys_call: nr="+call_nr+" a="+a+" b="+b+" c="+c+" d="+d+" e="+e+" f="+f) return -1; }, }}; function stringAt(buffer, n) { return n > 0 ? (new TextDecoder().decode(new Uint8Array(mem.buffer, buffer, n))) : "";} function init() { ( async () => { if (!kmodule) { const { module, instance } = await WebAssembly.instantiateStreaming(fetch('emu.wasm'), wasmImport); kmodule = module; parent = instance; mem = parent.exports.memory; //parent.exports.kmain(0, 0); } if (!proc) { const instance = await WebAssembly.instantiate(kmodule, wasmImport); const buffer = parent.exports.memory.buffer; mem = instance.exports.memory mem.grow((buffer.byteLength - mem.buffer.byteLength) / 65536) const ubytes = new Uint32Array(mem.buffer); ubytes.set(new Uint32Array(buffer)); proc = instance; proc.exports._start(); } console.log('Worker: Posting message back to main script\n'); postMessage(count); })(); } onmessage = function(m) { sharedArray = new Uint8Array(m.data, 32); sharedLock = new Int32Array(m.data, 0, 32); console.log('[WORKER] Received SharedArrayBuffer ' + m.data) init(); }
let kmodule;
let parent, proc; // parent and child process
let mem;
let zombie = 0;
let sharedArray;
let sharedLock;
let wasmImport = {
env: {
log_writeln: (fd, buffer, n) => console.log(stringAt(buffer, n)),
tty_read: (fd, buffer, n) => {
let consumer = Atomics.load(sharedLock, 0);
while (Atomics.load(sharedLock, 1) == consumer) {
Atomics.wait(sharedLock, 1, consumer, 1000000);
}
let array = new Uint8Array(mem.buffer, buffer, n);
let j = 0;
let producer = Atomics.load(sharedLock, 1);
let size = sharedArray.length;
while (j < n && consumer < producer) {
//console.log(consumer+" read="+sharedArray[consumer]);
array[j++] = sharedArray[(consumer++) % size];
}
Atomics.store(sharedLock, 0, consumer);
return j;
},
tty_write: (fd, buffer, n) => {
var data = stringAt(buffer, n);
//TODO: translate \n when converting from Uint8 array instead of current separate step
data = data.replace(/\n/gi, "\r\n");
sharedLock[2] = buffer;
sharedLock[3] = n;
postMessage(data);//t.io.print(data);
return n;
},
clock_gettime: (clock_id, timespec) => {
return -1;
},
osfork: () => {
if (zombie) throw ("cannot fork");
const buf = proc.exports.memory.buffer;
const mem = parent.exports.memory
mem.grow((buf.byteLength - mem.buffer.byteLength) / 65536)
const dest = new Uint32Array(mem.buffer);
dest.set(new Uint32Array(buf));
zombie++;
return 0; // thread returns as parent process
},
osexec: (cmd, argc, argv) => {
try {
const func = proc.exports[cmd+"_main"];
func(argc, argv);
} catch (e) {
if (zombie) {
const p = proc;
proc = parent;
parent = p;
zombie--;
}
}
},
osreboot: (cmd, argv) => {
throw ("reboot: "+cmd);
},
_exit: (status) => {
throw "_exit: status="+status;
},
cleanexit: (status) => {
throw "exit: status="+status;
},
sysfault: (buffer, ptr) => {
var msg = (new TextDecoder().decode(new Uint8Array(mem.buffer, buffer, 30)));
throw ("sys: "+msg+" "+(ptr|0));
},
js_call0: (call_nr) => {
console.log("sys_call: nr="+call_nr)
return -1;
},
js_call1: (call_nr, a) => {
console.log("sys_call: nr="+call_nr+" a=0x"+a.toString(16))
return -1;
},
js_call2: (call_nr, a, b) => {
console.log("sys_call: nr="+call_nr+" a=0x"+a.toString(16)+" b=0x"+b.toString(16))
return -1;
},
js_call3: (call_nr, a, b, c) => {
console.log("sys_call: nr="+call_nr+" a=0x"+a.toString(16)+" b0x="+b.toString(16)+" c=0x"+c.toString(16))
return -1;
},
js_call4: (call_nr, a, b, c, d) => {
console.log("sys_call: nr="+call_nr+" a="+a+" b="+b+" c="+c+" d="+d)
return -1;
},
js_call5: (call_nr, a, b, c, d, e) => {
console.log("sys_call: nr="+call_nr+" a="+a+" b="+b+" c="+c+" d="+d+" e="+e)
return -1;
},
js_call6: (call_nr, a, b, c, d, e, f) => {
console.log("sys_call: nr="+call_nr+" a="+a+" b="+b+" c="+c+" d="+d+" e="+e+" f="+f)
return -1;
},
}
};
function stringAt(buffer, n) {
return n > 0 ? (new TextDecoder().decode(new Uint8Array(mem.buffer, buffer, n))) : "";
}
function init() {
(
async () => {
if (!kmodule) {
const { module, instance } = await WebAssembly.instantiateStreaming(fetch('emu.wasm'), wasmImport);
kmodule = module;
parent = instance;
mem = parent.exports.memory;
//parent.exports.kmain(0, 0);
}
if (!proc) {
const instance = await WebAssembly.instantiate(kmodule, wasmImport);
const buffer = parent.exports.memory.buffer;
mem = instance.exports.memory
mem.grow((buffer.byteLength - mem.buffer.byteLength) / 65536)
const ubytes = new Uint32Array(mem.buffer);
ubytes.set(new Uint32Array(buffer));
proc = instance;
proc.exports._start();
}
console.log('Worker: Posting message back to main script\n');
postMessage(count);
})();
}
onmessage = function(m) {
sharedArray = new Uint8Array(m.data, 32);
sharedLock = new Int32Array(m.data, 0, 32);
console.log('[WORKER] Received SharedArrayBuffer ' + m.data)
init();
}