Phase 25.4 メンテナンス: Task A延長線上の箱化リファクタリング
## 📦 箱化内容
### 1. Entry選択ロジック統一箱
- 新規作成: `src/runner/modes/common_util/entry_selection.rs`
- 3箇所の重複ロジックを `select_entry_function()` に集約
- `selfhost/json.rs:48-59` (11行削減)
- `pyvm.rs:32-43` (11行削減)
- `pyvm.rs:102-113` (11行削減)
- `llvm.rs:292` (直接アクセス→統一関数呼び出し)
### 2. NamingBox SSOT 統合
- arity-aware優先フォールバック実装
1. `Main.main/0` (arity付き、NYASH_BUILD_STATIC_MAIN_ENTRY=1時)
2. `Main.main` (legacy、arity無し、現行デフォルト)
3. `main` (top-level、NYASH_ENTRY_ALLOW_TOPLEVEL_MAIN=1時)
4. `"Main.main"` (デフォルトフォールバック)
## 技術的成果
- **重複削減**: 33行の重複ロジック→1箇所に集約
- **NamingBox統一**: 全Entry選択が `src/mir/naming.rs` 経由
- **将来対応**: arity付き名前に自動対応(互換性維持)
## テスト結果
✅ cargo test mir_static_box_naming: 2 passed
✅ cargo test stage1_cli_entry_ssa_smoke: 2 passed
## 参考
- Phase 25.4-A完了commit: fa9cea51
- 箱理論原則: 重複ロジックを箱化→境界を明確化→一元管理
🎉 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
121 lines
4.7 KiB
Rust
121 lines
4.7 KiB
Rust
// no extra imports needed
|
||
|
||
/// Run PyVM harness over a MIR module, returning the exit code
|
||
#[allow(dead_code)]
|
||
pub fn run_pyvm_harness(module: &crate::mir::MirModule, tag: &str) -> Result<i32, String> {
|
||
let py3 = which::which("python3").map_err(|e| format!("python3 not found: {}", e))?;
|
||
// Resolve runner path relative to CWD or NYASH_ROOT fallback
|
||
let mut runner_buf = std::path::PathBuf::from("tools/pyvm_runner.py");
|
||
if !runner_buf.exists() {
|
||
if let Ok(root) = std::env::var("NYASH_ROOT") {
|
||
let alt = std::path::Path::new(&root).join("tools/pyvm_runner.py");
|
||
if alt.exists() {
|
||
runner_buf = alt;
|
||
}
|
||
}
|
||
}
|
||
if !runner_buf.exists() {
|
||
return Err(format!(
|
||
"PyVM runner not found: tools/pyvm_runner.py (cwd) or $NYASH_ROOT/tools/pyvm_runner.py"
|
||
));
|
||
}
|
||
let tmp_dir = std::path::Path::new("tmp");
|
||
let _ = std::fs::create_dir_all(tmp_dir);
|
||
let mir_json_path = tmp_dir.join("nyash_pyvm_mir.json");
|
||
crate::runner::mir_json_emit::emit_mir_json_for_harness_bin(module, &mir_json_path)
|
||
.map_err(|e| format!("PyVM MIR JSON emit error: {}", e))?;
|
||
crate::cli_v!(
|
||
"[ny-compiler] using PyVM ({} ) → {}",
|
||
tag,
|
||
mir_json_path.display()
|
||
);
|
||
// NamingBox SSOT: Select entry (arity-aware, Main.main → main fallback)
|
||
let entry = super::entry_selection::select_entry_function(&module);
|
||
// Optional: Mini‑VM stdin loader — when enabled, read entire stdin and pass as argv[0]
|
||
let mut cmd = std::process::Command::new(py3);
|
||
crate::runner::child_env::apply_core_wrapper_env(&mut cmd);
|
||
if std::env::var("NYASH_MINIVM_READ_STDIN").ok().as_deref() == Some("1") {
|
||
use std::io::Read;
|
||
let mut buf = String::new();
|
||
let _ = std::io::stdin().read_to_string(&mut buf);
|
||
// Wrap as argv JSON array [string]
|
||
let arg_json = serde_json::json!([buf]).to_string();
|
||
cmd.env("NYASH_SCRIPT_ARGS_JSON", arg_json);
|
||
}
|
||
let status = cmd
|
||
.args([
|
||
runner_buf.to_string_lossy().as_ref(),
|
||
"--in",
|
||
&mir_json_path.display().to_string(),
|
||
"--entry",
|
||
&entry,
|
||
"--args-env",
|
||
"NYASH_SCRIPT_ARGS_JSON",
|
||
])
|
||
.status()
|
||
.map_err(|e| format!("spawn pyvm: {}", e))?;
|
||
let code = status.code().unwrap_or(1);
|
||
if !status.success() {
|
||
crate::cli_v!("❌ PyVM ({}) failed (status={})", tag, code);
|
||
}
|
||
Ok(code)
|
||
}
|
||
|
||
/// Run PyVM harness over a nyash_rust (lib) MIR module, returning the exit code
|
||
#[allow(dead_code)]
|
||
pub fn run_pyvm_harness_lib(module: &nyash_rust::mir::MirModule, tag: &str) -> Result<i32, String> {
|
||
let py3 = which::which("python3").map_err(|e| format!("python3 not found: {}", e))?;
|
||
let mut runner_buf = std::path::PathBuf::from("tools/pyvm_runner.py");
|
||
if !runner_buf.exists() {
|
||
if let Ok(root) = std::env::var("NYASH_ROOT") {
|
||
let alt = std::path::Path::new(&root).join("tools/pyvm_runner.py");
|
||
if alt.exists() {
|
||
runner_buf = alt;
|
||
}
|
||
}
|
||
}
|
||
if !runner_buf.exists() {
|
||
return Err(format!(
|
||
"PyVM runner not found: tools/pyvm_runner.py (cwd) or $NYASH_ROOT/tools/pyvm_runner.py"
|
||
));
|
||
}
|
||
let tmp_dir = std::path::Path::new("tmp");
|
||
let _ = std::fs::create_dir_all(tmp_dir);
|
||
let mir_json_path = tmp_dir.join("nyash_pyvm_mir.json");
|
||
crate::runner::mir_json_emit::emit_mir_json_for_harness(module, &mir_json_path)
|
||
.map_err(|e| format!("PyVM MIR JSON emit error: {}", e))?;
|
||
crate::cli_v!(
|
||
"[Runner] using PyVM ({} ) → {}",
|
||
tag,
|
||
mir_json_path.display()
|
||
);
|
||
// NamingBox SSOT: Select entry (arity-aware, Main.main → main fallback)
|
||
let entry = super::entry_selection::select_entry_function(&module);
|
||
let mut cmd = std::process::Command::new(py3);
|
||
crate::runner::child_env::apply_core_wrapper_env(&mut cmd);
|
||
if std::env::var("NYASH_MINIVM_READ_STDIN").ok().as_deref() == Some("1") {
|
||
use std::io::Read;
|
||
let mut buf = String::new();
|
||
let _ = std::io::stdin().read_to_string(&mut buf);
|
||
let arg_json = serde_json::json!([buf]).to_string();
|
||
cmd.env("NYASH_SCRIPT_ARGS_JSON", arg_json);
|
||
}
|
||
let status = cmd
|
||
.args([
|
||
runner_buf.to_string_lossy().as_ref(),
|
||
"--in",
|
||
&mir_json_path.display().to_string(),
|
||
"--entry",
|
||
&entry,
|
||
"--args-env",
|
||
"NYASH_SCRIPT_ARGS_JSON",
|
||
])
|
||
.status()
|
||
.map_err(|e| format!("spawn pyvm: {}", e))?;
|
||
let code = status.code().unwrap_or(1);
|
||
if !status.success() {
|
||
crate::cli_v!("❌ PyVM ({}) failed (status={})", tag, code);
|
||
}
|
||
Ok(code)
|
||
}
|