nyrt: split plugin module (#139)
This commit is contained in:
239
crates/nyrt/src/plugin/birth.rs
Normal file
239
crates/nyrt/src/plugin/birth.rs
Normal file
@ -0,0 +1,239 @@
|
||||
// ---- 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
|
||||
let name_opt = nyash_rust::runtime::plugin_loader_unified::get_global_plugin_host()
|
||||
.read()
|
||||
.ok()
|
||||
.and_then(|h| h.config_ref().map(|cfg| cfg.box_types.clone()))
|
||||
.and_then(|m| m.into_iter().find(|(_k, v)| *v == tid).map(|(k, _v)| k));
|
||||
if let Some(box_type) = name_opt {
|
||||
if let Ok(host_g) = nyash_rust::runtime::get_global_plugin_host().read() {
|
||||
if let Ok(b) = host_g.create_box(&box_type, &[]) {
|
||||
let arc: std::sync::Arc<dyn nyash_rust::box_trait::NyashBox> =
|
||||
std::sync::Arc::from(b);
|
||||
let h = nyash_rust::jit::rt::handles::to_handle(arc);
|
||||
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||
println!(
|
||||
"nyrt: birth_h {} (type_id={}) -> handle={}",
|
||||
box_type, tid, 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",
|
||||
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;
|
||||
}
|
||||
let mut invoke: Option<
|
||||
unsafe extern "C" fn(u32, u32, u32, *const u8, usize, *mut u8, *mut usize) -> i32,
|
||||
> = None;
|
||||
// Resolve invoke_fn via temporary instance
|
||||
let box_type_name = nyash_rust::runtime::plugin_loader_unified::get_global_plugin_host()
|
||||
.read()
|
||||
.ok()
|
||||
.and_then(|h| h.config_ref().map(|cfg| cfg.box_types.clone()))
|
||||
.and_then(|m| {
|
||||
m.into_iter()
|
||||
.find(|(_k, v)| *v == (type_id as u32))
|
||||
.map(|(k, _v)| k)
|
||||
})
|
||||
.unwrap_or_else(|| "PluginBox".to_string());
|
||||
if let Ok(host_g) = nyash_rust::runtime::get_global_plugin_host().read() {
|
||||
if let Ok(b) = host_g.create_box(&box_type_name, &[]) {
|
||||
if let Some(p) = b.as_any().downcast_ref::<PluginBoxV2>() {
|
||||
invoke = Some(p.inner.invoke_fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
if invoke.is_none() {
|
||||
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") {
|
||||
eprintln!("nyrt: birth_i64 (type_id={}) FAILED: no invoke", type_id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
let method_id: u32 = 0; // birth
|
||||
let instance_id: u32 = 0; // static
|
||||
// Build TLV args
|
||||
use nyash_rust::jit::rt::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);
|
||||
}
|
||||
// Extra birth args from legacy VM when present
|
||||
if nargs > 2 && std::env::var("NYASH_JIT_ARGS_HANDLE_ONLY").ok().as_deref() != Some("1") {
|
||||
for pos in 3..=nargs {
|
||||
nyash_rust::jit::rt::with_legacy_vm_args(|args| {
|
||||
if let Some(v) = args.get(pos) {
|
||||
use nyash_rust::backend::vm::VMValue as V;
|
||||
match v {
|
||||
V::String(s) => {
|
||||
nyash_rust::runtime::plugin_ffi_common::encode::string(&mut buf, s)
|
||||
}
|
||||
V::Integer(i) => {
|
||||
nyash_rust::runtime::plugin_ffi_common::encode::i64(&mut buf, *i)
|
||||
}
|
||||
V::Float(f) => {
|
||||
nyash_rust::runtime::plugin_ffi_common::encode::f64(&mut buf, *f)
|
||||
}
|
||||
V::Bool(b) => {
|
||||
nyash_rust::runtime::plugin_ffi_common::encode::bool(&mut buf, *b)
|
||||
}
|
||||
V::BoxRef(bx) => {
|
||||
if let Some(pb) = bx.as_any().downcast_ref::<PluginBoxV2>() {
|
||||
if let Some(bufbox) =
|
||||
bx.as_any()
|
||||
.downcast_ref::<nyash_rust::boxes::buffer::BufferBox>()
|
||||
{
|
||||
nyash_rust::runtime::plugin_ffi_common::encode::bytes(
|
||||
&mut buf,
|
||||
&bufbox.to_vec(),
|
||||
);
|
||||
} else {
|
||||
nyash_rust::runtime::plugin_ffi_common::encode::plugin_handle(
|
||||
&mut buf,
|
||||
pb.inner.type_id,
|
||||
pb.instance_id(),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
let s = bx.to_string_box().value;
|
||||
nyash_rust::runtime::plugin_ffi_common::encode::string(&mut buf, &s)
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
let mut out = vec![0u8; 1024];
|
||||
let mut out_len: usize = out.len();
|
||||
let rc = unsafe {
|
||||
invoke.unwrap()(
|
||||
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.unwrap(),
|
||||
);
|
||||
let arc: std::sync::Arc<dyn nyash_rust::box_trait::NyashBox> = std::sync::Arc::new(pb);
|
||||
let h = nyash_rust::jit::rt::handles::to_handle(arc);
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user