146 lines · 3.9 KB · JavaScript
RawDownload
 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(); }