docs/runtime: externcall + println normalization; NyRT silent result flag; PyVM console warn/error/trace routing\nselfhost(M2): add MirEmitterBox (Return(Int)->const+ret) and --emit-mir switch; initial selfhost smoke\nrunner: child args/env hardening for selfhost (NYASH_NY_COMPILER_CHILD_ARGS under --; NYASH_JSON_ONLY=1, NYASH_VM_USE_PY=1, NYASH_DISABLE_PLUGINS=1); VM path strips using lines when NYASH_ENABLE_USING=1\nmeta: clarify PyVM/llvmlite as primary (vm/interpreter legacy OFF) in CURRENT_TASK.md; README links to externcall docs

This commit is contained in:
Selfhosting Dev
2025-09-18 06:35:49 +09:00
parent 9a7d77d868
commit 3fe908eb0d
26 changed files with 514 additions and 22 deletions

View File

@ -458,15 +458,26 @@ class PyVM:
func = inst.get("func")
args = [self._read(regs, a) for a in inst.get("args", [])]
out: Any = None
if func == "nyash.console.println":
s = args[0] if args else ""
if s is None:
s = ""
print(str(s))
out = 0
else:
# Unknown extern
out = None
# Normalize known console/debug externs
if isinstance(func, str):
if func in ("nyash.console.println", "nyash.console.log", "env.console.log"):
s = args[0] if args else ""
if s is None:
s = ""
print(str(s))
out = 0
elif func in ("nyash.console.warn", "env.console.warn", "nyash.console.error", "env.console.error", "nyash.debug.trace", "env.debug.trace"):
s = args[0] if args else ""
if s is None:
s = ""
# Write to stderr for warn/error/trace to approximate real consoles
try:
import sys as _sys
print(str(s), file=_sys.stderr)
except Exception:
print(str(s))
out = 0
# Unknown extern -> no-op with 0/None
self._set(regs, inst.get("dst"), out)
i += 1
continue

View File

@ -327,21 +327,32 @@ impl NyashRunner {
// - NYASH_SELFHOST_READ_TMP=1 → "-- --read-tmp"
// - NYASH_NY_COMPILER_CHILD_ARGS: additional raw args (split by whitespace)
let min_json = std::env::var("NYASH_NY_COMPILER_MIN_JSON").ok().unwrap_or_else(|| "0".to_string());
if min_json == "1" { cmd.arg("--").arg("--min-json"); }
let mut inserted_sep = false;
if min_json == "1" {
cmd.arg("--").arg("--min-json");
inserted_sep = true;
}
if std::env::var("NYASH_SELFHOST_READ_TMP").ok().as_deref() == Some("1") {
cmd.arg("--").arg("--read-tmp");
if !inserted_sep { cmd.arg("--"); inserted_sep = true; }
cmd.arg("--read-tmp");
}
if let Ok(raw) = std::env::var("NYASH_NY_COMPILER_CHILD_ARGS") {
if !inserted_sep { cmd.arg("--"); inserted_sep = true; }
for tok in raw.split_whitespace() { cmd.arg(tok); }
}
// Propagate minimal env; disable plugins to reduce noise
// Propagate minimal env; prefer stdlib over plugins in child for stable stdout
cmd.env_remove("NYASH_USE_NY_COMPILER");
cmd.env_remove("NYASH_CLI_VERBOSE");
cmd.env("NYASH_DISABLE_PLUGINS", "1");
cmd.env_remove("NYASH_USE_PLUGIN_BUILTINS");
// Suppress parent runner's result printing in child
cmd.env("NYASH_JSON_ONLY", "1");
// Prefer PyVM in child to ensure println/externcall are printed to stdout deterministically
cmd.env("NYASH_VM_USE_PY", "1");
// Propagate optional gates to child (if present)
if let Ok(v) = std::env::var("NYASH_JSON_INCLUDE_USINGS") { cmd.env("NYASH_JSON_INCLUDE_USINGS", v); }
if let Ok(v) = std::env::var("NYASH_ENABLE_USING") { cmd.env("NYASH_ENABLE_USING", v); }
if let Ok(v) = std::env::var("NYASH_ENABLE_USING") { cmd.env("NYASH_ENABLE_USING", v); }
// Child timeout guard (Hotfix for potential infinite loop in child Ny parser)
// Config: NYASH_NY_COMPILER_TIMEOUT_MS (default 2000ms)
let timeout_ms: u64 = std::env::var("NYASH_NY_COMPILER_TIMEOUT_MS")

View File

@ -101,6 +101,22 @@ impl NyashRunner {
}
};
// Optional Phase-15: strip `using` lines (gate) for minimal acceptance in VM path
let enable_using = crate::config::env::enable_using();
let code = if enable_using {
let mut out = String::with_capacity(code.len());
for line in code.lines() {
let t = line.trim_start();
if t.starts_with("using ") {
// Strip using lines (module resolution handled by nyash.toml elsewhere)
continue;
}
out.push_str(line);
out.push('\n');
}
out
} else { code };
// Parse to AST
let ast = match NyashParser::parse_from_string(&code) {
Ok(ast) => ast,