2025-09-03 05:04:56 +09:00
|
|
|
|
//! Global environment configuration aggregator (管理棟)
|
|
|
|
|
|
//!
|
|
|
|
|
|
//! Consolidates NYASH_* environment variables across subsystems and
|
|
|
|
|
|
//! optionally applies overrides from `nyash.toml`.
|
|
|
|
|
|
|
|
|
|
|
|
use std::collections::BTreeMap;
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Default)]
|
|
|
|
|
|
pub struct NyashEnv {
|
|
|
|
|
|
/// JIT-related configuration (delegates to jit::config)
|
|
|
|
|
|
pub jit: crate::jit::config::JitConfig,
|
|
|
|
|
|
/// Arbitrary key-value overrides loaded from nyash.toml [env]
|
|
|
|
|
|
pub overrides: BTreeMap<String, String>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl NyashEnv {
|
|
|
|
|
|
pub fn from_env() -> Self {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
Self {
|
|
|
|
|
|
jit: crate::jit::config::JitConfig::from_env(),
|
|
|
|
|
|
overrides: BTreeMap::new(),
|
|
|
|
|
|
}
|
2025-09-03 05:04:56 +09:00
|
|
|
|
}
|
|
|
|
|
|
/// Apply current struct values into process environment
|
|
|
|
|
|
pub fn apply_env(&self) {
|
|
|
|
|
|
self.jit.apply_env();
|
2025-09-17 07:43:07 +09:00
|
|
|
|
for (k, v) in &self.overrides {
|
|
|
|
|
|
std::env::set_var(k, v);
|
|
|
|
|
|
}
|
2025-09-03 05:04:56 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Global current env config (thread-safe)
|
|
|
|
|
|
use once_cell::sync::OnceCell;
|
|
|
|
|
|
use std::sync::RwLock;
|
|
|
|
|
|
|
|
|
|
|
|
static GLOBAL_ENV: OnceCell<RwLock<NyashEnv>> = OnceCell::new();
|
2025-09-19 02:07:38 +09:00
|
|
|
|
static PHI_ON_GATED_WARNED: OnceCell<()> = OnceCell::new();
|
2025-09-03 05:04:56 +09:00
|
|
|
|
|
|
|
|
|
|
pub fn current() -> NyashEnv {
|
|
|
|
|
|
if let Some(lock) = GLOBAL_ENV.get() {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
if let Ok(cfg) = lock.read() {
|
|
|
|
|
|
return cfg.clone();
|
|
|
|
|
|
}
|
2025-09-03 05:04:56 +09:00
|
|
|
|
}
|
|
|
|
|
|
NyashEnv::from_env()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn set_current(cfg: NyashEnv) {
|
|
|
|
|
|
if let Some(lock) = GLOBAL_ENV.get() {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
if let Ok(mut w) = lock.write() {
|
|
|
|
|
|
*w = cfg;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-09-03 05:04:56 +09:00
|
|
|
|
}
|
|
|
|
|
|
let _ = GLOBAL_ENV.set(RwLock::new(cfg));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Load overrides from nyash.toml `[env]` table and apply them to process env.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// Example:
|
|
|
|
|
|
/// [env]
|
|
|
|
|
|
/// NYASH_JIT_THRESHOLD = "1"
|
|
|
|
|
|
/// NYASH_CLI_VERBOSE = "1"
|
|
|
|
|
|
pub fn bootstrap_from_toml_env() {
|
2025-09-05 15:18:13 +09:00
|
|
|
|
// Allow disabling nyash.toml env bootstrapping for isolated smokes/CI
|
|
|
|
|
|
if std::env::var("NYASH_SKIP_TOML_ENV").ok().as_deref() == Some("1") {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-09-03 05:04:56 +09:00
|
|
|
|
let path = "nyash.toml";
|
2025-09-17 07:43:07 +09:00
|
|
|
|
let content = match std::fs::read_to_string(path) {
|
|
|
|
|
|
Ok(s) => s,
|
|
|
|
|
|
Err(_) => return,
|
|
|
|
|
|
};
|
|
|
|
|
|
let Ok(value) = toml::from_str::<toml::Value>(&content) else {
|
|
|
|
|
|
return;
|
|
|
|
|
|
};
|
|
|
|
|
|
let Some(env_tbl) = value.get("env").and_then(|v| v.as_table()) else {
|
|
|
|
|
|
return;
|
|
|
|
|
|
};
|
2025-09-03 05:04:56 +09:00
|
|
|
|
let mut overrides: BTreeMap<String, String> = BTreeMap::new();
|
|
|
|
|
|
for (k, v) in env_tbl {
|
|
|
|
|
|
if let Some(s) = v.as_str() {
|
|
|
|
|
|
std::env::set_var(k, s);
|
|
|
|
|
|
overrides.insert(k.clone(), s.to_string());
|
|
|
|
|
|
} else if let Some(b) = v.as_bool() {
|
|
|
|
|
|
let sv = if b { "1" } else { "0" };
|
|
|
|
|
|
std::env::set_var(k, sv);
|
|
|
|
|
|
overrides.insert(k.clone(), sv.to_string());
|
|
|
|
|
|
} else if let Some(n) = v.as_integer() {
|
|
|
|
|
|
let sv = n.to_string();
|
|
|
|
|
|
std::env::set_var(k, &sv);
|
|
|
|
|
|
overrides.insert(k.clone(), sv);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// Merge into global
|
|
|
|
|
|
let mut cur = current();
|
|
|
|
|
|
cur.overrides.extend(overrides);
|
|
|
|
|
|
set_current(cur);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Get await maximum milliseconds, centralized here for consistency.
|
|
|
|
|
|
pub fn await_max_ms() -> u64 {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
std::env::var("NYASH_AWAIT_MAX_MS")
|
|
|
|
|
|
.ok()
|
|
|
|
|
|
.and_then(|s| s.parse().ok())
|
|
|
|
|
|
.unwrap_or(5000)
|
2025-09-03 05:04:56 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-16 23:49:36 +09:00
|
|
|
|
// ---- MIR PHI-less (edge-copy) mode ----
|
|
|
|
|
|
/// Enable MIR PHI non-generation. Bridge/Builder emit edge copies instead of PHI.
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn mir_no_phi() -> bool {
|
2025-09-17 10:58:12 +09:00
|
|
|
|
match std::env::var("NYASH_MIR_NO_PHI").ok() {
|
|
|
|
|
|
Some(v) => {
|
|
|
|
|
|
let lv = v.to_ascii_lowercase();
|
2025-09-19 02:07:38 +09:00
|
|
|
|
let requested_no_phi = !(lv == "0" || lv == "false" || lv == "off");
|
|
|
|
|
|
if requested_no_phi {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
// PHI-on requested
|
|
|
|
|
|
#[cfg(feature = "phi-legacy")]
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
#[cfg(not(feature = "phi-legacy"))]
|
|
|
|
|
|
{
|
|
|
|
|
|
if PHI_ON_GATED_WARNED.set(()).is_ok() {
|
|
|
|
|
|
eprintln!(
|
|
|
|
|
|
"[nyash] PHI-on requested but disabled in this build (missing 'phi-legacy' feature). Falling back to PHI-off."
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2025-09-17 10:58:12 +09:00
|
|
|
|
}
|
|
|
|
|
|
// Default: ON for MIR13 stability (PHI generation off by default)
|
|
|
|
|
|
None => true,
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
}
|
2025-09-16 23:49:36 +09:00
|
|
|
|
|
|
|
|
|
|
/// Allow verifier to skip SSA/dominance/merge checks for PHI-less MIR.
|
|
|
|
|
|
pub fn verify_allow_no_phi() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_VERIFY_ALLOW_NO_PHI").ok().as_deref() == Some("1") || mir_no_phi()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-19 02:07:38 +09:00
|
|
|
|
/// Enable strict edge-copy policy verification in PHI-off mode.
|
|
|
|
|
|
/// When enabled, merge blocks must receive merged values via predecessor copies only,
|
|
|
|
|
|
/// and the merge block itself must not introduce a self-copy to the merged destination.
|
|
|
|
|
|
pub fn verify_edge_copy_strict() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_VERIFY_EDGE_COPY_STRICT").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-16 23:49:36 +09:00
|
|
|
|
// ---- LLVM harness toggle (llvmlite) ----
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn llvm_use_harness() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_LLVM_USE_HARNESS").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
2025-09-16 23:49:36 +09:00
|
|
|
|
|
2025-09-03 05:04:56 +09:00
|
|
|
|
// ---- Phase 11.8 MIR cleanup toggles ----
|
2025-09-07 07:28:53 +09:00
|
|
|
|
/// Core-13 minimal MIR mode toggle
|
|
|
|
|
|
/// Default: ON (unless explicitly disabled with NYASH_MIR_CORE13=0)
|
|
|
|
|
|
pub fn mir_core13() -> bool {
|
|
|
|
|
|
match std::env::var("NYASH_MIR_CORE13").ok() {
|
|
|
|
|
|
Some(v) => {
|
|
|
|
|
|
let lv = v.to_ascii_lowercase();
|
|
|
|
|
|
!(lv == "0" || lv == "false" || lv == "off")
|
|
|
|
|
|
}
|
|
|
|
|
|
None => true,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn mir_ref_boxcall() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_MIR_REF_BOXCALL").ok().as_deref() == Some("1") || mir_core13()
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn mir_array_boxcall() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_MIR_ARRAY_BOXCALL").ok().as_deref() == Some("1") || mir_core13()
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn mir_plugin_invoke() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_MIR_PLUGIN_INVOKE").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn plugin_only() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_PLUGIN_ONLY").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
2025-09-03 05:04:56 +09:00
|
|
|
|
|
2025-09-07 07:28:53 +09:00
|
|
|
|
/// Core-13 "pure" mode: after normalization, only the 13 canonical ops are allowed.
|
|
|
|
|
|
/// If enabled, the optimizer will try lightweight rewrites for Load/Store/NewBox/Unary,
|
|
|
|
|
|
/// and the final verifier will reject any remaining non-Core-13 ops.
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn mir_core13_pure() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_MIR_CORE13_PURE").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
2025-09-07 07:28:53 +09:00
|
|
|
|
|
2025-09-03 05:04:56 +09:00
|
|
|
|
// ---- Optimizer diagnostics ----
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn opt_debug() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_OPT_DEBUG").is_ok()
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn opt_diag() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_OPT_DIAG").is_ok()
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn opt_diag_forbid_legacy() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_OPT_DIAG_FORBID_LEGACY").is_ok()
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn opt_diag_fail() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_OPT_DIAG_FAIL").is_ok()
|
|
|
|
|
|
}
|
2025-09-03 05:04:56 +09:00
|
|
|
|
|
|
|
|
|
|
// ---- GC/Runtime tracing (execution-affecting visibility) ----
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn gc_trace() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_GC_TRACE").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn gc_barrier_trace() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_GC_BARRIER_TRACE").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn runtime_checkpoint_trace() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_RUNTIME_CHECKPOINT_TRACE")
|
|
|
|
|
|
.ok()
|
|
|
|
|
|
.as_deref()
|
|
|
|
|
|
== Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn vm_pic_stats() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_VM_PIC_STATS").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn vm_vt_trace() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_VM_VT_TRACE").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn vm_pic_trace() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_VM_PIC_TRACE").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn gc_barrier_strict() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_GC_BARRIER_STRICT").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
2025-09-03 05:04:56 +09:00
|
|
|
|
|
|
|
|
|
|
/// Return 0 (off) to 3 (max) for `NYASH_GC_TRACE`.
|
|
|
|
|
|
pub fn gc_trace_level() -> u8 {
|
|
|
|
|
|
match std::env::var("NYASH_GC_TRACE").ok().as_deref() {
|
|
|
|
|
|
Some("1") => 1,
|
|
|
|
|
|
Some("2") => 2,
|
|
|
|
|
|
Some("3") => 3,
|
|
|
|
|
|
Some(_) => 1,
|
|
|
|
|
|
None => 0,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-17 20:33:19 +09:00
|
|
|
|
// ---- GC mode and instrumentation ----
|
|
|
|
|
|
/// Return current GC mode string (auto default = "rc+cycle").
|
|
|
|
|
|
/// Allowed: "auto", "rc+cycle", "minorgen", "stw", "rc", "off"
|
|
|
|
|
|
pub fn gc_mode() -> String {
|
|
|
|
|
|
match std::env::var("NYASH_GC_MODE").ok() {
|
|
|
|
|
|
Some(m) if !m.trim().is_empty() => m,
|
|
|
|
|
|
_ => "rc+cycle".to_string(),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/// Brief metrics emission (text)
|
|
|
|
|
|
pub fn gc_metrics() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_GC_METRICS").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
/// JSON metrics emission (single line)
|
|
|
|
|
|
pub fn gc_metrics_json() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_GC_METRICS_JSON").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
/// Leak diagnostics on exit
|
|
|
|
|
|
pub fn gc_leak_diag() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_GC_LEAK_DIAG").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
/// Optional allocation threshold; if Some(n) and exceeded, print warning
|
|
|
|
|
|
pub fn gc_alloc_threshold() -> Option<u64> {
|
|
|
|
|
|
std::env::var("NYASH_GC_ALLOC_THRESHOLD").ok()?.parse().ok()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-19 02:07:38 +09:00
|
|
|
|
// ---- Cleanup (method-level postfix) policy toggles ----
|
|
|
|
|
|
/// Allow `return` inside a cleanup block. Default: false (0)
|
|
|
|
|
|
pub fn cleanup_allow_return() -> bool {
|
|
|
|
|
|
match std::env::var("NYASH_CLEANUP_ALLOW_RETURN").ok() {
|
|
|
|
|
|
Some(v) => {
|
|
|
|
|
|
let lv = v.to_ascii_lowercase();
|
|
|
|
|
|
!(lv == "0" || lv == "false" || lv == "off")
|
|
|
|
|
|
}
|
|
|
|
|
|
None => false,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Allow `throw` inside a cleanup block. Default: false (0)
|
|
|
|
|
|
pub fn cleanup_allow_throw() -> bool {
|
|
|
|
|
|
match std::env::var("NYASH_CLEANUP_ALLOW_THROW").ok() {
|
|
|
|
|
|
Some(v) => {
|
|
|
|
|
|
let lv = v.to_ascii_lowercase();
|
|
|
|
|
|
!(lv == "0" || lv == "false" || lv == "off")
|
|
|
|
|
|
}
|
|
|
|
|
|
None => false,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-17 20:33:19 +09:00
|
|
|
|
/// Run a collection every N safepoints (if Some)
|
|
|
|
|
|
pub fn gc_collect_sp_interval() -> Option<u64> {
|
|
|
|
|
|
std::env::var("NYASH_GC_COLLECT_SP").ok()?.parse().ok()
|
|
|
|
|
|
}
|
|
|
|
|
|
/// Run a collection when allocated bytes since last >= N (if Some)
|
|
|
|
|
|
pub fn gc_collect_alloc_bytes() -> Option<u64> {
|
|
|
|
|
|
std::env::var("NYASH_GC_COLLECT_ALLOC").ok()?.parse().ok()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-03 05:04:56 +09:00
|
|
|
|
// ---- Rewriter flags (optimizer transforms)
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn rewrite_debug() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_REWRITE_DEBUG").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn rewrite_safepoint() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_REWRITE_SAFEPOINT").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn rewrite_future() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_REWRITE_FUTURE").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
2025-09-03 05:04:56 +09:00
|
|
|
|
|
|
|
|
|
|
// ---- Phase 12: Nyash ABI (vtable) toggles ----
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn abi_vtable() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_ABI_VTABLE").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn abi_strict() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_ABI_STRICT").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
2025-09-03 05:41:33 +09:00
|
|
|
|
|
|
|
|
|
|
// ---- ExternCall strict diagnostics ----
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn extern_strict() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_EXTERN_STRICT").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn extern_trace() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_EXTERN_TRACE").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
2025-09-03 09:12:39 +09:00
|
|
|
|
|
|
|
|
|
|
// ---- Phase 12: thresholds and routing policies ----
|
|
|
|
|
|
/// PIC hotness threshold before promoting to mono cache.
|
|
|
|
|
|
pub fn vm_pic_threshold() -> u32 {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
std::env::var("NYASH_VM_PIC_THRESHOLD")
|
|
|
|
|
|
.ok()
|
|
|
|
|
|
.and_then(|s| s.parse().ok())
|
|
|
|
|
|
.unwrap_or(8)
|
2025-09-03 09:12:39 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Route VM ExternCall via name→slot handlers when available
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn extern_route_slots() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_EXTERN_ROUTE_SLOTS").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
2025-09-17 06:55:39 +09:00
|
|
|
|
|
|
|
|
|
|
// ---- Runner/CLI common toggles (hot-path centralization)
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn cli_verbose() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn enable_using() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_ENABLE_USING").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn vm_use_py() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_VM_USE_PY").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn pipe_use_pyvm() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_PIPE_USE_PYVM").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn vm_use_dispatch() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_VM_USE_DISPATCH").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
2025-09-17 06:55:39 +09:00
|
|
|
|
|
|
|
|
|
|
// Self-host compiler knobs
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn ny_compiler_timeout_ms() -> u64 {
|
|
|
|
|
|
std::env::var("NYASH_NY_COMPILER_TIMEOUT_MS")
|
|
|
|
|
|
.ok()
|
|
|
|
|
|
.and_then(|s| s.parse().ok())
|
|
|
|
|
|
.unwrap_or(2000)
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn ny_compiler_emit_only() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_NY_COMPILER_EMIT_ONLY").unwrap_or_else(|_| "1".to_string()) == "1"
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn ny_compiler_skip_py() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_NY_COMPILER_SKIP_PY").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn use_ny_compiler_exe() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_USE_NY_COMPILER_EXE").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn ny_compiler_exe_path() -> Option<String> {
|
|
|
|
|
|
std::env::var("NYASH_NY_COMPILER_EXE_PATH").ok()
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn ny_compiler_min_json() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_NY_COMPILER_MIN_JSON").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn selfhost_read_tmp() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_SELFHOST_READ_TMP").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn ny_compiler_stage3() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_NY_COMPILER_STAGE3").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
2025-09-19 02:07:38 +09:00
|
|
|
|
/// Core (Rust) parser Stage-3 gate
|
|
|
|
|
|
/// When enabled, the Rust parser accepts Stage-3 surface (try/catch/finally, throw).
|
|
|
|
|
|
/// Default is OFF to keep Stage-2 stable.
|
|
|
|
|
|
pub fn parser_stage3() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_PARSER_STAGE3").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Parser gate for Block‑Postfix Catch acceptance
|
|
|
|
|
|
/// Enabled when either NYASH_BLOCK_CATCH=1 or Stage‑3 gate is on.
|
|
|
|
|
|
/// Phase 15.5 allows parsing a standalone `{ ... }` block optionally followed by
|
|
|
|
|
|
/// a single `catch (...) { ... }` and/or `finally { ... }`, which is folded into
|
|
|
|
|
|
/// ASTNode::TryCatch with the preceding block as the try body.
|
|
|
|
|
|
pub fn block_postfix_catch() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_BLOCK_CATCH").ok().as_deref() == Some("1") || parser_stage3()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Bridge lowering: use Result-style try/throw lowering instead of MIR Catch/Throw
|
|
|
|
|
|
/// When on, try/catch is lowered using structured blocks and direct jumps,
|
|
|
|
|
|
/// without emitting MIR Throw/Catch. The thrown value is routed to catch via
|
|
|
|
|
|
/// block parameters (PHI-off uses edge-copy).
|
|
|
|
|
|
pub fn try_result_mode() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_TRY_RESULT_MODE").ok().as_deref() == Some("1")
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Parser gate for method-level postfix catch/finally acceptance on method definitions.
|
|
|
|
|
|
/// Enabled when either NYASH_METHOD_CATCH=1 or Stage‑3 gate is on.
|
|
|
|
|
|
pub fn method_catch() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_METHOD_CATCH").ok().as_deref() == Some("1") || parser_stage3()
|
|
|
|
|
|
}
|
2025-09-21 08:53:00 +09:00
|
|
|
|
|
|
|
|
|
|
/// Entry policy: allow top-level `main` resolution in addition to `Main.main`.
|
|
|
|
|
|
/// Default: false (prefer explicit `static box Main { main(...) }`).
|
|
|
|
|
|
pub fn entry_allow_toplevel_main() -> bool {
|
|
|
|
|
|
match std::env::var("NYASH_ENTRY_ALLOW_TOPLEVEL_MAIN").ok() {
|
|
|
|
|
|
Some(v) => {
|
|
|
|
|
|
let v = v.to_ascii_lowercase();
|
|
|
|
|
|
v == "1" || v == "true" || v == "on"
|
|
|
|
|
|
}
|
|
|
|
|
|
None => false,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Parser gate for expression-level postfix catch/cleanup acceptance.
|
|
|
|
|
|
/// Enabled when Stage-3 gate is on (NYASH_PARSER_STAGE3=1). Separate gate can
|
|
|
|
|
|
/// be introduced in future if needed, but we keep minimal toggles now.
|
|
|
|
|
|
pub fn expr_postfix_catch() -> bool {
|
|
|
|
|
|
parser_stage3()
|
|
|
|
|
|
}
|
2025-09-19 08:34:29 +09:00
|
|
|
|
/// Parser gate for Unified Members (stored/computed/once/birth_once).
|
|
|
|
|
|
/// Default: ON during Phase-15 (set NYASH_ENABLE_UNIFIED_MEMBERS=0|false|off to disable).
|
|
|
|
|
|
pub fn unified_members() -> bool {
|
|
|
|
|
|
match std::env::var("NYASH_ENABLE_UNIFIED_MEMBERS").ok() {
|
|
|
|
|
|
Some(v) => {
|
|
|
|
|
|
let lv = v.to_ascii_lowercase();
|
|
|
|
|
|
!(lv == "0" || lv == "false" || lv == "off")
|
|
|
|
|
|
}
|
|
|
|
|
|
None => true,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
pub fn ny_compiler_child_args() -> Option<String> {
|
|
|
|
|
|
std::env::var("NYASH_NY_COMPILER_CHILD_ARGS").ok()
|
|
|
|
|
|
}
|
|
|
|
|
|
pub fn ny_compiler_use_tmp_only() -> bool {
|
|
|
|
|
|
std::env::var("NYASH_NY_COMPILER_USE_TMP_ONLY")
|
|
|
|
|
|
.ok()
|
|
|
|
|
|
.as_deref()
|
|
|
|
|
|
== Some("1")
|
|
|
|
|
|
}
|