Return component ONCE slots with handler resolution
This commit is contained in:
+38
-32
@@ -2527,8 +2527,11 @@ private:
|
||||
// hostcall body: uce_host_component_resolve(unit, handler, current) → slot.
|
||||
// `handler` names the export ("render", "component:CARD", "cli",
|
||||
// "serve_http:named", "once") or is "exists" (probe only, loads nothing).
|
||||
int32_t component_resolve(const String& target, const String& handler, const String& current_unit, String& resolved_out)
|
||||
int32_t component_resolve(const String& target, const String& handler, const String& current_unit,
|
||||
String& resolved_out, int32_t* once_slot_out = 0)
|
||||
{
|
||||
if(once_slot_out)
|
||||
*once_slot_out = 0;
|
||||
auto probe_start = std::chrono::steady_clock::now();
|
||||
auto record_probe = [&]() {
|
||||
component_resolve_count += 1;
|
||||
@@ -2675,38 +2678,38 @@ private:
|
||||
component_link_total_us += (u64)std::chrono::duration_cast<std::chrono::microseconds>(
|
||||
std::chrono::steady_clock::now() - link_start).count();
|
||||
};
|
||||
String symbol = handler_export_symbol(handler);
|
||||
String slot_key = resolved + ":" + symbol;
|
||||
auto cached = handler_slots.find(slot_key);
|
||||
if(cached != handler_slots.end())
|
||||
{
|
||||
record_link();
|
||||
record_probe();
|
||||
return((int32_t)cached->second);
|
||||
}
|
||||
auto handler_fn = unit_func(unit_index, symbol);
|
||||
if(!handler_fn)
|
||||
{
|
||||
// ONCE is optional per unit; a missing __uce_once is not an error
|
||||
if(handler != "once")
|
||||
fprintf(stderr, "[wasm] %s does not export %s\n", resolved.c_str(), symbol.c_str());
|
||||
record_link();
|
||||
record_probe();
|
||||
return(0);
|
||||
}
|
||||
u32 slot = 0;
|
||||
error = place_funcref(*handler_fn, slot);
|
||||
if(error != "")
|
||||
{
|
||||
fprintf(stderr, "[wasm] %s\n", error.c_str());
|
||||
record_link();
|
||||
record_probe();
|
||||
return(0);
|
||||
}
|
||||
handler_slots[slot_key] = slot;
|
||||
auto link_handler = [&](const String& requested_handler) -> int32_t {
|
||||
String symbol = handler_export_symbol(requested_handler);
|
||||
String slot_key = resolved + ":" + symbol;
|
||||
auto cached = handler_slots.find(slot_key);
|
||||
if(cached != handler_slots.end())
|
||||
return((int32_t)cached->second);
|
||||
auto handler_fn = unit_func(unit_index, symbol);
|
||||
if(!handler_fn)
|
||||
{
|
||||
// ONCE is optional per unit; a missing __uce_once is not an error.
|
||||
if(requested_handler != "once")
|
||||
fprintf(stderr, "[wasm] %s does not export %s\n", resolved.c_str(), symbol.c_str());
|
||||
return(0);
|
||||
}
|
||||
u32 slot = 0;
|
||||
error = place_funcref(*handler_fn, slot);
|
||||
if(error != "")
|
||||
{
|
||||
fprintf(stderr, "[wasm] %s\n", error.c_str());
|
||||
return(0);
|
||||
}
|
||||
handler_slots[slot_key] = slot;
|
||||
return((int32_t)slot);
|
||||
};
|
||||
int32_t slot = link_handler(handler);
|
||||
bool runs_once = handler == "render" || handler.rfind("render:", 0) == 0 ||
|
||||
handler == "component" || handler.rfind("component:", 0) == 0;
|
||||
if(slot && once_slot_out && runs_once)
|
||||
*once_slot_out = link_handler("once");
|
||||
record_link();
|
||||
record_probe();
|
||||
return((int32_t)slot);
|
||||
return(slot);
|
||||
}
|
||||
|
||||
String run_task_callback(u64 callback_id)
|
||||
@@ -4013,7 +4016,8 @@ private:
|
||||
self->hostcall_read(args[0].i32(), args[1].i32(), target);
|
||||
self->hostcall_read(args[2].i32(), args[3].i32(), handler);
|
||||
self->hostcall_read(args[4].i32(), args[5].i32(), current);
|
||||
int32_t slot = self->component_resolve(target, handler, current, resolved);
|
||||
int32_t once_slot = 0;
|
||||
int32_t slot = self->component_resolve(target, handler, current, resolved, &once_slot);
|
||||
u32 cap = (u32)args[7].i32();
|
||||
if(cap > 0)
|
||||
{
|
||||
@@ -4022,6 +4026,8 @@ private:
|
||||
resolved.push_back('\0');
|
||||
self->hostcall_write(args[6].i32(), resolved);
|
||||
}
|
||||
String once_slot_bytes((const char*)&once_slot, sizeof(once_slot));
|
||||
self->hostcall_write(args[8].i32(), once_slot_bytes);
|
||||
results[0] = Val(slot);
|
||||
return(std::monostate());
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user