diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml index 3fd5b3f..bd4ab07 100644 --- a/.github/workflows/verify.yaml +++ b/.github/workflows/verify.yaml @@ -38,8 +38,10 @@ jobs: with: name: clayterm-wasm path: | - clayterm.wasm - wasm.ts + layout.wasm + input.wasm + layout.wasm.ts + input.wasm.ts test-alt-os: needs: test diff --git a/.gitignore b/.gitignore index 99b6cdf..efab0a5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ /.agent-shell/ -/clayterm.wasm -/wasm.ts +/layout.wasm +/input.wasm +/layout.wasm.ts +/input.wasm.ts /build/ /node_modules/ diff --git a/BUILD.md b/BUILD.md index f7c4782..f31e488 100644 --- a/BUILD.md +++ b/BUILD.md @@ -18,10 +18,12 @@ The local source build is driven by `make`. It generates: -- `clayterm.wasm` — the compiled WebAssembly module built from the C sources -- `wasm.ts` — a generated TypeScript file derived from `clayterm.wasm` +- `layout.wasm` — the layout WebAssembly module built from the C sources +- `input.wasm` — the input WebAssembly module built from the C sources +- `layout.wasm.ts` — generated TypeScript derived from `layout.wasm` +- `input.wasm.ts` — generated TypeScript derived from `input.wasm` -`wasm.ts` is generated output, not hand-maintained source. +These `.ts` files are generated output, not hand-maintained source. ## Clone the repo with submodules @@ -182,8 +184,10 @@ make This should produce: -- `clayterm.wasm` -- `wasm.ts` +- `layout.wasm` +- `input.wasm` +- `layout.wasm.ts` +- `input.wasm.ts` For a clean rebuild: @@ -197,7 +201,7 @@ Re-run `make` when: - you change files under `src/` - you update the `clay` submodule -- `clayterm.wasm` or `wasm.ts` is missing +- `layout.wasm`, `input.wasm`, `layout.wasm.ts`, or `input.wasm.ts` is missing - generated outputs look stale after switching branches or pulling changes When in doubt, use a clean rebuild: @@ -247,7 +251,7 @@ make clean && make Symptoms may include: - target-related `clang` errors mentioning `wasm32` -- linker failures while producing `clayterm.wasm` +- linker failures while producing the `.wasm` outputs Recovery: @@ -267,8 +271,8 @@ If the smoke test fails, fix the toolchain first and only then rerun `make`. Symptoms may include: -- `clayterm.wasm` is missing -- `wasm.ts` is missing +- `layout.wasm` or `input.wasm` is missing +- `layout.wasm.ts` or `input.wasm.ts` is missing - you changed `src/` or updated `clay/`, but the generated outputs do not match Recovery: diff --git a/Makefile b/Makefile index 1103b8e..9feb82b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,4 @@ CC = clang -TARGET = clayterm.wasm -SRC = src/module.c CFLAGS = --target=wasm32 -nostdlib -O2 \ -ffunction-sections -fdata-sections \ @@ -8,7 +6,13 @@ CFLAGS = --target=wasm32 -nostdlib -O2 \ -DCLAY_IMPLEMENTATION -DCLAY_WASM \ -Isrc -I. -EXPORTS = \ +LDFLAGS_COMMON = -Wl,--no-entry \ + -Wl,--import-memory \ + -Wl,--stack-first \ + -Wl,--strip-all \ + -Wl,--gc-sections + +LAYOUT_EXPORTS = \ -Wl,--export=__heap_base \ -Wl,--export=clayterm_size \ -Wl,--export=init \ @@ -24,7 +28,10 @@ EXPORTS = \ -Wl,--export=error_count \ -Wl,--export=error_type \ -Wl,--export=error_message_length \ - -Wl,--export=error_message_ptr \ + -Wl,--export=error_message_ptr + +INPUT_EXPORTS = \ + -Wl,--export=__heap_base \ -Wl,--export=input_size \ -Wl,--export=input_init \ -Wl,--export=input_scan \ @@ -32,27 +39,33 @@ EXPORTS = \ -Wl,--export=input_event \ -Wl,--export=input_delay -LDFLAGS = -Wl,--no-entry \ - -Wl,--import-memory \ - -Wl,--stack-first \ - -Wl,--strip-all \ - -Wl,--gc-sections \ - -Wl,--undefined=Clay__MeasureText \ - -Wl,--undefined=Clay__QueryScrollOffset \ - $(EXPORTS) +LAYOUT_LDFLAGS = $(LDFLAGS_COMMON) \ + -Wl,--undefined=Clay__MeasureText \ + -Wl,--undefined=Clay__QueryScrollOffset \ + $(LAYOUT_EXPORTS) -all: $(TARGET) wasm.ts - @echo "Built $(TARGET) ($$(wc -c < $(TARGET)) bytes raw, $$(gzip -c $(TARGET) | wc -c) bytes gzip)" +INPUT_LDFLAGS = $(LDFLAGS_COMMON) \ + $(INPUT_EXPORTS) DEPS = $(wildcard src/*.c src/*.h) -$(TARGET): $(DEPS) - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(SRC) +all: layout.wasm input.wasm layout.wasm.ts input.wasm.ts + @echo "Built layout.wasm ($$(wc -c < layout.wasm) bytes raw, $$(gzip -c layout.wasm | wc -c) bytes gzip)" + @echo "Built input.wasm ($$(wc -c < input.wasm) bytes raw, $$(gzip -c input.wasm | wc -c) bytes gzip)" + +layout.wasm: $(DEPS) + $(CC) $(CFLAGS) $(LAYOUT_LDFLAGS) -o $@ src/module-layout.c + +input.wasm: $(DEPS) + $(CC) $(filter-out -DCLAY_IMPLEMENTATION -DCLAY_WASM, $(CFLAGS)) $(INPUT_LDFLAGS) -o $@ src/module-input.c + +layout.wasm.ts: layout.wasm + deno run --allow-read --allow-write tasks/bundle-wasm.ts layout.wasm layout.wasm.ts -wasm.ts: $(TARGET) - deno run --allow-read --allow-write tasks/bundle-wasm.ts +input.wasm.ts: input.wasm + deno run --allow-read --allow-write tasks/bundle-wasm.ts input.wasm input.wasm.ts clean: - rm -f $(TARGET) wasm.ts + rm -f layout.wasm input.wasm layout.wasm.ts input.wasm.ts .PHONY: all clean diff --git a/deno.json b/deno.json index fab9ce2..8d4e7d1 100644 --- a/deno.json +++ b/deno.json @@ -19,11 +19,13 @@ }, "exports": { ".": "./mod.ts", + "./layout": "./layout.ts", + "./input": "./input.ts", "./validate": "./validate.ts" }, "publish": { "include": ["*.ts"], - "exclude": ["!wasm.ts"] + "exclude": ["!layout.wasm.ts", "!input.wasm.ts"] }, "fmt": { "exclude": ["clay", "build"] diff --git a/input-native.ts b/input-native.ts index 7ed6d1b..11576c9 100644 --- a/input-native.ts +++ b/input-native.ts @@ -169,7 +169,7 @@ export interface InputNative { delay(st: number): number; } -import { compiled } from "./wasm.ts"; +import { compiled } from "./input.wasm.ts"; export async function createInputNative( escLatency: number, @@ -178,14 +178,6 @@ export async function createInputNative( let instance = await WebAssembly.instantiate(compiled, { env: { memory }, - clay: { - measureTextFunction() {}, - queryScrollOffsetFunction(ret: number) { - let v = new DataView(memory.buffer); - v.setFloat32(ret, 0, true); - v.setFloat32(ret + 4, 0, true); - }, - }, }); let exports = instance.exports as unknown as { diff --git a/layout.ts b/layout.ts new file mode 100644 index 0000000..1fe605e --- /dev/null +++ b/layout.ts @@ -0,0 +1,4 @@ +export * from "./ops.ts"; +export * from "./term.ts"; +export * from "./settings.ts"; +export * from "./termcodes.ts"; diff --git a/src/module-input.c b/src/module-input.c new file mode 100644 index 0000000..550d698 --- /dev/null +++ b/src/module-input.c @@ -0,0 +1,6 @@ +/* module-input.c — input-only compilation unit, no Clay layout engine */ + +#include "mem.c" +#include "utf8.c" +#include "trie.c" +#include "input.c" diff --git a/src/module-layout.c b/src/module-layout.c new file mode 100644 index 0000000..f865f5f --- /dev/null +++ b/src/module-layout.c @@ -0,0 +1,10 @@ +/* module-layout.c — layout-only compilation unit, no input parser */ + +#include "../clay/clay.h" + +#include "mem.c" +#include "buffer.c" +#include "cell.c" +#include "utf8.c" +#include "wcwidth.c" +#include "clayterm.c" diff --git a/tasks/build-npm.ts b/tasks/build-npm.ts index c31f754..ee417b9 100644 --- a/tasks/build-npm.ts +++ b/tasks/build-npm.ts @@ -10,7 +10,12 @@ if (!version) { } await build({ - entryPoints: ["./mod.ts"], + entryPoints: [ + "./mod.ts", + { name: "./layout", path: "./layout.ts" }, + { name: "./input", path: "./input.ts" }, + { name: "./validate", path: "./validate.ts" }, + ], outDir, shims: { deno: false, diff --git a/tasks/bundle-wasm.ts b/tasks/bundle-wasm.ts index b6b033d..e990ba2 100644 --- a/tasks/bundle-wasm.ts +++ b/tasks/bundle-wasm.ts @@ -1,6 +1,12 @@ import { encodeBase64 } from "@std/encoding/base64"; -const wasm = await Deno.readFile("clayterm.wasm"); +const [input, output] = Deno.args; +if (!input || !output) { + console.error("Usage: bundle-wasm.ts "); + Deno.exit(1); +} + +const wasm = await Deno.readFile(input); const base64 = encodeBase64(wasm); const source = `const bin = atob("${base64}"); @@ -9,5 +15,5 @@ for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i); export const compiled = await WebAssembly.compile(bytes); `; -await Deno.writeTextFile("wasm.ts", source); -console.log(`wrote wasm.ts (${wasm.length} bytes encoded)`); +await Deno.writeTextFile(output, source); +console.log(`wrote ${output} (${wasm.length} bytes encoded)`); diff --git a/term-native.ts b/term-native.ts index 40e646d..3ad544b 100644 --- a/term-native.ts +++ b/term-native.ts @@ -31,7 +31,7 @@ export interface Native { errorMessage(ct: number, index: number): string; } -import { compiled } from "./wasm.ts"; +import { compiled } from "./layout.wasm.ts"; export async function createTermNative( w: number,