166 lines
7.0 KiB
Markdown
166 lines
7.0 KiB
Markdown
# 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 `<signal.h>` 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 `<signal.h>` 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.
|