smokes: add curated LLVM runner; archive legacy smokes; PHI-off unified across Bridge/Builder; LLVM resolver tracing; minimal Throw lowering; config env getters; dev profile and root cleaner; docs updated; CI workflow runs curated LLVM (PHI-on/off)
This commit is contained in:
@ -24,28 +24,47 @@ fn main() {
|
||||
// Read stdin to tmp/ny_mir_builder_input.json for re-use
|
||||
let mut buf = Vec::new();
|
||||
io::stdin().read_to_end(&mut buf).expect("read stdin");
|
||||
if buf.is_empty() { eprintln!("error: no input on stdin"); std::process::exit(2); }
|
||||
let cwd_tmp = Path::new("tmp"); let _ = fs::create_dir_all(cwd_tmp);
|
||||
if buf.is_empty() {
|
||||
eprintln!("error: no input on stdin");
|
||||
std::process::exit(2);
|
||||
}
|
||||
let cwd_tmp = Path::new("tmp");
|
||||
let _ = fs::create_dir_all(cwd_tmp);
|
||||
let cwd_path = cwd_tmp.join("ny_mir_builder_input.json");
|
||||
fs::write(&cwd_path, &buf).expect("write cwd tmp json");
|
||||
cwd_path
|
||||
} else {
|
||||
let p = PathBuf::from(matches.get_one::<String>("in").unwrap());
|
||||
if !p.exists() { eprintln!("error: input not found: {}", p.display()); std::process::exit(2); }
|
||||
if !p.exists() {
|
||||
eprintln!("error: input not found: {}", p.display());
|
||||
std::process::exit(2);
|
||||
}
|
||||
p
|
||||
};
|
||||
|
||||
let emit = matches.get_one::<String>("emit").unwrap().as_str();
|
||||
let out_path = matches.get_one::<String>("out").map(|s| s.to_string()).unwrap_or_else(|| match emit {
|
||||
"obj" => format!("{}/target/aot_objects/a.o", std::env::current_dir().unwrap().display()),
|
||||
"ll" => format!("{}/target/aot_objects/a.ll", std::env::current_dir().unwrap().display()),
|
||||
"exe" => "a.out".to_string(),
|
||||
"json" => "/dev/stdout".to_string(),
|
||||
_ => unreachable!(),
|
||||
});
|
||||
let out_path = matches
|
||||
.get_one::<String>("out")
|
||||
.map(|s| s.to_string())
|
||||
.unwrap_or_else(|| match emit {
|
||||
"obj" => format!(
|
||||
"{}/target/aot_objects/a.o",
|
||||
std::env::current_dir().unwrap().display()
|
||||
),
|
||||
"ll" => format!(
|
||||
"{}/target/aot_objects/a.ll",
|
||||
std::env::current_dir().unwrap().display()
|
||||
),
|
||||
"exe" => "a.out".to_string(),
|
||||
"json" => "/dev/stdout".to_string(),
|
||||
_ => unreachable!(),
|
||||
});
|
||||
let verify = matches.get_flag("verify_llvm");
|
||||
let quiet = matches.get_flag("quiet");
|
||||
let nyrt_dir = matches.get_one::<String>("nyrt").map(|s| s.to_string()).unwrap_or("crates/nyrt".to_string());
|
||||
let nyrt_dir = matches
|
||||
.get_one::<String>("nyrt")
|
||||
.map(|s| s.to_string())
|
||||
.unwrap_or("crates/nyrt".to_string());
|
||||
|
||||
// Determine sibling nyash binary path (target dir)
|
||||
let nyash_bin = current_dir_bin("nyash");
|
||||
@ -56,47 +75,74 @@ fn main() {
|
||||
} else {
|
||||
fs::copy(&in_file, &out_path).expect("copy json");
|
||||
}
|
||||
if !quiet { println!("OK json:{}", out_path); }
|
||||
if !quiet {
|
||||
println!("OK json:{}", out_path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure build dirs
|
||||
let aot_dir = Path::new("target/aot_objects"); let _ = fs::create_dir_all(aot_dir);
|
||||
let aot_dir = Path::new("target/aot_objects");
|
||||
let _ = fs::create_dir_all(aot_dir);
|
||||
|
||||
match emit {
|
||||
"ll" => {
|
||||
std::env::set_var("NYASH_LLVM_DUMP_LL", "1");
|
||||
std::env::set_var("NYASH_LLVM_LL_OUT", &out_path);
|
||||
if verify { std::env::set_var("NYASH_LLVM_VERIFY", "1"); }
|
||||
if verify {
|
||||
std::env::set_var("NYASH_LLVM_VERIFY", "1");
|
||||
}
|
||||
std::env::set_var("NYASH_LLVM_USE_HARNESS", "1");
|
||||
run_nyash_pipe(&nyash_bin, &in_file);
|
||||
if !Path::new(&out_path).exists() { eprintln!("error: failed to produce {}", out_path); std::process::exit(4); }
|
||||
if !quiet { println!("OK ll:{}", out_path); }
|
||||
if !Path::new(&out_path).exists() {
|
||||
eprintln!("error: failed to produce {}", out_path);
|
||||
std::process::exit(4);
|
||||
}
|
||||
if !quiet {
|
||||
println!("OK ll:{}", out_path);
|
||||
}
|
||||
}
|
||||
"obj" => {
|
||||
std::env::set_var("NYASH_LLVM_OBJ_OUT", &out_path);
|
||||
if verify { std::env::set_var("NYASH_LLVM_VERIFY", "1"); }
|
||||
if verify {
|
||||
std::env::set_var("NYASH_LLVM_VERIFY", "1");
|
||||
}
|
||||
std::env::set_var("NYASH_LLVM_USE_HARNESS", "1");
|
||||
// remove stale
|
||||
let _ = fs::remove_file(&out_path);
|
||||
run_nyash_pipe(&nyash_bin, &in_file);
|
||||
if !Path::new(&out_path).exists() { eprintln!("error: failed to produce {}", out_path); std::process::exit(4); }
|
||||
if !quiet { println!("OK obj:{}", out_path); }
|
||||
if !Path::new(&out_path).exists() {
|
||||
eprintln!("error: failed to produce {}", out_path);
|
||||
std::process::exit(4);
|
||||
}
|
||||
if !quiet {
|
||||
println!("OK obj:{}", out_path);
|
||||
}
|
||||
}
|
||||
"exe" => {
|
||||
let obj_path = format!("{}/target/aot_objects/__tmp_mir_builder.o", std::env::current_dir().unwrap().display());
|
||||
let obj_path = format!(
|
||||
"{}/target/aot_objects/__tmp_mir_builder.o",
|
||||
std::env::current_dir().unwrap().display()
|
||||
);
|
||||
std::env::set_var("NYASH_LLVM_OBJ_OUT", &obj_path);
|
||||
if verify { std::env::set_var("NYASH_LLVM_VERIFY", "1"); }
|
||||
if verify {
|
||||
std::env::set_var("NYASH_LLVM_VERIFY", "1");
|
||||
}
|
||||
std::env::set_var("NYASH_LLVM_USE_HARNESS", "1");
|
||||
let _ = fs::remove_file(&obj_path);
|
||||
run_nyash_pipe(&nyash_bin, &in_file);
|
||||
if !Path::new(&obj_path).exists() { eprintln!("error: failed to produce object {}", obj_path); std::process::exit(4); }
|
||||
if !Path::new(&obj_path).exists() {
|
||||
eprintln!("error: failed to produce object {}", obj_path);
|
||||
std::process::exit(4);
|
||||
}
|
||||
// Link with NyRT
|
||||
if let Err(e) = link_exe(&obj_path, &out_path, &nyrt_dir) {
|
||||
eprintln!("error: link failed: {}", e);
|
||||
std::process::exit(5);
|
||||
}
|
||||
if !quiet { println!("OK exe:{}", out_path); }
|
||||
if !quiet {
|
||||
println!("OK exe:{}", out_path);
|
||||
}
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
@ -108,17 +154,23 @@ fn current_dir_bin(name: &str) -> PathBuf {
|
||||
if let Ok(cur) = std::env::current_exe() {
|
||||
if let Some(dir) = cur.parent() {
|
||||
let cand = dir.join(name);
|
||||
if cand.exists() { return cand; }
|
||||
if cand.exists() {
|
||||
return cand;
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let cand = dir.join(format!("{}.exe", name));
|
||||
if cand.exists() { return cand; }
|
||||
if cand.exists() {
|
||||
return cand;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fallback to target/release
|
||||
let cand = PathBuf::from("target/release").join(name);
|
||||
if cand.exists() { return cand; }
|
||||
if cand.exists() {
|
||||
return cand;
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let cand = PathBuf::from("target/release").join(format!("{}.exe", name));
|
||||
@ -157,10 +209,17 @@ fn link_exe(obj_path: &str, out_path: &str, nyrt_dir: &str) -> Result<(), String
|
||||
args.push(obj_path.to_string());
|
||||
// Provide LIBPATH and library name (prefer nyrt.lib)
|
||||
args.push(format!("/LIBPATH:{}", nyrt_release));
|
||||
if std::path::Path::new(&lib_nyrt_lib).exists() { args.push("nyrt.lib".to_string()); }
|
||||
if std::path::Path::new(&lib_nyrt_lib).exists() {
|
||||
args.push("nyrt.lib".to_string());
|
||||
}
|
||||
// lld-link cannot consume .a directly; rely on .lib
|
||||
let status = PCommand::new("lld-link").args(args.iter().map(|s| s.as_str())).status().map_err(|e| e.to_string())?;
|
||||
if status.success() { return Ok(()); }
|
||||
let status = PCommand::new("lld-link")
|
||||
.args(args.iter().map(|s| s.as_str()))
|
||||
.status()
|
||||
.map_err(|e| e.to_string())?;
|
||||
if status.success() {
|
||||
return Ok(());
|
||||
}
|
||||
return Err(format!("lld-link failed: status {:?}", status.code()));
|
||||
}
|
||||
if which::which("link").is_ok() {
|
||||
@ -168,9 +227,16 @@ fn link_exe(obj_path: &str, out_path: &str, nyrt_dir: &str) -> Result<(), String
|
||||
args.push(format!("/OUT:{}", out_path));
|
||||
args.push(obj_path.to_string());
|
||||
args.push(format!("/LIBPATH:{}", nyrt_release));
|
||||
if std::path::Path::new(&lib_nyrt_lib).exists() { args.push("nyrt.lib".to_string()); }
|
||||
let status = PCommand::new("link").args(args.iter().map(|s| s.as_str())).status().map_err(|e| e.to_string())?;
|
||||
if status.success() { return Ok(()); }
|
||||
if std::path::Path::new(&lib_nyrt_lib).exists() {
|
||||
args.push("nyrt.lib".to_string());
|
||||
}
|
||||
let status = PCommand::new("link")
|
||||
.args(args.iter().map(|s| s.as_str()))
|
||||
.status()
|
||||
.map_err(|e| e.to_string())?;
|
||||
if status.success() {
|
||||
return Ok(());
|
||||
}
|
||||
return Err(format!("link.exe failed: status {:?}", status.code()));
|
||||
}
|
||||
// Fallback: try cc with MinGW-like flags
|
||||
@ -178,8 +244,11 @@ fn link_exe(obj_path: &str, out_path: &str, nyrt_dir: &str) -> Result<(), String
|
||||
.args([obj_path])
|
||||
.args(["-L", &format!("{}/target/release", nyrt_dir)])
|
||||
.args(["-lnyrt", "-o", out_path])
|
||||
.status().map_err(|e| e.to_string())?;
|
||||
if status.success() { return Ok(()); }
|
||||
.status()
|
||||
.map_err(|e| e.to_string())?;
|
||||
if status.success() {
|
||||
return Ok(());
|
||||
}
|
||||
return Err(format!("cc link failed: status {:?}", status.code()));
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
@ -190,7 +259,12 @@ fn link_exe(obj_path: &str, out_path: &str, nyrt_dir: &str) -> Result<(), String
|
||||
.args(["-L", &format!("{}/target/release", nyrt_dir)])
|
||||
.args(["-Wl,--whole-archive", "-lnyrt", "-Wl,--no-whole-archive"])
|
||||
.args(["-lpthread", "-ldl", "-lm", "-o", out_path])
|
||||
.status().map_err(|e| e.to_string())?;
|
||||
if status.success() { Ok(()) } else { Err(format!("cc failed: status {:?}", status.code())) }
|
||||
.status()
|
||||
.map_err(|e| e.to_string())?;
|
||||
if status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("cc failed: status {:?}", status.code()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,13 +5,13 @@ use nyash_rust::runtime::{get_global_loader_v2, init_global_loader_v2};
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
|
||||
|
||||
println!("=== v2 Plugin Loader Test (Phase 12 prep) ===\n");
|
||||
|
||||
|
||||
// Load configuration
|
||||
let config_path = "test_nyash_v2.toml";
|
||||
println!("Loading configuration from: {}", config_path);
|
||||
|
||||
|
||||
let config = match NyashConfigV2::from_file(config_path) {
|
||||
Ok(cfg) => cfg,
|
||||
Err(e) => {
|
||||
@ -19,10 +19,10 @@ fn main() {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
println!("Configuration loaded successfully!");
|
||||
println!("Is v2 format: {}", config.is_v2_format());
|
||||
|
||||
|
||||
if let Some(libs) = &config.plugins.libraries {
|
||||
println!("\nLibraries found:");
|
||||
for (name, lib) in libs {
|
||||
@ -30,7 +30,7 @@ fn main() {
|
||||
println!(" Provides: {:?}", lib.provides);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Initialize and load plugins
|
||||
println!("\nLoading plugins...");
|
||||
if let Err(e) = init_global_loader_v2(config_path) {
|
||||
@ -39,12 +39,14 @@ fn main() {
|
||||
}
|
||||
let loader = get_global_loader_v2();
|
||||
let loader = loader.read().unwrap();
|
||||
|
||||
|
||||
// Test box type resolution
|
||||
println!("\nTesting box type resolution:");
|
||||
for box_type in ["StringBox", "FileBox", "MapBox"] {
|
||||
match config.find_library_for_box(box_type) {
|
||||
Some((name, lib)) => println!(" {} -> library: {} (path={})", box_type, name, lib.path),
|
||||
Some((name, lib)) => {
|
||||
println!(" {} -> library: {} (path={})", box_type, name, lib.path)
|
||||
}
|
||||
None => println!(" {} -> not found in config", box_type),
|
||||
}
|
||||
}
|
||||
@ -55,12 +57,13 @@ fn main() {
|
||||
} else {
|
||||
println!("create_box(StringBox) not available or failed (ok for stub)");
|
||||
}
|
||||
|
||||
|
||||
// Simple reverse host-call exercise (simulate plugin calling host via C ABI by-slot)
|
||||
println!("\nReverse host-call (by-slot) quick test:");
|
||||
// Create ArrayBox and obtain HostHandle
|
||||
let mut arr = nyash_rust::boxes::ArrayBox::new();
|
||||
arr.push(Box::new(nyash_rust::box_trait::StringBox::new("init")) as Box<dyn nyash_rust::box_trait::NyashBox>);
|
||||
arr.push(Box::new(nyash_rust::box_trait::StringBox::new("init"))
|
||||
as Box<dyn nyash_rust::box_trait::NyashBox>);
|
||||
let handle = nyash_rust::runtime::host_handles::to_handle_box(Box::new(arr));
|
||||
// Call Array.set(0, "hello") via slot=101
|
||||
let mut tlv = nyash_rust::runtime::plugin_ffi_common::encode_tlv_header(2);
|
||||
@ -68,21 +71,44 @@ fn main() {
|
||||
nyash_rust::runtime::plugin_ffi_common::encode::string(&mut tlv, "hello");
|
||||
let mut out = vec![0u8; 256];
|
||||
let mut out_len: usize = out.len();
|
||||
let code = unsafe { nyash_rust::runtime::host_api::nyrt_host_call_slot(handle, 101, tlv.as_ptr(), tlv.len(), out.as_mut_ptr(), &mut out_len) };
|
||||
let code = unsafe {
|
||||
nyash_rust::runtime::host_api::nyrt_host_call_slot(
|
||||
handle,
|
||||
101,
|
||||
tlv.as_ptr(),
|
||||
tlv.len(),
|
||||
out.as_mut_ptr(),
|
||||
&mut out_len,
|
||||
)
|
||||
};
|
||||
println!(" set(slot=101) -> code={}, out_len={}", code, out_len);
|
||||
// Call Array.get(0) via slot=100 and decode
|
||||
let mut tlv2 = nyash_rust::runtime::plugin_ffi_common::encode_tlv_header(1);
|
||||
nyash_rust::runtime::plugin_ffi_common::encode::i64(&mut tlv2, 0);
|
||||
let mut out2 = vec![0u8; 256];
|
||||
let mut out2_len: usize = out2.len();
|
||||
let code2 = unsafe { nyash_rust::runtime::host_api::nyrt_host_call_slot(handle, 100, tlv2.as_ptr(), tlv2.len(), out2.as_mut_ptr(), &mut out2_len) };
|
||||
let code2 = unsafe {
|
||||
nyash_rust::runtime::host_api::nyrt_host_call_slot(
|
||||
handle,
|
||||
100,
|
||||
tlv2.as_ptr(),
|
||||
tlv2.len(),
|
||||
out2.as_mut_ptr(),
|
||||
&mut out2_len,
|
||||
)
|
||||
};
|
||||
if code2 == 0 {
|
||||
if let Some((tag, _sz, payload)) = nyash_rust::runtime::plugin_ffi_common::decode::tlv_first(&out2[..out2_len]) {
|
||||
if tag == 6 || tag == 7 { // string/bytes
|
||||
if let Some((tag, _sz, payload)) =
|
||||
nyash_rust::runtime::plugin_ffi_common::decode::tlv_first(&out2[..out2_len])
|
||||
{
|
||||
if tag == 6 || tag == 7 {
|
||||
// string/bytes
|
||||
let s = nyash_rust::runtime::plugin_ffi_common::decode::string(payload);
|
||||
println!(" get(slot=100) -> tag={}, value='{}'", tag, s);
|
||||
} else if tag == 3 { // i64
|
||||
let v = nyash_rust::runtime::plugin_ffi_common::decode::i32(payload).unwrap_or_default();
|
||||
} else if tag == 3 {
|
||||
// i64
|
||||
let v = nyash_rust::runtime::plugin_ffi_common::decode::i32(payload)
|
||||
.unwrap_or_default();
|
||||
println!(" get(slot=100) -> tag={}, i32={}", tag, v);
|
||||
} else {
|
||||
println!(" get(slot=100) -> tag={}, size={}", tag, _sz);
|
||||
@ -102,16 +128,36 @@ fn main() {
|
||||
nyash_rust::runtime::plugin_ffi_common::encode::string(&mut tlv_set, "v");
|
||||
let mut out_s = vec![0u8; 256];
|
||||
let mut out_s_len: usize = out_s.len();
|
||||
let code_s = unsafe { nyash_rust::runtime::host_api::nyrt_host_call_slot(map_h, 204, tlv_set.as_ptr(), tlv_set.len(), out_s.as_mut_ptr(), &mut out_s_len) };
|
||||
let code_s = unsafe {
|
||||
nyash_rust::runtime::host_api::nyrt_host_call_slot(
|
||||
map_h,
|
||||
204,
|
||||
tlv_set.as_ptr(),
|
||||
tlv_set.len(),
|
||||
out_s.as_mut_ptr(),
|
||||
&mut out_s_len,
|
||||
)
|
||||
};
|
||||
println!(" set(slot=204) -> code={}, out_len={}", code_s, out_s_len);
|
||||
// get("k") → slot=203
|
||||
let mut tlv_get = nyash_rust::runtime::plugin_ffi_common::encode_tlv_header(1);
|
||||
nyash_rust::runtime::plugin_ffi_common::encode::string(&mut tlv_get, "k");
|
||||
let mut out_g = vec![0u8; 256];
|
||||
let mut out_g_len: usize = out_g.len();
|
||||
let code_g = unsafe { nyash_rust::runtime::host_api::nyrt_host_call_slot(map_h, 203, tlv_get.as_ptr(), tlv_get.len(), out_g.as_mut_ptr(), &mut out_g_len) };
|
||||
let code_g = unsafe {
|
||||
nyash_rust::runtime::host_api::nyrt_host_call_slot(
|
||||
map_h,
|
||||
203,
|
||||
tlv_get.as_ptr(),
|
||||
tlv_get.len(),
|
||||
out_g.as_mut_ptr(),
|
||||
&mut out_g_len,
|
||||
)
|
||||
};
|
||||
if code_g == 0 {
|
||||
if let Some((tag, _sz, payload)) = nyash_rust::runtime::plugin_ffi_common::decode::tlv_first(&out_g[..out_g_len]) {
|
||||
if let Some((tag, _sz, payload)) =
|
||||
nyash_rust::runtime::plugin_ffi_common::decode::tlv_first(&out_g[..out_g_len])
|
||||
{
|
||||
if tag == 6 || tag == 7 {
|
||||
let s = nyash_rust::runtime::plugin_ffi_common::decode::string(payload);
|
||||
println!(" get(slot=203) -> '{}'", s);
|
||||
@ -123,13 +169,37 @@ fn main() {
|
||||
// has("k") → slot=202
|
||||
let mut out_hb = vec![0u8; 16];
|
||||
let mut out_hb_len: usize = out_hb.len();
|
||||
let code_hb = unsafe { nyash_rust::runtime::host_api::nyrt_host_call_slot(map_h, 202, tlv_get.as_ptr(), tlv_get.len(), out_hb.as_mut_ptr(), &mut out_hb_len) };
|
||||
println!(" has(slot=202) -> code={}, out_len={}", code_hb, out_hb_len);
|
||||
let code_hb = unsafe {
|
||||
nyash_rust::runtime::host_api::nyrt_host_call_slot(
|
||||
map_h,
|
||||
202,
|
||||
tlv_get.as_ptr(),
|
||||
tlv_get.len(),
|
||||
out_hb.as_mut_ptr(),
|
||||
&mut out_hb_len,
|
||||
)
|
||||
};
|
||||
println!(
|
||||
" has(slot=202) -> code={}, out_len={}",
|
||||
code_hb, out_hb_len
|
||||
);
|
||||
// size() → slot=200
|
||||
let mut out_sz = vec![0u8; 32];
|
||||
let mut out_sz_len: usize = out_sz.len();
|
||||
let code_sz = unsafe { nyash_rust::runtime::host_api::nyrt_host_call_slot(map_h, 200, std::ptr::null(), 0, out_sz.as_mut_ptr(), &mut out_sz_len) };
|
||||
println!(" size(slot=200) -> code={}, out_len={}", code_sz, out_sz_len);
|
||||
|
||||
let code_sz = unsafe {
|
||||
nyash_rust::runtime::host_api::nyrt_host_call_slot(
|
||||
map_h,
|
||||
200,
|
||||
std::ptr::null(),
|
||||
0,
|
||||
out_sz.as_mut_ptr(),
|
||||
&mut out_sz_len,
|
||||
)
|
||||
};
|
||||
println!(
|
||||
" size(slot=200) -> code={}, out_len={}",
|
||||
code_sz, out_sz_len
|
||||
);
|
||||
|
||||
println!("\nTest completed!");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user