74 lines
2.4 KiB
C++
74 lines
2.4 KiB
C++
// WASM-PROPOSAL Phase 0 — unit module stub.
|
|
//
|
|
// Stands in for a generated UCE unit: compiled with -fPIC and linked with
|
|
// wasm-ld -shared into a PIC module carrying a dylink.0 section. Defines no
|
|
// allocator and links no libc — operator new/delete, memcpy, and the core
|
|
// API all arrive as imports resolved by the loader against the core module
|
|
// (§5.4 unit module contract).
|
|
//
|
|
// Exercises, in one render call:
|
|
// - unit-local data segment with relocation (__memory_base placement)
|
|
// - GOT.mem read+write of a core-defined global (core_counter)
|
|
// - C++ containers (std::string/std::map) on the core's heap
|
|
// - heap object created in core, mutated and read from the unit
|
|
// - function pointer from unit through core and back (shared table)
|
|
// - std::function/lambda handed across the module boundary
|
|
|
|
#include <string>
|
|
#include <functional>
|
|
#include <map>
|
|
|
|
extern "C" {
|
|
void uce_print(const char* s, size_t len);
|
|
extern int core_counter;
|
|
std::string* core_make_string(const char* s);
|
|
void core_append_string(std::string* str, const char* s);
|
|
void core_invoke_callback(void (*cb)(int), int arg);
|
|
void core_invoke_function(std::function<int(int)>* f, int arg);
|
|
}
|
|
|
|
static const char* unit_static_message = "unit-data-segment-ok";
|
|
static int unit_state = 41;
|
|
|
|
static void my_callback(int x)
|
|
{
|
|
std::string s = "[cb:" + std::to_string(x + unit_state) + "]";
|
|
uce_print(s.data(), s.size());
|
|
}
|
|
|
|
extern "C" void uce_unit_render()
|
|
{
|
|
std::string out = "hello from unit; ";
|
|
out += unit_static_message;
|
|
out += "; counter=" + std::to_string(core_counter);
|
|
uce_print(out.data(), out.size());
|
|
|
|
std::map<std::string, int> m;
|
|
m["a"] = 1;
|
|
m["b"] = 2;
|
|
int sum = 0;
|
|
for(auto& kv : m)
|
|
sum += kv.second;
|
|
std::string s2 = "; mapsum=" + std::to_string(sum);
|
|
uce_print(s2.data(), s2.size());
|
|
|
|
std::string* cs = core_make_string("; core-string");
|
|
core_append_string(cs, "+unit");
|
|
uce_print(cs->data(), cs->size());
|
|
delete cs;
|
|
|
|
core_invoke_callback(my_callback, 1);
|
|
|
|
// address of a core-defined function taken in the unit → GOT.func import;
|
|
// the loader must ensure the core function has a funcref table entry.
|
|
// volatile so the optimizer cannot fold it back into a direct call.
|
|
void (*volatile print_ptr)(const char*, size_t) = uce_print;
|
|
print_ptr("[got-func-ok]", 13);
|
|
|
|
auto* fn = new std::function<int(int)>([](int v) { return(v * 3); });
|
|
core_invoke_function(fn, 14);
|
|
delete fn;
|
|
|
|
core_counter++;
|
|
}
|