|
|
|
@@ -14,7 +14,7 @@ unit_call
|
|
|
|
|
:content
|
|
|
|
|
UCE runs a small custom source-to-source preprocessor before Clang sees a `.uce` or `.ws.uce` file.
|
|
|
|
|
|
|
|
|
|
The template rewriting implementation lives in `src/lib/compiler-parser.cpp`, with orchestration in `src/lib/compiler.cpp`. It does not try to parse all of C++. Instead, it performs a narrow character-wise rewrite that understands literal output, inline code islands, `#load`, and `EXPORT` harvesting, then writes a generated `.cpp` file and compiles that file into a shared object.
|
|
|
|
|
The template rewriting implementation lives in `src/lib/compiler-parser.cpp`, with orchestration in `src/lib/compiler.cpp`. It does not try to parse all of C++. Instead, it performs a narrow character-wise rewrite that understands literal output, inline code islands, `#load`, and `EXPORT` harvesting, then writes a generated `.cpp` file and compiles that file into a WebAssembly side module.
|
|
|
|
|
|
|
|
|
|
## Syntax
|
|
|
|
|
|
|
|
|
@@ -32,7 +32,7 @@ The template rewriting implementation lives in `src/lib/compiler-parser.cpp`, wi
|
|
|
|
|
|
|
|
|
|
## Pipeline
|
|
|
|
|
|
|
|
|
|
- The generated file starts by including the logical runtime header `uce_lib.h`; native and WASM compile scripts provide the include path.
|
|
|
|
|
- The generated file starts by including the logical runtime header `uce_lib.h`; the wasm unit compile script provides the include path.
|
|
|
|
|
- It then inlines the configured setup template from `SETUP_TEMPLATE` (by default `scripts/setup.h.template`), which defines the internal hook `__uce_set_current_request(Request*)`.
|
|
|
|
|
- It inserts `#line 1` before page code so compiler diagnostics point back to the original `.uce` file.
|
|
|
|
|
- Each literal region is rewritten into one or more `print(R"...( ... )...");` calls using a safe raw-string delimiter selected for that literal content.
|
|
|
|
@@ -47,8 +47,8 @@ The template rewriting implementation lives in `src/lib/compiler-parser.cpp`, wi
|
|
|
|
|
- Lines beginning with `RENDER:NAME(...)` are rewritten into exported `__uce_render_NAME(...)` functions.
|
|
|
|
|
- Lines beginning with `COMPONENT:NAME(...)` are rewritten into exported `__uce_component_NAME(...)` functions for the component helpers.
|
|
|
|
|
- The final generated source is written to `BIN_DIRECTORY + src_path + "/" + source_file + ".cpp"`.
|
|
|
|
|
- `scripts/compile` then compiles that generated `.cpp` into `source_file + ".so"` with `clang++ -shared -std=c++20 ...`.
|
|
|
|
|
- When a worker loads the compiled unit into memory, the runtime checks for `INIT(Request& context)` and calls it once for that worker-side load.
|
|
|
|
|
- `scripts/compile_wasm_unit` then compiles that generated `.cpp` into `source_file + ".wasm"` as a PIC WebAssembly side module.
|
|
|
|
|
- When a worker instantiates the compiled unit, the runtime checks for `INIT(Request& context)` and calls it once for that worker-side instance.
|
|
|
|
|
- On each request, the first time a given unit is entered through `RENDER()`, `CLI()`, or any `COMPONENT...` handler, the runtime checks for `ONCE(Request& context)` and calls it before the selected handler.
|
|
|
|
|
|
|
|
|
|
## Generated Files
|
|
|
|
@@ -56,7 +56,7 @@ The template rewriting implementation lives in `src/lib/compiler-parser.cpp`, wi
|
|
|
|
|
For a source file like `/some/path/page.uce`, the preprocessor produces:
|
|
|
|
|
|
|
|
|
|
- generated C++: `BIN_DIRECTORY/some/path/page.uce.cpp`
|
|
|
|
|
- shared object: `BIN_DIRECTORY/some/path/page.uce.so`
|
|
|
|
|
- wasm side module: `BIN_DIRECTORY/some/path/page.uce.wasm`
|
|
|
|
|
- export list: `BIN_DIRECTORY/some/path/page.uce.exports.txt`
|
|
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
@@ -153,7 +153,7 @@ The page template can then render `context.call["fragments"]["head"]` inside `<h
|
|
|
|
|
- `EXPORT` harvesting only triggers when the current line starts with `EXPORT` at column 1 and is followed by whitespace.
|
|
|
|
|
- Relative `#load` paths are expanded against the including unit's source directory.
|
|
|
|
|
- `unit_render()` and `unit_call()` are runtime APIs. `#load` is a compile-time composition feature.
|
|
|
|
|
- `INIT()` runs when the shared object is loaded into a worker during a request-triggered load, so it still receives a valid `Request& context`.
|
|
|
|
|
- `INIT()` runs when the wasm unit is instantiated by a worker during a request-triggered load, so it still receives a valid `Request& context`.
|
|
|
|
|
- `ONCE()` is tracked per request and per resolved unit file. A file entered multiple times in one request only runs `ONCE()` once.
|
|
|
|
|
|
|
|
|
|
## Limitations
|
|
|
|
|