177 lines
7.2 KiB
Rust
177 lines
7.2 KiB
Rust
// ---- 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) {
|
|
if let Ok(host_g) = nyash_rust::runtime::get_global_plugin_host().read() {
|
|
if let Ok(b) = host_g.create_box(&meta.box_type, &[]) {
|
|
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;
|
|
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
|
|
);
|
|
}
|
|
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
|
|
);
|
|
}
|
|
}
|
|
} 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 {
|
|
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
|
eprintln!("nyrt: birth_i64 (type_id={}) FAILED: type map", type_id);
|
|
}
|
|
return 0;
|
|
};
|
|
let box_type_name = meta.box_type.clone();
|
|
let invoke_fn = meta.invoke_fn;
|
|
let method_id: u32 = 0; // birth
|
|
let instance_id: u32 = 0; // static
|
|
// Build TLV args
|
|
use nyash_rust::runtime::host_handles as handles;
|
|
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) {
|
|
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
|
|
let mut out = vec![0u8; 1024];
|
|
let mut out_len: usize = out.len();
|
|
let rc = unsafe {
|
|
invoke_fn(
|
|
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,
|
|
);
|
|
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;
|
|
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
|
|
}
|