75 lines
2.3 KiB
C++
75 lines
2.3 KiB
C++
// WASM-PROPOSAL Phase 0 — core module stub.
|
|
//
|
|
// Stands in for the future "core module" (uce_lib + libc compiled to wasm):
|
|
// owns linear memory, the allocator, and libc/libc++ (statically linked,
|
|
// per the §10 mitigation: avoid shared wasi-libc entirely). Built as a
|
|
// non-PIC wasm32-wasi reactor with everything exported so unit modules can
|
|
// import from it.
|
|
//
|
|
// Deliberately avoids WASI I/O (no printf-to-fd): output accumulates in a
|
|
// buffer the host reads back, so the module can be instantiated through the
|
|
// plain wasm-c-api without a WASI context if need be.
|
|
|
|
#include <string>
|
|
#include <functional>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
|
|
static std::string g_output;
|
|
|
|
extern "C" {
|
|
|
|
// data symbol referenced from the unit module → must arrive there as a
|
|
// GOT.mem import
|
|
int core_counter = 7;
|
|
|
|
void uce_print(const char* s, size_t len)
|
|
{
|
|
g_output.append(s, len);
|
|
}
|
|
|
|
// heap C++ object created in core, handed to the unit by pointer —
|
|
// validates one-heap/one-allocator pointer semantics (§3.4)
|
|
std::string* core_make_string(const char* s)
|
|
{
|
|
return(new std::string(s));
|
|
}
|
|
|
|
void core_append_string(std::string* str, const char* s)
|
|
{
|
|
str->append(s);
|
|
}
|
|
|
|
// plain function pointer crossing: unit passes its own function, core calls
|
|
// it back — validates the shared funcref table
|
|
void core_invoke_callback(void (*cb)(int), int arg)
|
|
{
|
|
cb(arg);
|
|
}
|
|
|
|
// std::function allocated by unit code, executed here — validates fat
|
|
// callable objects (lambdas) across module boundaries
|
|
void core_invoke_function(std::function<int(int)>* f, int arg)
|
|
{
|
|
char buf[64];
|
|
snprintf(buf, sizeof(buf), "[fn:%d]", (*f)(arg));
|
|
g_output.append(buf);
|
|
}
|
|
|
|
// GOT.func resolution helper: taking the address here forces uce_print into
|
|
// core's elem segment at link time, and on wasm a function pointer IS its
|
|
// table index — so the loader can resolve GOT.func.uce_print with a plain
|
|
// call instead of host-side funcref injection (which WAMR does not allow).
|
|
// The production core will generalize this into a name → funcptr registry.
|
|
intptr_t core_table_index_of_uce_print()
|
|
{
|
|
return(reinterpret_cast<intptr_t>(uce_print));
|
|
}
|
|
|
|
// host reads the result out of linear memory via these
|
|
const char* core_output_data() { return(g_output.data()); }
|
|
size_t core_output_size() { return(g_output.size()); }
|
|
void core_output_clear() { g_output.clear(); }
|
|
|
|
}
|