diff --git a/vm/backend/tb.c b/vm/backend/tb.c index 959418fb..47edc59c 100644 --- a/vm/backend/tb.c +++ b/vm/backend/tb.c @@ -1679,17 +1679,17 @@ void *vm_tb_rfunc_comp(vm_rblock_t *rblock) { void *code = vm_cache_comp("emcc", cs, name); rblock->code = code; return code; - } else if (state->config->target == VM_TARGET_TB_JS) { - const char *js1 = tb_pass_js_prelude(state->module); - const char *js2 = tb_pass_js_fmt(passes); - size_t len1 = strlen(js1); - size_t len2 = strlen(js2); - char *buf = vm_malloc(len1 + len2 + 1); - memcpy(buf, js1, len1); - memcpy(buf + len1, js2, len2); - buf[len1 + len2] = '\0'; - rblock->code = buf; - return buf; + // } else if (state->config->target == VM_TARGET_TB_JS) { + // const char *js1 = tb_pass_js_prelude(state->module); + // const char *js2 = tb_pass_js_fmt(passes); + // size_t len1 = strlen(js1); + // size_t len2 = strlen(js2); + // char *buf = vm_malloc(len1 + len2 + 1); + // memcpy(buf, js1, len1); + // memcpy(buf + len1, js2, len2); + // buf[len1 + len2] = '\0'; + // rblock->code = buf; + // return buf; } else { __builtin_trap(); } diff --git a/vm/lua/repl.c b/vm/lua/repl.c index 1dc5e7e6..bc419214 100644 --- a/vm/lua/repl.c +++ b/vm/lua/repl.c @@ -240,6 +240,7 @@ void vm_lang_lua_repl(vm_config_t *config, vm_table_t *std, vm_blocks_t *blocks) }; while (true) { + #if !defined(EMSCRIPTEN) char *input = ic_readline_ex( "lua", vm_lang_lua_repl_completer, @@ -250,6 +251,30 @@ void vm_lang_lua_repl(vm_config_t *config, vm_table_t *std, vm_blocks_t *blocks) if (input == NULL) { break; } + #else + setvbuf(stdin, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + printf("lua> "); + char input[256]; + size_t head = 0; + while (true) { + char c = fgetc(stdin); + if (c == '\n' || c == '\r') { + c = '\0'; + printf("\n"); + } else if (c == 127) { + printf("\x1B[D \x1B[D"); + head -= 1; + } else { + printf("%c", (int) c); + } + input[head++] = c; + if (c == '\0') { + break; + } + } + #endif vm_lang_lua_repl_table_get_config(repl, config); ic_history_add(input); clock_t start = clock(); @@ -260,7 +285,9 @@ void vm_lang_lua_repl(vm_config_t *config, vm_table_t *std, vm_blocks_t *blocks) } vm_ast_node_t node = vm_lang_lua_parse(config, input); + #if !defined(EMSCRIPTEN) free(input); + #endif if (config->dump_ast) { vm_io_buffer_t buf = {0}; diff --git a/web.mak b/web.mak index b91083da..52c39f5e 100644 --- a/web.mak +++ b/web.mak @@ -2,7 +2,6 @@ EXE ?= .js CC = emcc TCC_SRCS = -ISOCLINE_SRCS = GLOBAL := -s EXPORT_ALL=1 CFLAGS := -fPIC -DNDEBUG $(GLOBLAL) $(CFLAGS) diff --git a/web/src/app/App.svelte b/web/src/app/App.svelte index 6f482a18..84f09367 100644 --- a/web/src/app/App.svelte +++ b/web/src/app/App.svelte @@ -3,17 +3,25 @@ import { onMount } from 'svelte'; import * as xterm from 'xterm'; import * as fit from 'xterm-addon-fit'; - import { Readline } from 'xterm-readline'; - import parse from 'bash-parser'; let terminalElement; let terminalController; let termFit; - + const thens = []; const comp = new Worker(new URL('../lib/wcomp.js', import.meta.url)); - const lua = (args) => new Promise((ok, err) => { + const unmap = (c) => { + if (c === '\n') { + return '\r\n'; + } else { + return c; + } + }; + + const lua = (args) => new Promise(async (ok, err) => { + const inexists = new SharedArrayBuffer(4); + const inbuf = new SharedArrayBuffer(4); const wait = new SharedArrayBuffer(4); const ret = new SharedArrayBuffer(65536); const worker = new Worker(new URL('../lib/wlua.js', import.meta.url)); @@ -27,12 +35,16 @@ }); worker.onmessage = async ({data}) => { switch (data.type) { + case 'got-stdin': { + Atomics.notify() + break; + } case 'stdout': { - rl.println(data.stdout); + terminalController.write(unmap(data.stdout)); break; } case 'stderr': { - rl.println(data.stdout); + terminalController.write(unmap(data.stdout)); break; } case 'exit-err': { @@ -56,6 +68,7 @@ type: 'buffer', ret: ret, wait: wait, + inbuf: inbuf, }); break; } @@ -68,38 +81,56 @@ } } }; - }); - - const loop = async (rl) => { + const inArray = []; + const i32buf = new Int32Array(inbuf); + const i32exists = new Int32Array(inexists); + terminalController.onData((data) => { + for (const c of data) { + inArray.push(c.charCodeAt(0)); + Atomics.notify(i32exists, 0, 1); + } + }); while (true) { - const res = await rl.read('$ '); - for (const {type, name, suffix} of parse(res).commands) { - if (type === 'SimpleCommand') { - switch (name) { - case 'lua': { - const args = []; - for (const obj of suffix) { - if (obj.type == 'Word') { - args.push(obj.text); - } else { - console.log(obj); - } - } - await lua(args); - break; - } - } - } + if (inArray.length === 0) { + await Atomics.waitAsync(i32exists, 0, 0).value; } + i32buf[0] = inArray.shift(); + Atomics.notify(i32buf, 0, 1); + await Atomics.waitAsync(i32buf, 0, i32buf[0]).value; } + }); + + const loop = async () => { + await lua(['--repl']); + // while (true) { + // const res = await rl.read('$ '); + // for (const {type, name, suffix} of parse(res).commands) { + // if (type === 'SimpleCommand') { + // switch (name) { + // case 'lua': { + // const args = []; + // for (const obj of suffix) { + // if (obj.type == 'Word') { + // args.push(obj.text); + // } else { + // console.log(obj); + // } + // } + // await lua(args); + // break; + // } + // } + // } + // } + // } }; const initalizeXterm = async() => { - const rl = new Readline(); + // const rl = new Readline(); terminalController = new xterm.Terminal(); termFit = new fit.FitAddon(); - terminalController.loadAddon(rl); + // terminalController.loadAddon(rl); terminalController.loadAddon(termFit); terminalController.open(terminalElement); termFit.fit(); @@ -119,7 +150,7 @@ }; }); - loop(rl); + loop(); }; onMount(async () => { diff --git a/web/src/index.js b/web/src/index.js index 584814ae..c7120ade 100644 --- a/web/src/index.js +++ b/web/src/index.js @@ -23,7 +23,11 @@ const fengari = (str) => { load(str)(); }; -window.minivm = lua; +const minivm = (str) => { + lua(str); +}; + +window.minivm = minivm; window.fengari = fengari; window.bench = (func, ...args) => { console.time(func.name); diff --git a/web/src/lib/comp.js b/web/src/lib/comp.js index ca4c7bba..291f1b19 100644 --- a/web/src/lib/comp.js +++ b/web/src/lib/comp.js @@ -16,10 +16,9 @@ let comps = 0; export const comp = (cBuf) => { comps += 1; emception.fileSystem.writeFile(`/working/in${comps}.c`, cBuf); - const result1 = emception.runx(`/usr/bin/clang -c ${flags1} /working/in${comps}.c -o /working/mid${comps}.o`); + const result1 = emception.runx(`/usr/bin/clang -O2 -c ${flags1} /working/in${comps}.c -o /working/mid${comps}.o`); if (result1.returncode !== 0) { console.error(`clang exited with code ${result1.returncode}`); - console.log(result1); } const result2 = emception.runx(`/usr/bin/wasm-ld --whole-archive /working/mid${comps}.o ${flags2} -o /working/out${comps}.wasm`); if (result2.returncode !== 0) { @@ -28,4 +27,4 @@ export const comp = (cBuf) => { return emception.fileSystem.readFile(`/working/out${comps}.wasm`); }; -comp('int main() {}'); +// comp('int main() {}'); diff --git a/web/src/lib/emception.js b/web/src/lib/emception.js index 38afb717..d3eb4b93 100644 --- a/web/src/lib/emception.js +++ b/web/src/lib/emception.js @@ -130,9 +130,6 @@ class Emception { ...opts, cwd: opts.cwd || "/", path: ["/emscripten"], - preRun: (mod) => { - console.log(mod); - }, }); this.fileSystem.push(); diff --git a/web/src/lib/lua.js b/web/src/lib/lua.js index 8d87d168..ce5f07ea 100644 --- a/web/src/lib/lua.js +++ b/web/src/lib/lua.js @@ -6,27 +6,35 @@ const wasmBuffer = await (await fetch(wasmBinary)).arrayBuffer(); export const run = (args, opts) => { const stdinFunc = () => { - return null; + return opts.stdin(); }; - let stdout = ''; + // let stdout = ''; + // const stdoutFunc = (c) => { + // if (c == 10) { + // opts.stdout(stdout); + // stdout = ''; + // } else { + // stdout += String.fromCharCode(c); + // } + // }; + + // let stderr = ''; + // const stderrFunc = (c) => { + // if (c == 10) { + // opts.stdout(stdout); + // stderr = ''; + // } else { + // stderr += String.fromCharCode(c); + // } + // }; + const stdoutFunc = (c) => { - if (c == 10) { - opts.stdout(stdout); - stdout = ''; - } else { - stdout += String.fromCharCode(c); - } + opts.stdout(String.fromCharCode(c)); }; - - let stderr = ''; + const stderrFunc = (c) => { - if (c == 10) { - opts.stdout(stdout); - stderr = ''; - } else { - stderr += String.fromCharCode(c); - } + opts.stderr(String.fromCharCode(c)); }; const comp = (n) => { diff --git a/web/src/lib/wlua.js b/web/src/lib/wlua.js index 95db0380..7ea3b2a4 100644 --- a/web/src/lib/wlua.js +++ b/web/src/lib/wlua.js @@ -1,6 +1,16 @@ import {run} from './lua.js'; +let inbuf; +const stdin = () => { + const i32 = new Int32Array(inbuf); + i32[0] = 0; + Atomics.wait(i32, 0, 0); + console.log(i32[0]); + Atomics.notify(i32, 0, 1); + return i32[0]; +}; + const stdout = (msg) => { self.postMessage({ type: 'stdout', @@ -34,7 +44,7 @@ const comp = (input) => { }; const onArgs = (args) => { - run(args, {stdout, stderr, comp}); + run(args, {stdin, stdout, stderr, comp}); self.postMessage({ type: 'exit-ok', }); @@ -46,6 +56,11 @@ self.onmessage = ({data}) => { self.postMessage({type: 'get-args'}); wait = data.wait; ret = data.ret; + inbuf = data.inbuf; + break; + } + case 'stdin': { + break; } case 'args': {