Phase 21.7 normalization: optimization pre-work + bench harness expansion

- Add opt-in optimizations (defaults OFF)
  - Ret purity verifier: NYASH_VERIFY_RET_PURITY=1
  - strlen FAST enhancement for const handles
  - FAST_INT gate for same-BB SSA optimization
  - length cache for string literals in llvmlite
- Expand bench harness (tools/perf/microbench.sh)
  - Add branch/call/stringchain/arraymap/chip8/kilo cases
  - Auto-calculate ratio vs C reference
  - Document in benchmarks/README.md
- Compiler health improvements
  - Unify PHI insertion to insert_phi_at_head()
  - Add NYASH_LLVM_SKIP_BUILD=1 for build reuse
- Runtime & safety enhancements
  - Clarify Rust/Hako ownership boundaries
  - Strengthen receiver localization (LocalSSA/pin/after-PHIs)
  - Stop excessive PluginInvoke→BoxCall rewrites
- Update CURRENT_TASK.md, docs, and canaries

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-13 16:40:58 +09:00
parent 9e2fa1e36e
commit dda65b94b7
160 changed files with 6773 additions and 1692 deletions

View File

@ -131,6 +131,12 @@ fn main() -> Result<()> {
bail!("input JSON not found: {}", input_path.display());
}
// Optional: dump incoming MIR JSON for diagnostics (AotPrep 後の入力を観測)
if let Ok(dump_path) = env::var("NYASH_LLVM_DUMP_MIR_IN") {
let _ = std::fs::copy(&input_path, &dump_path);
eprintln!("[ny-llvmc] dumped MIR input to {}", dump_path);
}
// Optional: preflight shape/hints (best-effort; no behavior change)
if let Ok(s) = std::fs::read_to_string(&input_path) {
if let Ok(val) = serde_json::from_str::<JsonValue>(&s) {
@ -379,9 +385,26 @@ fn link_executable(
cmd.arg(tok);
}
}
let status = cmd.status().context("failed to invoke system linker")?;
if !status.success() {
bail!("linker exited with status: {:?}", status.code());
// Run linker and capture diagnostics for better error reporting
let output = cmd
.output()
.with_context(|| format!("failed to invoke system linker: {}", linker))?;
if !output.status.success() {
eprintln!("[ny-llvmc/link] command: {}", linker);
// Show args (for debugging)
// Note: std::process::Command doesn't expose argv back; re-emit essential parts
eprintln!(
"[ny-llvmc/link] args: -o {} {} -Wl,--whole-archive {} -Wl,--no-whole-archive -ldl -lpthread -lm {}",
out_exe.display(),
obj.display(),
libnyrt.display(),
extra_libs.unwrap_or("")
);
let stderr = String::from_utf8_lossy(&output.stderr);
let stdout = String::from_utf8_lossy(&output.stdout);
eprintln!("[ny-llvmc/link:stdout]\n{}", stdout);
eprintln!("[ny-llvmc/link:stderr]\n{}", stderr);
bail!("linker exited with status: {:?}", output.status.code());
}
Ok(())
}

View File

@ -38,6 +38,7 @@ pub extern "C" fn nyash_string_len_h(handle: i64) -> i64 {
// FAST-path helper: compute string length from raw pointer (i8*) with mode (reserved)
// Exported as both legacy name (nyash.string.length_si) and neutral name (nyrt_string_length)
#[inline(always)]
#[export_name = "nyrt_string_length"]
pub extern "C" fn nyrt_string_length(ptr: *const i8, _mode: i64) -> i64 {
use std::ffi::CStr;