Files
hakorune/crates/nyash_kernel/src/plugin/birth.rs

177 lines
7.2 KiB
Rust
Raw Normal View History

2025-09-11 11:19:55 +09:00
// ---- Handle-based birth shims for AOT/JIT object linkage ----
// These resolve symbols like "nyash.string.birth_h" referenced by ObjectModule.
// Generic birth by type_id -> handle (no args). Exported as nyash.box.birth_h
#[export_name = "nyash.box.birth_h"]
pub extern "C" fn nyash_box_birth_h_export(type_id: i64) -> i64 {
if type_id <= 0 {
return 0;
}
let tid = type_id as u32;
// Map type_id back to type name
if let Some(meta) = nyash_rust::runtime::plugin_loader_v2::metadata_for_type_id(tid) {
2025-09-11 11:19:55 +09:00
if let Ok(host_g) = nyash_rust::runtime::get_global_plugin_host().read() {
if let Ok(b) = host_g.create_box(&meta.box_type, &[]) {
2025-09-11 11:19:55 +09:00
let arc: std::sync::Arc<dyn nyash_rust::box_trait::NyashBox> =
std::sync::Arc::from(b);
let h = nyash_rust::runtime::host_handles::to_handle_arc(arc) as u64;
2025-09-11 11:19:55 +09:00
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
println!(
"nyrt: birth_h {} (type_id={}) -> handle={}",
meta.box_type, meta.type_id, h
2025-09-11 11:19:55 +09:00
);
}
return h as i64;
} else if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
eprintln!(
"nyrt: birth_h {} (type_id={}) FAILED: create_box",
meta.box_type, tid
2025-09-11 11:19:55 +09:00
);
}
}
} else if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
eprintln!("nyrt: birth_h (type_id={}) FAILED: type map not found", tid);
}
0
}
// Generic birth with args: (type_id, argc, a1, a2) -> handle
// Export name: nyash.box.birth_i64
#[export_name = "nyash.box.birth_i64"]
pub extern "C" fn nyash_box_birth_i64_export(type_id: i64, argc: i64, a1: i64, a2: i64) -> i64 {
use nyash_rust::runtime::plugin_loader_v2::PluginBoxV2;
if type_id <= 0 {
return 0;
}
// Resolve invoke_fn via loader metadata
let meta = if let Some(meta) =
nyash_rust::runtime::plugin_loader_v2::metadata_for_type_id(type_id as u32)
{
meta
} else {
2025-09-11 11:19:55 +09:00
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
eprintln!("nyrt: birth_i64 (type_id={}) FAILED: type map", type_id);
2025-09-11 11:19:55 +09:00
}
return 0;
};
let box_type_name = meta.box_type.clone();
let invoke_fn = meta.invoke_fn;
2025-09-11 11:19:55 +09:00
let method_id: u32 = 0; // birth
let instance_id: u32 = 0; // static
// Build TLV args
use nyash_rust::runtime::host_handles as handles;
2025-09-11 11:19:55 +09:00
let nargs = argc.max(0) as usize;
let mut buf = nyash_rust::runtime::plugin_ffi_common::encode_tlv_header(nargs as u16);
let mut encode_handle = |h: i64| {
if h > 0 {
if let Some(obj) = handles::get(h as u64) {
2025-09-11 11:19:55 +09:00
if let Some(p) = obj.as_any().downcast_ref::<PluginBoxV2>() {
let host = nyash_rust::runtime::get_global_plugin_host();
if let Ok(hg) = host.read() {
if p.box_type == "StringBox" {
if let Ok(Some(sb)) = hg.invoke_instance_method(
"StringBox",
"toUtf8",
p.instance_id(),
&[],
) {
if let Some(s) = sb
.as_any()
.downcast_ref::<nyash_rust::box_trait::StringBox>()
{
nyash_rust::runtime::plugin_ffi_common::encode::string(
&mut buf, &s.value,
);
return;
}
}
} else if p.box_type == "IntegerBox" {
if let Ok(Some(ibx)) =
hg.invoke_instance_method("IntegerBox", "get", p.instance_id(), &[])
{
if let Some(i) = ibx
.as_any()
.downcast_ref::<nyash_rust::box_trait::IntegerBox>()
{
nyash_rust::runtime::plugin_ffi_common::encode::i64(
&mut buf, i.value,
);
return;
}
}
}
}
nyash_rust::runtime::plugin_ffi_common::encode::plugin_handle(
&mut buf,
p.inner.type_id,
p.instance_id(),
);
return;
}
}
}
nyash_rust::runtime::plugin_ffi_common::encode::i64(&mut buf, h);
};
if nargs >= 1 {
encode_handle(a1);
}
if nargs >= 2 {
encode_handle(a2);
}
// ✂️ REMOVED: Legacy VM argument processing for args 3+
// In Plugin-First architecture, birth functions are limited to 2 explicit arguments
// Extended argument support removed with legacy VM system archival
2025-09-11 11:19:55 +09:00
let mut out = vec![0u8; 1024];
let mut out_len: usize = out.len();
let rc = unsafe {
invoke_fn(
2025-09-11 11:19:55 +09:00
type_id as u32,
method_id,
instance_id,
buf.as_ptr(),
buf.len(),
out.as_mut_ptr(),
&mut out_len,
)
};
if rc != 0 {
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
eprintln!(
"nyrt: birth_i64 (type_id={}) FAILED: invoke rc={}",
type_id, rc
);
}
return 0;
}
if let Some((tag, _sz, payload)) =
nyash_rust::runtime::plugin_ffi_common::decode::tlv_first(&out[..out_len])
{
if tag == 8 && payload.len() == 8 {
let mut t = [0u8; 4];
t.copy_from_slice(&payload[0..4]);
let mut i = [0u8; 4];
i.copy_from_slice(&payload[4..8]);
let r_type = u32::from_le_bytes(t);
let r_inst = u32::from_le_bytes(i);
let pb = nyash_rust::runtime::plugin_loader_v2::make_plugin_box_v2(
box_type_name.clone(),
r_type,
r_inst,
invoke_fn,
2025-09-11 11:19:55 +09:00
);
let arc: std::sync::Arc<dyn nyash_rust::box_trait::NyashBox> = std::sync::Arc::new(pb);
let h = nyash_rust::runtime::host_handles::to_handle_arc(arc) as u64;
2025-09-11 11:19:55 +09:00
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
println!(
"nyrt: birth_i64 {} (type_id={}) argc={} -> handle={}",
box_type_name, type_id, nargs, h
);
}
return h as i64;
}
}
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
eprintln!("nyrt: birth_i64 (type_id={}) FAILED: decode", type_id);
}
0
}