diff --git a/vm/backend/exec.c b/vm/backend/exec.c index 4088109e..f78bff0f 100644 --- a/vm/backend/exec.c +++ b/vm/backend/exec.c @@ -92,7 +92,7 @@ void *vm_cache_comp(const char *comp, const char **srcs, const char *entry) { remove(c_file); remove(so_file); // dlclose(handle); - // printf("%p\n", sym); + // printf("\n", sym); return sym; } #endif diff --git a/vm/backend/tb.c b/vm/backend/tb.c index 47edc59c..36603033 100644 --- a/vm/backend/tb.c +++ b/vm/backend/tb.c @@ -588,7 +588,7 @@ void vm_tb_func_body_once_as(vm_tb_state_t *state, TB_Node **regs, vm_block_t *b vm_tb_inst_call( state, proto, - tb_inst_get_symbol_address(state->fun, state->vm_table_set), + tb_inst_get_symbol_address(state->fun, state->vm_table_iset), 5, args ); @@ -1432,12 +1432,12 @@ void vm_tb_new_module(vm_tb_state_t *state) { state->vm_tb_rfunc_comp = tb_extern_create(mod, -1, "vm_tb_rfunc_comp", TB_EXTERNAL_SO_LOCAL); state->vm_table_new = tb_extern_create(mod, -1, "vm_table_new", TB_EXTERNAL_SO_LOCAL); - state->vm_table_set = tb_extern_create(mod, -1, "vm_table_set", TB_EXTERNAL_SO_LOCAL); + state->vm_table_iset = tb_extern_create(mod, -1, "vm_table_iset", TB_EXTERNAL_SO_LOCAL); state->vm_table_get_pair = tb_extern_create(mod, -1, "vm_table_get_pair", TB_EXTERNAL_SO_LOCAL); state->vm_tb_print = tb_extern_create(mod, -1, "vm_tb_print", TB_EXTERNAL_SO_LOCAL); tb_symbol_bind_ptr(state->vm_tb_rfunc_comp, (void *)&vm_tb_rfunc_comp); tb_symbol_bind_ptr(state->vm_table_new, (void *)&vm_table_new); - tb_symbol_bind_ptr(state->vm_table_set, (void *)&vm_table_set); + tb_symbol_bind_ptr(state->vm_table_iset, (void *)&vm_table_iset); tb_symbol_bind_ptr(state->vm_table_get_pair, (void *)&vm_table_get_pair); tb_symbol_bind_ptr(state->vm_tb_print, (void *)&vm_tb_print); diff --git a/vm/backend/tb.h b/vm/backend/tb.h index b87c0265..599117a9 100644 --- a/vm/backend/tb.h +++ b/vm/backend/tb.h @@ -43,7 +43,7 @@ struct vm_tb_state_t { // externals void *vm_tb_rfunc_comp; void *vm_table_new; - void *vm_table_set; + void *vm_table_iset; void *vm_table_get_pair; void *vm_tb_print; void *std; diff --git a/vm/lua/repl.c b/vm/lua/repl.c index bc419214..75080371 100644 --- a/vm/lua/repl.c +++ b/vm/lua/repl.c @@ -239,6 +239,12 @@ void vm_lang_lua_repl(vm_config_t *config, vm_table_t *std, vm_blocks_t *blocks) .std = std, }; + #if defined(EMSCRIPTEN) + setvbuf(stdin, NULL, _IONBF, 0); + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + #endif + while (true) { #if !defined(EMSCRIPTEN) char *input = ic_readline_ex( @@ -252,9 +258,6 @@ void vm_lang_lua_repl(vm_config_t *config, vm_table_t *std, vm_blocks_t *blocks) 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; diff --git a/vm/obj.c b/vm/obj.c index fdc94ade..8d83f255 100644 --- a/vm/obj.c +++ b/vm/obj.c @@ -343,6 +343,10 @@ vm_pair_t *vm_table_lookup(vm_table_t *table, vm_value_t key_val, uint32_t key_t return NULL; } +void vm_table_iset(vm_table_t *restrict table, uint64_t key_ival, uint64_t val_ival, uint32_t key_tag, uint32_t val_tag) { + vm_table_set(table, *(vm_value_t *)&key_ival, *(vm_value_t *)&val_ival, key_tag, val_tag); +} + void vm_table_set(vm_table_t *restrict table, vm_value_t key_val, vm_value_t val_val, uint32_t key_tag, uint32_t val_tag) { if (table->alloc == 0) { return; diff --git a/vm/obj.h b/vm/obj.h index 96c9408b..e461ee38 100644 --- a/vm/obj.h +++ b/vm/obj.h @@ -67,6 +67,7 @@ int64_t vm_value_to_i64(vm_std_value_t arg); void vm_free_table(vm_table_t *table); vm_table_t *vm_table_new(void); vm_pair_t *vm_table_lookup(vm_table_t *table, vm_value_t key_val, uint32_t key_tag); +void vm_table_iset(vm_table_t *table, uint64_t key_ival, uint64_t val_ival, uint32_t key_tag, uint32_t val_tag); void vm_table_set(vm_table_t *table, vm_value_t key_val, vm_value_t val_val, uint32_t key_tag, uint32_t val_tag); void vm_table_set_pair(vm_table_t *table, vm_pair_t *pair); void vm_table_get_pair(vm_table_t *table, vm_pair_t *pair); diff --git a/vm/std/io.c b/vm/std/io.c index 31411eb6..b4d232aa 100644 --- a/vm/std/io.c +++ b/vm/std/io.c @@ -201,7 +201,7 @@ void vm_io_debug(vm_io_buffer_t *out, size_t indent, const char *prefix, vm_std_ } case VM_TAG_CLOSURE: { vm_indent(out, indent, prefix); - vm_io_buffer_format(out, "\n", value.value.all); + vm_io_buffer_format(out, "\n", value.value.all); break; } case VM_TAG_FUN: { diff --git a/web.mak b/web.mak index 52c39f5e..025f1569 100644 --- a/web.mak +++ b/web.mak @@ -3,9 +3,8 @@ EXE ?= .js CC = emcc TCC_SRCS = -GLOBAL := -s EXPORT_ALL=1 -CFLAGS := -fPIC -DNDEBUG $(GLOBLAL) $(CFLAGS) -LDFLAGS := -s BINARYEN_ASYNC_COMPILATION=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s ALLOW_MEMORY_GROWTH=1 -s EXPORT_ES6=1 -s ENVIRONMENT=web -s MAIN_MODULE=2 -s EXPORTED_RUNTIME_METHODS="['FS','callMain']" $(GLOBLAL) $(LDFLAGS) +CFLAGS := -fPIC -DNDEBUG $(CFLAGS) +LDFLAGS := -s BINARYEN_ASYNC_COMPILATION=0 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s ALLOW_MEMORY_GROWTH=1 -s EXPORT_ES6=1 -s ENVIRONMENT=web -s MAIN_MODULE=2 -s EXPORTED_RUNTIME_METHODS="['FS','callMain']" $(LDFLAGS) include makefile diff --git a/web/package.json b/web/package.json index a57e366a..ac86af09 100644 --- a/web/package.json +++ b/web/package.json @@ -1,11 +1,7 @@ { "dependencies": { - "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.20.7", - "@babel/plugin-proposal-private-methods": "^7.18.6", "@babel/preset-env": "^7.23.9", "babel-loader": "^9.1.3", - "bash-parser": "^0.5.0", "compression-webpack-plugin": "^11.0.0", "copy-webpack-plugin": "^12.0.2", "css-loader": "^6.10.0", @@ -20,8 +16,7 @@ "webpack-node": "^0.0.0", "worker-loader": "^3.0.8", "xterm": "^5.3.0", - "xterm-addon-fit": "^0.8.0", - "xterm-readline": "^1.1.1" + "xterm-addon-fit": "^0.8.0" }, "type": "module" } diff --git a/web/server.py b/web/server.py index a9048262..1cf5dc8d 100644 --- a/web/server.py +++ b/web/server.py @@ -13,4 +13,4 @@ def end_headers(self): if __name__ == "__main__": - test(CORSRequestHandler, HTTPServer, port=8000) + test(CORSRequestHandler, HTTPServer, port=8080) diff --git a/web/src/app/App.svelte b/web/src/app/App.svelte index 84f09367..039d9e52 100644 --- a/web/src/app/App.svelte +++ b/web/src/app/App.svelte @@ -1,178 +1,7 @@ - - - -
- + + \ No newline at end of file diff --git a/web/src/app/New.svelte b/web/src/app/New.svelte new file mode 100644 index 00000000..a0e0ddb6 --- /dev/null +++ b/web/src/app/New.svelte @@ -0,0 +1,67 @@ + + + + +
+ + +
\ No newline at end of file diff --git a/web/src/app/Term.svelte b/web/src/app/Term.svelte new file mode 100644 index 00000000..bbd4bae7 --- /dev/null +++ b/web/src/app/Term.svelte @@ -0,0 +1,48 @@ + + + + +
+ diff --git a/web/src/index.js b/web/src/index.js index c7120ade..4a0768b5 100644 --- a/web/src/index.js +++ b/web/src/index.js @@ -1,18 +1,7 @@ -// import {run} from './lib/spawn.js'; - -// window.lua = async (src) => { -// const {stdout, stderr} = await run(src); -// stdout; -// }; - +import './app/global.css'; import {lua} from './lib/spawn.js'; - - import {load} from 'fengari-web'; - - -import './app/global.css'; import App from './app/App.svelte'; new App({ @@ -35,6 +24,4 @@ window.bench = (func, ...args) => { console.timeEnd(func.name); return ret; }; -console.log('window.{minvim, fengari, time} available'); - -minivm('return print'); +// console.log('window.{minvim, fengari, time} available'); diff --git a/web/src/lib/comp.js b/web/src/lib/comp.js index 291f1b19..083b5957 100644 --- a/web/src/lib/comp.js +++ b/web/src/lib/comp.js @@ -10,7 +10,7 @@ emception.onstderr = (s) => console.error(s); // emception.run('emcc --check -Wno-version-check'); let flags1 = '-target wasm32-unknown-emscripten -fignore-exceptions -fPIC -fvisibility=default -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr -DEMSCRIPTEN -Wno-incompatible-library-redeclaration -Wno-parentheses-equality' -let flags2 = '-L/lazy/emscripten/cache/sysroot/lib/wasm32-emscripten/pic --no-whole-archive -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --import-undefined --import-memory --strip-debug --export-dynamic --export-if-defined=main --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=__main_argc_argv --export-if-defined=__wasm_apply_data_relocs --export=__wasm_call_ctors --experimental-pic -shared' +let flags2 = '-L/lazy/emscripten/cache/sysroot/lib/wasm32-emscripten/pic --no-whole-archive -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --import-undefined --import-memory --strip-debug --export-dynamic --export=__wasm_call_ctors --experimental-pic -shared' let comps = 0; export const comp = (cBuf) => { diff --git a/web/src/lib/lua.js b/web/src/lib/lua.js index ce5f07ea..f3236e6d 100644 --- a/web/src/lib/lua.js +++ b/web/src/lib/lua.js @@ -9,26 +9,6 @@ export const run = (args, opts) => { return opts.stdin(); }; - // 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) => { opts.stdout(String.fromCharCode(c)); }; diff --git a/web/src/lib/repl.js b/web/src/lib/repl.js new file mode 100644 index 00000000..e6bbfcf6 --- /dev/null +++ b/web/src/lib/repl.js @@ -0,0 +1,106 @@ + +const comp = new Worker(new URL('../lib/wcomp.js', import.meta.url)); + +const thens = []; + +const waitForComp = await new Promise((ok, err) => { + comp.onmessage = ({data}) => { + switch (data.type) { + case 'result': { + if (data.number != null) { + thens[data.number](data.output); + } + break; + } + case 'ready': { + ok(); + break; + } + } + }; +}); + +const unmap = (c) => { + if (c === '\n') { + return '\r\n'; + } else { + return c; + } +}; + +export const repl = ({putchar}) => { + const obj = {}; + obj.putchar = putchar; + const want = new SharedArrayBuffer(4); + const inbuf = new SharedArrayBuffer(4); + obj.input = async (str) => { + const i32buf = new Int32Array(inbuf); + const i32want = new Int32Array(want); + for (const c of str) { + await Atomics.waitAsync(i32want, 0, 0).value; + i32want[0] = 0; + i32buf[0] = c.charCodeAt(0); + Atomics.notify(i32buf, 0, 1); + } + }; + obj.start = async() => { + const wait = new SharedArrayBuffer(4); + const ret = new SharedArrayBuffer(65536); + const worker = new Worker(new URL('../lib/wlua.js', import.meta.url)); + const number = thens.length; + thens.push((buf) => { + const len = buf.byteLength; + new Uint8Array(ret).set(new Uint8Array(buf)); + const w32 = new Int32Array(wait); + w32[0] = len + Atomics.notify(w32, 0, 1); + }); + worker.onmessage = async ({data}) => { + switch (data.type) { + case 'stdout': { + obj.putchar(unmap(data.stdout)); + break; + } + case 'stderr': { + obj.putchar(unmap(data.stdout)); + break; + } + case 'exit-err': { + err(); + break; + } + case 'exit-ok': { + ok(); + break; + } + case 'comp': { + await waitForComp; + comp.postMessage({ + type: 'comp', + number: number, + input: data.input, + }); + break; + } + case 'get-buffer': { + worker.postMessage({ + type: 'buffer', + ret: ret, + wait: wait, + inbuf: inbuf, + want: want, + }); + break; + } + case 'get-args': { + worker.postMessage({ + type: 'args', + args: ['--repl'], + }); + break; + } + } + }; + }; + return obj; +}; \ No newline at end of file diff --git a/web/src/lib/spawn.js b/web/src/lib/spawn.js index dde64b21..28e2800b 100644 --- a/web/src/lib/spawn.js +++ b/web/src/lib/spawn.js @@ -6,12 +6,23 @@ const stdin = () => { return null; }; +let buf = ''; const stdout = (str) => { - console.log(str); + if (str == '\n') { + console.log(buf); + buf = ''; + } else { + buf += str; + } }; const stderr = (str) => { - console.error();(str); + if (str == '\n') { + console.log(buf); + buf = ''; + } else { + buf += str; + } }; export const lua = (lua) => { diff --git a/web/src/lib/wlua.js b/web/src/lib/wlua.js index 7ea3b2a4..69a97601 100644 --- a/web/src/lib/wlua.js +++ b/web/src/lib/wlua.js @@ -1,14 +1,15 @@ import {run} from './lua.js'; +let want; 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 i32buf = new Int32Array(inbuf); + const i32want = new Int32Array(want); + i32want[0] = 1; + Atomics.notify(i32want, 0, 1); + Atomics.wait(i32buf, 0, i32buf[0]); + return i32buf[0]; }; const stdout = (msg) => { @@ -57,6 +58,7 @@ self.onmessage = ({data}) => { wait = data.wait; ret = data.ret; inbuf = data.inbuf; + want = data.want; break; } case 'stdin': { diff --git a/web/webpack.config.js b/web/webpack.config.js index e98928bc..21fc618b 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -3,8 +3,10 @@ import CopyPlugin from 'copy-webpack-plugin'; import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import path from 'path'; +const dev = true; + export default { - mode: 'development', + mode: dev ? 'development' : 'production', entry: { 'minivm': './src/index.js', }, @@ -33,6 +35,12 @@ export default { test: /\.svelte$/, use: { loader: 'svelte-loader', + options: { + compilerOptions: { + dev: dev, + }, + hotReload: dev, + }, }, }, { @@ -63,11 +71,6 @@ export default { '@babel/preset-env', ], ], - // plugins: [ - // "@babel/plugin-proposal-private-methods", - // "@babel/plugin-proposal-class-properties", - // "@babel/plugin-proposal-object-rest-spread", - // ], }, }, },