# UCE real generated unit -> WASM PIC side module report Remote host: `k-uce` Working directory/artifacts left in place: `/tmp/uce/wasm-phase0/realunit/` Repository `/Code/uce.openfu.com/uce` was treated read-only; patched copies/shims only under `/tmp/uce/wasm-phase0/realunit/`. ## Result Both real generated units compiled and linked as WASM PIC side modules with `dylink.0`: - `collections.uce.cpp` -> `/tmp/uce/wasm-phase0/realunit/collections.wasm` - `dylink.0`: `memsize=1208 memalign=2^2 tablesize=3 tablealign=2^0` - imports: 52 - exports: 23 - allocator status: no exported/defined `malloc`, `free`, or `operator new`; `operator new`/sized delete are imports (`env._Znwm`, `env._ZdlPvm`). - `hello.uce.cpp` -> `/tmp/uce/wasm-phase0/realunit/hello.wasm` - `dylink.0`: `memsize=5544 memalign=2^2 tablesize=0 tablealign=2^0` - imports: 38 - exports: 24 - allocator status: no exported/defined `malloc`, `free`, or `operator new`; `operator new`/sized delete are imports (`env._Znwm`, `env._ZdlPvm`). Inspector outputs are saved remotely as: - `/tmp/uce/wasm-phase0/realunit/collections.inspect.txt` - `/tmp/uce/wasm-phase0/realunit/hello.inspect.txt` ## Final command lines Run on `k-uce` from `/tmp/uce/wasm-phase0/realunit`. `collections`: ```sh /opt/wasi-sdk/bin/clang++ --target=wasm32-wasip1 -fPIC -fvisibility=default -O1 -fno-exceptions \ -I/tmp/uce/wasm-phase0/realunit/shim -I/Code/uce.openfu.com/uce/src/lib \ -c collections.uce.cpp -o collections.o /opt/wasi-sdk/bin/wasm-ld -shared --experimental-pic --unresolved-symbols=import-dynamic \ collections.o -o collections.wasm --export=__uce_render python3 /Code/uce.openfu.com/uce/spikes/wasm-phase0/wasm_inspect.py collections.wasm ``` `hello`: ```sh /opt/wasi-sdk/bin/clang++ --target=wasm32-wasip1 -fPIC -fvisibility=default -O1 -fno-exceptions \ -I/tmp/uce/wasm-phase0/realunit/shim -I/Code/uce.openfu.com/uce/src/lib \ -c hello.uce.cpp -o hello.o /opt/wasi-sdk/bin/wasm-ld -shared --experimental-pic --unresolved-symbols=import-dynamic \ hello.o -o hello.wasm --export=__uce_render ``` Note: the stub-spike command exported `uce_unit_render`, but these generated units define/export `__uce_render` from the repo `RENDER` macro, so the real-unit link exports `__uce_render`. ## Ordered friction points and fixes 1. **WASI sysroot rejects `` by default.** First compile failed via `/Code/uce.openfu.com/uce/src/lib/sys.h`: ```txt /share/wasi-sysroot/include/wasm32-wasip1/signal.h:2:2: error: "wasm lacks signal support; to enable minimal signal emulation, compile with -D_WASI_EMULATED_SIGNAL ..." ``` Fix: added `/tmp/uce/wasm-phase0/realunit/shim/signal.h` before repo/system includes. Key lines: ```c typedef int sig_atomic_t; typedef void (*sighandler_t)(int); #define SIGTERM 15 int raise(int); sighandler_t signal(int, sighandler_t); ``` This is only enough for declarations in `sys.h`; real signal behavior has no WASI equivalent. 2. **Generated `collections.uce.cpp` includes missing local `demo_guard.h`.** First compile also failed: ```txt fatal error: 'demo_guard.h' file not found ``` Fix: added empty include guard shim `/tmp/uce/wasm-phase0/realunit/shim/demo_guard.h`: ```c #ifndef UCE_WASM_SHIM_DEMO_GUARD_H #define UCE_WASM_SHIM_DEMO_GUARD_H #endif ``` 3. **Generated source uses an absolute repo include, preventing header interposition.** Original generated line: ```c++ #include "/Code/uce.openfu.com/uce/src/lib/uce_lib.h" ``` To use patched shim headers without touching `/Code`, copied the generated units into the workdir and changed only that line to: ```c++ #include "uce_lib.h" ``` Copies are `/tmp/uce/wasm-phase0/realunit/collections.uce.cpp` and `hello.uce.cpp`. 4. **`types.h` defines global `operator new/delete` in every unit.** A straight build linked, but exported allocator definitions (`_Znwm`, `_ZdlPv`), violating the side-module allocator rule. The repo code in `types.h` contains: ```c++ void * operator new(decltype(sizeof(0)) n) noexcept(false) { ... malloc(n) ... } void operator delete(void * p) throw() { free(p); } ``` Fix: copied `uce_lib.h` and `types.h` to the shim tree, then patched only the copied `shim/types.h` allocator block to declarations: ```c++ // WASM side-module shim: allocator must be provided by the host/core module, // not defined in each generated unit. Keep declarations only. void * operator new(decltype(sizeof(0)) n) noexcept(false); void operator delete(void * p) throw(); ``` Verification from `llvm-nm -C collections.o`: ```txt U operator delete(void*, unsigned long) U operator new(unsigned long) ``` ## Notable imports / GOT entries `collections.wasm` notable imports: - allocator/runtime: `env._Znwm`, `env._ZdlPvm`, libc++ string/iostream helpers, `env.__stack_pointer`, `env.memory`, `env.__indirect_function_table` - UCE/runtime functions: `DValue::set`, `DValue::operator[]`, `DValue::push`, `dv_filter`, `dv_map`, `dv_group_by`, `list_unique`, `list_sort`, `replace`, `to_upper`, `html_escape`, `json_encode`, `var_dump`, `time` - MySQL wrappers are imported even for this unit because included header inline functions reference `MySQL` methods. - GOT.mem globals: - `GOT.mem.context` - `GOT.mem._ZNSt3__25ctypeIcE2idE` - `GOT.mem._ZTVN10__cxxabiv117__class_type_infoE` `hello.wasm` notable imports: - allocator/runtime: `env._Znwm`, `env._ZdlPvm`, libc++ string/iostream helpers, `env.memcmp` - UCE/runtime functions: `time`, `html_escape`, `html_escapey`, `var_dump` - GOT.mem globals: - `GOT.mem.context` - `GOT.mem._ZNSt3__219piecewise_constructE` - `GOT.mem._ZNSt3__25ctypeIcE2idE` ## Phase 2 land mines - `src/lib/sys.h` includes `` and declares signals/tasks/socket/process/file-lock APIs. WASI has no normal POSIX signals, fork/exec, traditional sockets, or process model. These need real repo-level `#ifdef __wasm__` / runtime boundary design, not local shims. - `types.h` defines global allocator operators in a header. For side modules this must move to the core/runtime or be gated out under WASM side-module builds; otherwise each unit defines its own allocator entry points. - Generated units include `/Code/.../uce_lib.h` by absolute path. That makes cross-target header selection brittle. The generator should emit a logical include (`"uce_lib.h"`) and the build should supply target-specific include order. - Header-defined helper functions cause many exports from each unit (`to_string`, MySQL wrapper functions, vector slow-path/lambda helpers, globals `parent_pid`, `my_pid`, `context`). For a clean side-module ABI, these should probably be hidden, moved out of headers, marked inline/static where appropriate, or provided by the core module. - MySQL inline wrappers are pulled into every unit by `uce_lib.h` even when the unit does not use MySQL directly. This is why `MySQL::connect/disconnect/query/error` imports appear in both outputs. - Kept `-fno-exceptions`; no try/catch blocker was hit for these two generated units.