From e0cae790dcafcde54995d94c2b93fde9275c5221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Mon, 11 Jul 2022 21:02:07 +0200 Subject: [PATCH] Remove waforth2c experiment Will be superseded by `waforthc` in the future. --- src/waforth2c/.gitignore | 4 - src/waforth2c/Makefile | 44 -------- src/waforth2c/README.md | 24 ---- src/waforth2c/main.c | 6 - src/waforth2c/waforth.c | 67 ----------- src/waforth2c/waforth.h | 3 - src/waforth2c/waforth2c.js | 134 ---------------------- src/waforth2c/wasm2c/wasm-rt-impl.c | 122 -------------------- src/waforth2c/wasm2c/wasm-rt-impl.h | 56 ---------- src/waforth2c/wasm2c/wasm-rt.h | 168 ---------------------------- 10 files changed, 628 deletions(-) delete mode 100644 src/waforth2c/.gitignore delete mode 100644 src/waforth2c/Makefile delete mode 100644 src/waforth2c/README.md delete mode 100644 src/waforth2c/main.c delete mode 100644 src/waforth2c/waforth.c delete mode 100644 src/waforth2c/waforth.h delete mode 100755 src/waforth2c/waforth2c.js delete mode 100644 src/waforth2c/wasm2c/wasm-rt-impl.c delete mode 100644 src/waforth2c/wasm2c/wasm-rt-impl.h delete mode 100644 src/waforth2c/wasm2c/wasm-rt.h diff --git a/src/waforth2c/.gitignore b/src/waforth2c/.gitignore deleted file mode 100644 index 32dceeb..0000000 --- a/src/waforth2c/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -waforth.gen -*.o -waforth_core.* -main diff --git a/src/waforth2c/Makefile b/src/waforth2c/Makefile deleted file mode 100644 index 1c7f0ac..0000000 --- a/src/waforth2c/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -CFLAGS= -CPPFLAGS=-Wno-main-return-type -Wno-main -I. -Iwaforth.gen -Iwasm2c -LINKFLAGS=-g - -.DEFAULT_GOAL := all - --include waforth.gen/Makefile.inc - -WAFORTH_MODULE_SOURCES=$(patsubst %.wasm,%.c,$(WAFORTH_MODULES)) -WAFORTH_MODULE_HEADERS=$(patsubst %.wasm,%.h,$(WAFORTH_MODULES)) -WAFORTH_MODULE_OBJECTS=$(patsubst %.wasm,%.o,$(WAFORTH_MODULES)) - -OBJECTS=waforth_core.o main.o waforth.o wasm2c/wasm-rt-impl.o $(WAFORTH_MODULE_OBJECTS) waforth.gen/waforth_modules.o - -.PHONY: all -all: main - -.PHONY: example -example: - ./waforth2c.js ../examples/sieve.f - $(MAKE) - ./main - -main: $(OBJECTS) - $(CC) $(LINKFLAGS) -o $@ $(OBJECTS) - -clean: - -rm -rf $(OBJECTS) waforth_core.c waforth_core.h main $(WAFORTH_MODULE_HEADERS) $(WAFORTH_MODULE_SOURCES) - -waforth.o: waforth.gen/waforth_modules.h - -waforth_core.c: ../../src/waforth.wasm - wasm2c $< -o $@ - -waforth_core.o: waforth_core.c - $(CC) $(CPPFLAGS) $(CFLAGS) -DWASM_RT_MODULE_PREFIX=waforth_core_ -c $< -o $@ - -waforth.gen/waforth_module_%.c waforth.gen/waforth_module_%.h: waforth.gen/waforth_module_%.wasm - wasm2c $< -o $(subst .wasm,.c,$<) - -waforth.gen/waforth_module_%.o: waforth.gen/waforth_module_%.c - $(CC) $(CPPFLAGS) $(CFLAGS) -DWASM_RT_MODULE_PREFIX=$(subst waforth.gen/,,$(subst .o,,$@))_ -c $< -o $@ - -waforth.gen/waforth_modules.h: $(WAFORTH_MODULE_HEADERS) diff --git a/src/waforth2c/README.md b/src/waforth2c/README.md deleted file mode 100644 index bbd4764..0000000 --- a/src/waforth2c/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# WAForth2C: Experiment to use WAForth to convert Forth to C - -Uses WAForth to generate WebAssembly modules, passes them to `wasm2c`, and -compiles and loads everything together into a native binary. - -## Usage - -1. Create a `.f` file with a `main` word defined (e.g. `example/sieve.f`) -2. Compile - - ./waforth2c.js examples/sieve.f - - This will generate `.wasm` files for all the defined words. - -3. Build - - make - - This will generate `.c` files from the `.wasm` files generated in 2., and build - them using the C compiler. - -4. Run - - ./main diff --git a/src/waforth2c/main.c b/src/waforth2c/main.c deleted file mode 100644 index dafc116..0000000 --- a/src/waforth2c/main.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "waforth.h" - -int main(int argc, char** argv) { - waforth_init(); - return 0; -} diff --git a/src/waforth2c/waforth.c b/src/waforth2c/waforth.c deleted file mode 100644 index fed58ac..0000000 --- a/src/waforth2c/waforth.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include - -#define WASM_RT_MODULE_PREFIX waforth_core_ -#include "waforth_core.h" -#undef WASM_RT_MODULE_PREFIX -#include "waforth.gen/waforth_modules.h" - -void (*Z_shellZ_emitZ_vi)(u32); -u32 (*Z_shellZ_getcZ_iv)(void); -void (*Z_shellZ_loadZ_viii)(u32, u32, u32); -void (*Z_shellZ_debugZ_vi)(u32); -wasm_rt_table_t (*Z_envZ_table); -wasm_rt_memory_t (*Z_envZ_memory); - -static void shellEmit(u32 c) { - printf("%c", c); - fflush(stdout); -} - -static int bufferIndex; -char* buffer = "main\n"; - -static u32 shellGetC() { - if (bufferIndex >= strlen(buffer)) { - return -1; - } - return buffer[bufferIndex++]; -} - -static void shellLoad(u32 offset, u32 length, u32 index) { - printf("Loading not supported!\n"); -} - -static void shellDebug(u32 c) { - fprintf(stderr, "%d\n", c); -} - -void wasm_rt_reallocate_table(wasm_rt_table_t* table, uint32_t elements, uint32_t max_elements) { - table->size = elements; - table->max_size = max_elements; - table->data = realloc(table->data, table->size * sizeof(wasm_rt_elem_t)); -} - -void waforth_init() { - waforth_core_init(); - - if (WAFORTH_TABLE_SIZE >= 0) { - wasm_rt_reallocate_table(waforth_core_Z_table, WAFORTH_TABLE_SIZE, waforth_core_Z_table->max_size); - } - - Z_shellZ_emitZ_vi = &shellEmit; - Z_shellZ_getcZ_iv = &shellGetC; - Z_shellZ_loadZ_viii = &shellLoad; - Z_shellZ_debugZ_vi = &shellDebug; - - Z_envZ_table = waforth_core_Z_table; - Z_envZ_memory = waforth_core_Z_memory; - - waforth_core_Z_set_stateZ_vii(WAFORTH_LATEST, WAFORTH_HERE); - - waforth_modules_init(); - - bufferIndex = 0; - waforth_core_Z_interpretZ_iv(); -} diff --git a/src/waforth2c/waforth.h b/src/waforth2c/waforth.h deleted file mode 100644 index 4e7f64b..0000000 --- a/src/waforth2c/waforth.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void waforth_init(); diff --git a/src/waforth2c/waforth2c.js b/src/waforth2c/waforth2c.js deleted file mode 100755 index 083f3cb..0000000 --- a/src/waforth2c/waforth2c.js +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/env node - -/* eslint @typescript-eslint/no-var-requires:0 */ - -const fs = require("fs"); -const process = require("process"); - -if (process.argv.length < 3) { - console.log("Expected input file"); - process.exit(1); -} -const input = fs.readFileSync(process.argv[2]) + ""; - -const coreWasm = fs.readFileSync("../../src/waforth.wasm"); - -let core, table, memory, memory32; -const buffer = []; -const modules = []; -let tableSize = -1; - -function run(s) { - const data = new TextEncoder().encode(s); - for (let i = data.length - 1; i >= 0; --i) { - buffer.push(data[i]); - } - return core.exports.run(); -} - -function latest() { - run("LATEST"); - const result = memory32[core.exports.tos() / 4 - 1]; - run("DROP"); - return result; -} - -function here() { - run("HERE"); - const result = memory32[core.exports.tos() / 4 - 1]; - run("DROP"); - return result; -} - -WebAssembly.instantiate(coreWasm, { - shell: { - emit: (c) => { - process.stdout.write(String.fromCharCode(c)); - }, - - getc: () => { - if (buffer.length === 0) { - return -1; - } - return buffer.pop(); - }, - - debug: (c) => { - process.stderr.write(String.fromCharCode(c)); - }, - - load: (offset, length, index) => { - let data = new Uint8Array(core.exports.memory.buffer, offset, length); - if (index >= table.length) { - table.grow(table.length); - } - tableSize = index + 1; - var module = new WebAssembly.Module(data); - modules.push(new Uint8Array(Array.from(data))); - new WebAssembly.Instance(module, { - env: { table, memory, tos: -1 }, - }); - }, - }, -}).then((instance) => { - core = instance.instance; - table = core.exports.table; - memory = core.exports.memory; - memory32 = new Int32Array(core.exports.memory.buffer, 0, 0x30000); - const memory8 = new Uint8Array(core.exports.memory.buffer, 0, 0x30000); - - const dictionaryStart = latest(); - - // Load code - run(input); - - const savedLatest = latest(); - const savedHere = here(); - - //////////////////////////////////////////////////////////// - // Generate build files - //////////////////////////////////////////////////////////// - - if (!fs.existsSync("waforth.gen")) { - fs.mkdirSync("waforth.gen"); - } - - const make = []; - const include = [ - "#pragma once", - "", - "#define WAFORTH_LATEST " + savedLatest + "\n", - "#define WAFORTH_HERE " + savedHere + "\n", - "#define WAFORTH_TABLE_SIZE " + tableSize + "\n", - "void waforth_modules_init();", - "#undef WASM_RT_MODULE_PREFIX", - ]; - const init = [ - "#include ", - '#include "waforth_modules.h"', - "static const u8 dictionary[] = { " + - Array.from(memory8.slice(dictionaryStart, savedHere)).join(", ") + - " };", - "void waforth_modules_init() {", - "memcpy(&Z_envZ_memory->data[" + - dictionaryStart + - "], dictionary, " + - (savedHere - dictionaryStart) + - ");", - ]; - const moduleFiles = []; - for (let i = 0; i < modules.length; ++i) { - fs.writeFileSync("waforth.gen/waforth_module_" + i + ".wasm", modules[i]); - include.push("#define WASM_RT_MODULE_PREFIX waforth_module_" + i + "_"); - include.push('#include "waforth.gen/waforth_module_' + i + '.h"'); - include.push("#undef WASM_RT_MODULE_PREFIX"); - init.push("waforth_module_" + i + "_init();"); - moduleFiles.push("waforth.gen/waforth_module_" + i + ".wasm"); - } - include.push("#define WASM_RT_MODULE_PREFIX"); - make.push("WAFORTH_MODULES = " + moduleFiles.join(" ") + "\n"); - init.push("}"); - fs.writeFileSync("waforth.gen/Makefile.inc", make.join("\n") + "\n"); - fs.writeFileSync("waforth.gen/waforth_modules.h", include.join("\n") + "\n"); - fs.writeFileSync("waforth.gen/waforth_modules.c", init.join("\n") + "\n"); -}); diff --git a/src/waforth2c/wasm2c/wasm-rt-impl.c b/src/waforth2c/wasm2c/wasm-rt-impl.c deleted file mode 100644 index 0fcbcf9..0000000 --- a/src/waforth2c/wasm2c/wasm-rt-impl.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2018 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "wasm-rt-impl.h" - -#include -#include -#include -#include -#include -#include - -#define PAGE_SIZE 65536 - -typedef struct FuncType { - wasm_rt_type_t* params; - wasm_rt_type_t* results; - uint32_t param_count; - uint32_t result_count; -} FuncType; - -uint32_t wasm_rt_call_stack_depth; -uint32_t g_saved_call_stack_depth; - -jmp_buf g_jmp_buf; -FuncType* g_func_types; -uint32_t g_func_type_count; - -void wasm_rt_trap(wasm_rt_trap_t code) { - assert(code != WASM_RT_TRAP_NONE); - wasm_rt_call_stack_depth = g_saved_call_stack_depth; - longjmp(g_jmp_buf, code); -} - -static bool func_types_are_equal(FuncType* a, FuncType* b) { - if (a->param_count != b->param_count || a->result_count != b->result_count) - return 0; - int i; - for (i = 0; i < a->param_count; ++i) - if (a->params[i] != b->params[i]) - return 0; - for (i = 0; i < a->result_count; ++i) - if (a->results[i] != b->results[i]) - return 0; - return 1; -} - -uint32_t wasm_rt_register_func_type(uint32_t param_count, - uint32_t result_count, - ...) { - FuncType func_type; - func_type.param_count = param_count; - func_type.params = malloc(param_count * sizeof(wasm_rt_type_t)); - func_type.result_count = result_count; - func_type.results = malloc(result_count * sizeof(wasm_rt_type_t)); - - va_list args; - va_start(args, result_count); - - uint32_t i; - for (i = 0; i < param_count; ++i) - func_type.params[i] = va_arg(args, wasm_rt_type_t); - for (i = 0; i < result_count; ++i) - func_type.results[i] = va_arg(args, wasm_rt_type_t); - va_end(args); - - for (i = 0; i < g_func_type_count; ++i) { - if (func_types_are_equal(&g_func_types[i], &func_type)) { - free(func_type.params); - free(func_type.results); - return i + 1; - } - } - - uint32_t idx = g_func_type_count++; - g_func_types = realloc(g_func_types, g_func_type_count * sizeof(FuncType)); - g_func_types[idx] = func_type; - return idx + 1; -} - -void wasm_rt_allocate_memory(wasm_rt_memory_t* memory, - uint32_t initial_pages, - uint32_t max_pages) { - memory->pages = initial_pages; - memory->max_pages = max_pages; - memory->size = initial_pages * PAGE_SIZE; - memory->data = calloc(memory->size, 1); -} - -uint32_t wasm_rt_grow_memory(wasm_rt_memory_t* memory, uint32_t delta) { - uint32_t old_pages = memory->pages; - uint32_t new_pages = memory->pages + delta; - if (new_pages < old_pages || new_pages > memory->max_pages) { - return (uint32_t)-1; - } - memory->pages = new_pages; - memory->size = new_pages * PAGE_SIZE; - memory->data = realloc(memory->data, memory->size); - memset(memory->data + old_pages * PAGE_SIZE, 0, delta * PAGE_SIZE); - return old_pages; -} - -void wasm_rt_allocate_table(wasm_rt_table_t* table, - uint32_t elements, - uint32_t max_elements) { - table->size = elements; - table->max_size = max_elements; - table->data = calloc(table->size, sizeof(wasm_rt_elem_t)); -} diff --git a/src/waforth2c/wasm2c/wasm-rt-impl.h b/src/waforth2c/wasm2c/wasm-rt-impl.h deleted file mode 100644 index bdc4502..0000000 --- a/src/waforth2c/wasm2c/wasm-rt-impl.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2018 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef WASM_RT_IMPL_H_ -#define WASM_RT_IMPL_H_ - -#include - -#include "wasm-rt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** A setjmp buffer used for handling traps. */ -extern jmp_buf g_jmp_buf; - -/** Saved call stack depth that will be restored in case a trap occurs. */ -extern uint32_t g_saved_call_stack_depth; - -/** Convenience macro to use before calling a wasm function. On first execution - * it will return `WASM_RT_TRAP_NONE` (i.e. 0). If the function traps, it will - * jump back and return the trap that occurred. - * - * ``` - * wasm_rt_trap_t code = wasm_rt_impl_try(); - * if (code != 0) { - * printf("A trap occurred with code: %d\n", code); - * ... - * } - * - * // Call the potentially-trapping function. - * my_wasm_func(); - * ``` - */ -#define wasm_rt_impl_try() \ - (g_saved_call_stack_depth = wasm_rt_call_stack_depth, setjmp(g_jmp_buf)) - -#ifdef __cplusplus -} -#endif - -#endif // WASM_RT_IMPL_H_ diff --git a/src/waforth2c/wasm2c/wasm-rt.h b/src/waforth2c/wasm2c/wasm-rt.h deleted file mode 100644 index 494fde1..0000000 --- a/src/waforth2c/wasm2c/wasm-rt.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2018 WebAssembly Community Group participants - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef WASM_RT_H_ -#define WASM_RT_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Maximum stack depth before trapping. This can be configured by defining - * this symbol before including wasm-rt when building the generated c files, - * for example: - * - * ``` - * cc -c -DWASM_RT_MAX_CALL_STACK_DEPTH=100 my_module.c -o my_module.o - * ``` - * */ -#ifndef WASM_RT_MAX_CALL_STACK_DEPTH -#define WASM_RT_MAX_CALL_STACK_DEPTH 500 -#endif - -/** Reason a trap occurred. Provide this to `wasm_rt_trap`. */ -typedef enum { - WASM_RT_TRAP_NONE, /** No error. */ - WASM_RT_TRAP_OOB, /** Out-of-bounds access in linear memory. */ - WASM_RT_TRAP_INT_OVERFLOW, /** Integer overflow on divide or truncation. */ - WASM_RT_TRAP_DIV_BY_ZERO, /** Integer divide by zero. */ - WASM_RT_TRAP_INVALID_CONVERSION, /** Conversion from NaN to integer. */ - WASM_RT_TRAP_UNREACHABLE, /** Unreachable instruction executed. */ - WASM_RT_TRAP_CALL_INDIRECT, /** Invalid call_indirect, for any reason. */ - WASM_RT_TRAP_EXHAUSTION, /** Call stack exhausted. */ -} wasm_rt_trap_t; - -/** Value types. Used to define function signatures. */ -typedef enum { - WASM_RT_I32, - WASM_RT_I64, - WASM_RT_F32, - WASM_RT_F64, -} wasm_rt_type_t; - -/** A function type for all `anyfunc` functions in a Table. All functions are - * stored in this canonical form, but must be cast to their proper signature to - * call. */ -typedef void (*wasm_rt_anyfunc_t)(void); - -/** A single element of a Table. */ -typedef struct { - /** The index as returned from `wasm_rt_register_func_type`. */ - uint32_t func_type; - /** The function. The embedder must know the actual C signature of the - * function and cast to it before calling. */ - wasm_rt_anyfunc_t func; -} wasm_rt_elem_t; - -/** A Memory object. */ -typedef struct { - /** The linear memory data, with a byte length of `size`. */ - uint8_t* data; - /** The current and maximum page count for this Memory object. If there is no - * maximum, `max_pages` is 0xffffffffu (i.e. UINT32_MAX). */ - uint32_t pages, max_pages; - /** The current size of the linear memory, in bytes. */ - uint32_t size; -} wasm_rt_memory_t; - -/** A Table object. */ -typedef struct { - /** The table element data, with an element count of `size`. */ - wasm_rt_elem_t* data; - /** The maximum element count of this Table object. If there is no maximum, - * `max_size` is 0xffffffffu (i.e. UINT32_MAX). */ - uint32_t max_size; - /** The current element count of the table. */ - uint32_t size; -} wasm_rt_table_t; - -/** Stop execution immediately and jump back to the call to `wasm_rt_try`. - * The result of `wasm_rt_try` will be the provided trap reason. - * - * This is typically called by the generated code, and not the embedder. */ -extern void wasm_rt_trap(wasm_rt_trap_t) __attribute__((noreturn)); - -/** Register a function type with the given signature. The returned function - * index is guaranteed to be the same for all calls with the same signature. - * The following varargs must all be of type `wasm_rt_type_t`, first the - * params` and then the `results`. - * - * ``` - * // Register (func (param i32 f32) (result i64)). - * wasm_rt_register_func_type(2, 1, WASM_RT_I32, WASM_RT_F32, WASM_RT_I64); - * => returns 1 - * - * // Register (func (result i64)). - * wasm_rt_register_func_type(0, 1, WASM_RT_I32); - * => returns 2 - * - * // Register (func (param i32 f32) (result i64)) again. - * wasm_rt_register_func_type(2, 1, WASM_RT_I32, WASM_RT_F32, WASM_RT_I64); - * => returns 1 - * ``` */ -extern uint32_t wasm_rt_register_func_type(uint32_t params, - uint32_t results, - ...); - -/** Initialize a Memory object with an initial page size of `initial_pages` and - * a maximum page size of `max_pages`. - * - * ``` - * wasm_rt_memory_t my_memory; - * // 1 initial page (65536 bytes), and a maximum of 2 pages. - * wasm_rt_allocate_memory(&my_memory, 1, 2); - * ``` */ -extern void wasm_rt_allocate_memory(wasm_rt_memory_t*, - uint32_t initial_pages, - uint32_t max_pages); - -/** Grow a Memory object by `pages`, and return the previous page count. If - * this new page count is greater than the maximum page count, the grow fails - * and 0xffffffffu (UINT32_MAX) is returned instead. - * - * ``` - * wasm_rt_memory_t my_memory; - * ... - * // Grow memory by 10 pages. - * uint32_t old_page_size = wasm_rt_grow_memory(&my_memory, 10); - * if (old_page_size == UINT32_MAX) { - * // Failed to grow memory. - * } - * ``` */ -extern uint32_t wasm_rt_grow_memory(wasm_rt_memory_t*, uint32_t pages); - -/** Initialize a Table object with an element count of `elements` and a maximum - * page size of `max_elements`. - * - * ``` - * wasm_rt_table_t my_table; - * // 5 elemnets and a maximum of 10 elements. - * wasm_rt_allocate_table(&my_table, 5, 10); - * ``` */ -extern void wasm_rt_allocate_table(wasm_rt_table_t*, - uint32_t elements, - uint32_t max_elements); - -/** Current call stack depth. */ -extern uint32_t wasm_rt_call_stack_depth; - -#ifdef __cplusplus -} -#endif - -#endif /* WASM_RT_H_ */