refactor(config): Modularize env.rs into 7 semantic flag Boxes
Refactored monolithic env.rs (948 lines, 106 flat functions) into 7 focused Box modules following Box-First principles. Zero breaking changes via backward-compatible re-exports. **Module organization** (7 semantic Boxes): - joinir_flags.rs (172 lines, 15 functions) - JoinIR core/experiment flags - mir_flags.rs (227 lines, 35 functions) - MIR core/PHI/optimizer flags - vm_backend_flags.rs (135 lines, 15 functions) - VM/Backend/LLVM flags - parser_flags.rs (136 lines, 10 functions) - Parser stage/postfix flags - using_flags.rs (70 lines, 7 functions) - Using/namespace system flags - verification_flags.rs (61 lines, 7 functions) - Verification/SSA flags - selfhost_flags.rs (98 lines, 12 functions) - Selfhost NY compiler flags **Improvements**: - IDE discoverability: `joinir_flags::`, `mir_flags::` in autocomplete - Single Responsibility: Each Box handles one semantic area - Maintainability: ~100-200 line modules instead of 948 line monolith - Scalability: Easy to add new flags to appropriate modules - Backward compatibility: All functions re-exported at `crate::config::env::` **Verification**: - 937/937 tests PASS (zero regressions) - cargo build --release succeeds - No code changes required in existing callsites (backward compatible) Box-First architecture: - 箱に切り出す: 106 functions → 7 semantic modules - 境界をはっきりさせる: Each module has clear responsibility - 差し替え可能: Backward-compatible re-exports - いつでも戻せる: Original backup created, reverts are safe 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@ -2,6 +2,19 @@
|
|||||||
//!
|
//!
|
||||||
//! Consolidates NYASH_* environment variables across subsystems and
|
//! Consolidates NYASH_* environment variables across subsystems and
|
||||||
//! optionally applies overrides from `nyash.toml`.
|
//! optionally applies overrides from `nyash.toml`.
|
||||||
|
//!
|
||||||
|
//! # Modular Organization
|
||||||
|
//!
|
||||||
|
//! Environment flags are now organized into focused Box modules:
|
||||||
|
//! - `joinir_flags` - JoinIR-related flags (30+ functions)
|
||||||
|
//! - `mir_flags` - MIR-related flags (20+ functions)
|
||||||
|
//! - `vm_backend_flags` - VM/Backend flags (15+ functions)
|
||||||
|
//! - `parser_flags` - Parser flags (10+ functions)
|
||||||
|
//! - `using_flags` - Using/namespace flags (10+ functions)
|
||||||
|
//! - `verification_flags` - Verification flags (8+ functions)
|
||||||
|
//! - `selfhost_flags` - Selfhost compiler flags (10+ functions)
|
||||||
|
//!
|
||||||
|
//! All functions are re-exported at the top level for backward compatibility.
|
||||||
|
|
||||||
mod catalog;
|
mod catalog;
|
||||||
pub mod dump;
|
pub mod dump;
|
||||||
@ -10,12 +23,31 @@ pub mod dump;
|
|||||||
pub mod joinir_dev;
|
pub mod joinir_dev;
|
||||||
pub mod stage1;
|
pub mod stage1;
|
||||||
|
|
||||||
|
// New modular organization
|
||||||
|
mod joinir_flags;
|
||||||
|
mod mir_flags;
|
||||||
|
mod vm_backend_flags;
|
||||||
|
mod parser_flags;
|
||||||
|
mod using_flags;
|
||||||
|
mod verification_flags;
|
||||||
|
mod selfhost_flags;
|
||||||
|
|
||||||
pub use catalog::{env_vars, AppliesTo, EnvVarMeta};
|
pub use catalog::{env_vars, AppliesTo, EnvVarMeta};
|
||||||
pub use dump::*;
|
pub use dump::*;
|
||||||
// Phase 124: hako_check exports removed (JoinIR-only consolidation)
|
// Phase 124: hako_check exports removed (JoinIR-only consolidation)
|
||||||
// pub use hako_check::*;
|
// pub use hako_check::*;
|
||||||
pub use joinir_dev::*;
|
pub use joinir_dev::*;
|
||||||
pub use stage1::*;
|
pub use stage1::*;
|
||||||
|
|
||||||
|
// Backward-compatible re-exports (NO BREAKING CHANGES!)
|
||||||
|
pub use joinir_flags::*;
|
||||||
|
pub use mir_flags::*;
|
||||||
|
pub use vm_backend_flags::*;
|
||||||
|
pub use parser_flags::*;
|
||||||
|
pub use using_flags::*;
|
||||||
|
pub use verification_flags::*;
|
||||||
|
pub use selfhost_flags::*;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
@ -47,12 +79,10 @@ impl NyashEnv {
|
|||||||
// Global current env config (thread-safe)
|
// Global current env config (thread-safe)
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::sync::{Mutex, Once, RwLock};
|
use std::sync::Mutex;
|
||||||
|
|
||||||
static GLOBAL_ENV: OnceCell<RwLock<NyashEnv>> = OnceCell::new();
|
static GLOBAL_ENV: OnceCell<std::sync::RwLock<NyashEnv>> = OnceCell::new();
|
||||||
static WARNED_ALIASES: OnceCell<Mutex<HashSet<String>>> = OnceCell::new();
|
static WARNED_ALIASES: OnceCell<Mutex<HashSet<String>>> = OnceCell::new();
|
||||||
static WARNED_JOINIR_CORE_OFF: Once = Once::new();
|
|
||||||
// フェーズM.2: PHI_ON_GATED_WARNED削除(phi-legacy簡略化により不要)
|
|
||||||
|
|
||||||
pub fn current() -> NyashEnv {
|
pub fn current() -> NyashEnv {
|
||||||
if let Some(lock) = GLOBAL_ENV.get() {
|
if let Some(lock) = GLOBAL_ENV.get() {
|
||||||
@ -70,7 +100,7 @@ pub fn set_current(cfg: NyashEnv) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let _ = GLOBAL_ENV.set(RwLock::new(cfg));
|
let _ = GLOBAL_ENV.set(std::sync::RwLock::new(cfg));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load overrides from nyash.toml `[env]` table and apply them to process env.
|
/// Load overrides from nyash.toml `[env]` table and apply them to process env.
|
||||||
@ -122,56 +152,6 @@ pub fn bootstrap_from_toml_env() {
|
|||||||
set_current(cur);
|
set_current(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get await maximum milliseconds, centralized here for consistency.
|
|
||||||
pub fn await_max_ms() -> u64 {
|
|
||||||
std::env::var("NYASH_AWAIT_MAX_MS")
|
|
||||||
.ok()
|
|
||||||
.and_then(|s| s.parse().ok())
|
|
||||||
.unwrap_or(5000)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- MIR PHI / PHI-less (edge-copy) mode ----
|
|
||||||
/// Enable MIR PHI non-generation for Bridge compatibility mode only.
|
|
||||||
/// フェーズM.2: MirBuilder/LoopBuilderでPHI統一済み、Bridge層の互換性制御のみ
|
|
||||||
/// Default: PHI-ON (Phase 15 direction), override with NYASH_MIR_NO_PHI=1
|
|
||||||
pub fn mir_no_phi() -> bool {
|
|
||||||
env_bool("NYASH_MIR_NO_PHI")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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 {
|
|
||||||
env_bool("NYASH_VERIFY_EDGE_COPY_STRICT")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Enforce purity of return blocks: no side-effecting instructions allowed before Return
|
|
||||||
/// Default: OFF. Enable with NYASH_VERIFY_RET_PURITY=1 in dev/profiling sessions.
|
|
||||||
pub fn verify_ret_purity() -> bool {
|
|
||||||
env_bool("NYASH_VERIFY_RET_PURITY")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Stage-B/selfhost 専用の dev verify トグル(SSA などの厳格チェックを一時緩和するためのスイッチ)
|
|
||||||
/// Default: ON(現行挙動)。NYASH_STAGEB_DEV_VERIFY=0 で Stage-B 経路の dev verify をスキップ。
|
|
||||||
pub fn stageb_dev_verify_enabled() -> bool {
|
|
||||||
env_flag("NYASH_STAGEB_DEV_VERIFY").unwrap_or(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- LLVM harness toggle (llvmlite) ----
|
|
||||||
pub fn llvm_use_harness() -> bool {
|
|
||||||
// Phase 15: デフォルトON(LLVMバックエンドはPythonハーネス使用)
|
|
||||||
// NYASH_LLVM_USE_HARNESS=0 で明示的に無効化可能
|
|
||||||
match std::env::var("NYASH_LLVM_USE_HARNESS").ok().as_deref() {
|
|
||||||
Some("0") | Some("false") | Some("off") => false,
|
|
||||||
_ => true, // デフォルト: ON(ハーネス使用)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generic boolean env parser: accepts 1/true/on (case-insensitive) as true.
|
/// Generic boolean env parser: accepts 1/true/on (case-insensitive) as true.
|
||||||
pub fn env_bool(key: &str) -> bool {
|
pub fn env_bool(key: &str) -> bool {
|
||||||
match std::env::var(key).ok() {
|
match std::env::var(key).ok() {
|
||||||
@ -194,698 +174,13 @@ pub fn env_bool_default(key: &str, default: bool) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn nyash_features_list() -> Option<Vec<String>> {
|
pub(crate) fn env_flag(var: &str) -> Option<bool> {
|
||||||
let raw = std::env::var("NYASH_FEATURES").ok()?;
|
|
||||||
let list: Vec<String> = raw
|
|
||||||
.split(',')
|
|
||||||
.filter_map(|s| {
|
|
||||||
let trimmed = s.trim();
|
|
||||||
if trimmed.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(trimmed.to_ascii_lowercase())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
if list.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(list)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn feature_stage3_enabled() -> bool {
|
|
||||||
if let Some(list) = nyash_features_list() {
|
|
||||||
for item in list {
|
|
||||||
let normalized = item.replace(['-', '_'], "");
|
|
||||||
if normalized == "stage3" || normalized == "parserstage3" {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Global fail-fast policy for runtime fallbacks.
|
|
||||||
/// Default: ON (true) to prohibit silent/different-route fallbacks in Rust layer.
|
|
||||||
/// Set NYASH_FAIL_FAST=0 to temporarily allow legacy fallbacks during bring-up.
|
|
||||||
pub fn fail_fast() -> bool {
|
|
||||||
env_bool_default("NYASH_FAIL_FAST", true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Phase 29/30 JoinIR toggles ----
|
|
||||||
/// JoinIR experiment mode. Required for JoinIR-related experimental paths.
|
|
||||||
/// Set NYASH_JOINIR_EXPERIMENT=1 to enable.
|
|
||||||
pub fn joinir_experiment_enabled() -> bool {
|
|
||||||
env_bool("NYASH_JOINIR_EXPERIMENT")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// JoinIR core policy: **always ON** after LoopBuilder removal.
|
|
||||||
/// - `NYASH_JOINIR_CORE` is deprecated(0 を指定しても警告して無視する)
|
|
||||||
/// - JoinIR を OFF にするモードは提供しない(Fail-Fast 原則、フォールバックなし)
|
|
||||||
pub fn joinir_core_enabled() -> bool {
|
|
||||||
if let Some(v) = env_flag("NYASH_JOINIR_CORE") {
|
|
||||||
if !v {
|
|
||||||
warn_joinir_core_off_ignored();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
fn warn_joinir_core_off_ignored() {
|
|
||||||
WARNED_JOINIR_CORE_OFF.call_once(|| {
|
|
||||||
eprintln!(
|
|
||||||
"[deprecate/env] NYASH_JOINIR_CORE=0 is ignored; JoinIR core is always on (LoopBuilder is removed)"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// JoinIR VM bridge mode. When enabled with NYASH_JOINIR_EXPERIMENT=1,
|
|
||||||
/// specific functions can be executed via JoinIR → VM bridge instead of direct MIR → VM.
|
|
||||||
/// Set NYASH_JOINIR_VM_BRIDGE=1 to enable.
|
|
||||||
pub fn joinir_vm_bridge_enabled() -> bool {
|
|
||||||
joinir_core_enabled() && env_bool("NYASH_JOINIR_VM_BRIDGE")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// JoinIR strict mode: when enabled, JoinIR 対象のフォールバックを禁止する。
|
|
||||||
/// 既定OFF。NYASH_JOINIR_STRICT=1 のときのみ有効。
|
|
||||||
pub fn joinir_strict_enabled() -> bool {
|
|
||||||
env_flag("NYASH_JOINIR_STRICT").unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// JoinIR VM bridge debug output. Enables verbose logging of JoinIR→MIR conversion.
|
|
||||||
/// Set NYASH_JOINIR_VM_BRIDGE_DEBUG=1 to enable.
|
|
||||||
pub fn joinir_vm_bridge_debug() -> bool {
|
|
||||||
env_bool("NYASH_JOINIR_VM_BRIDGE_DEBUG")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// JoinIR LLVM experiment mode. When enabled with NYASH_JOINIR_EXPERIMENT=1,
|
|
||||||
/// enables experimental JoinIR→MIR'→LLVM path for specific functions (e.g., Main.skip/1).
|
|
||||||
/// This is a dev-only toggle for testing PHI normalization via JoinIR in the LLVM path.
|
|
||||||
/// Set NYASH_JOINIR_LLVM_EXPERIMENT=1 to enable.
|
|
||||||
pub fn joinir_llvm_experiment_enabled() -> bool {
|
|
||||||
joinir_core_enabled() && env_bool("NYASH_JOINIR_LLVM_EXPERIMENT")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Phase 33: JoinIR If Select 実験の有効化
|
|
||||||
/// Primary: HAKO_JOINIR_IF_SELECT (Phase 33-8+).
|
|
||||||
pub fn joinir_if_select_enabled() -> bool {
|
|
||||||
// Core ON なら既定で有効化(JoinIR 本線化を優先)
|
|
||||||
if joinir_core_enabled() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// Primary: HAKO_JOINIR_IF_SELECT
|
|
||||||
if let Some(v) = env_flag("HAKO_JOINIR_IF_SELECT") {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Phase 33-8: JoinIR Stage-1 rollout toggle
|
|
||||||
/// Set HAKO_JOINIR_STAGE1=1 to enable JoinIR lowering for Stage-1 functions.
|
|
||||||
pub fn joinir_stage1_enabled() -> bool {
|
|
||||||
// Primary: HAKO_JOINIR_STAGE1
|
|
||||||
if let Some(v) = env_flag("HAKO_JOINIR_STAGE1") {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Phase 33-8: JoinIR debug log level (0-3)
|
|
||||||
/// - 0: No logs (default)
|
|
||||||
/// - 1: Basic logs (which functions were lowered)
|
|
||||||
/// - 2: Pattern matching details (CFG analysis)
|
|
||||||
/// - 3: Full dump (all variables, all instructions)
|
|
||||||
pub fn joinir_debug_level() -> u8 {
|
|
||||||
// Primary: HAKO_JOINIR_DEBUG
|
|
||||||
if let Ok(v) = std::env::var("HAKO_JOINIR_DEBUG") {
|
|
||||||
return v.parse().unwrap_or(0);
|
|
||||||
}
|
|
||||||
// Fallback: NYASH_JOINIR_DEBUG (deprecated)
|
|
||||||
if let Ok(v) = std::env::var("NYASH_JOINIR_DEBUG") {
|
|
||||||
warn_alias_once("NYASH_JOINIR_DEBUG", "HAKO_JOINIR_DEBUG");
|
|
||||||
return v.parse().unwrap_or(0);
|
|
||||||
}
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Dev-only convenience switch to bundle experimental JoinIR knobs.
|
|
||||||
/// - NYASH_JOINIR_DEV=1 enables
|
|
||||||
/// - Otherwise inherits from joinir_debug_level()>0 (opt-in debug)
|
|
||||||
pub fn joinir_dev_enabled() -> bool {
|
|
||||||
env_bool("NYASH_JOINIR_DEV") || joinir_debug_level() > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Phase 61-2: If-in-loop JoinIR dry-run有効化
|
|
||||||
///
|
|
||||||
/// `HAKO_JOINIR_IF_IN_LOOP_DRYRUN=1` でdry-runモードを有効化
|
|
||||||
///
|
|
||||||
/// dry-runモード:
|
|
||||||
/// - JoinIR経路でPHI仕様を計算
|
|
||||||
/// - PhiBuilderBox経路と比較
|
|
||||||
/// - 実際のPHI生成はPhiBuilderBoxを使用(安全)
|
|
||||||
pub fn joinir_if_in_loop_dryrun_enabled() -> bool {
|
|
||||||
env_bool("HAKO_JOINIR_IF_IN_LOOP_DRYRUN")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Phase 61-3: If-in-loop JoinIR本番経路有効化
|
|
||||||
///
|
|
||||||
/// `HAKO_JOINIR_IF_IN_LOOP_ENABLE=1` でJoinIR本番経路を有効化
|
|
||||||
///
|
|
||||||
/// 動作:
|
|
||||||
/// - ON: JoinIR + IfInLoopPhiEmitter経路(PhiBuilderBox不使用)
|
|
||||||
/// - OFF: PhiBuilderBox経路(既存フォールバック)
|
|
||||||
///
|
|
||||||
/// 前提条件:
|
|
||||||
/// - JoinIR IfSelect 基盤(Phase 33)の有効化
|
|
||||||
/// - dry-runモードとは独立(HAKO_JOINIR_IF_IN_LOOP_DRYRUN)
|
|
||||||
///
|
|
||||||
/// デフォルト: OFF(安全第一)
|
|
||||||
pub fn joinir_if_in_loop_enable() -> bool {
|
|
||||||
env_bool("HAKO_JOINIR_IF_IN_LOOP_ENABLE")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Phase 61-4: ループ外If JoinIR経路有効化
|
|
||||||
///
|
|
||||||
/// `HAKO_JOINIR_IF_TOPLEVEL=1` でループ外IfのJoinIR経路を有効化
|
|
||||||
///
|
|
||||||
/// 動作:
|
|
||||||
/// - ON: try_lower_if_to_joinir経路(if_form.rsで使用)
|
|
||||||
/// - OFF: PhiBuilderBox経路(既存)
|
|
||||||
///
|
|
||||||
/// 前提条件:
|
|
||||||
/// - HAKO_JOINIR_IF_SELECT=1(Phase 33基盤)
|
|
||||||
///
|
|
||||||
/// デフォルト: OFF(安全第一)
|
|
||||||
pub fn joinir_if_toplevel_enabled() -> bool {
|
|
||||||
env_bool("HAKO_JOINIR_IF_TOPLEVEL")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Phase 61-4: ループ外If JoinIR dry-run有効化
|
|
||||||
///
|
|
||||||
/// `HAKO_JOINIR_IF_TOPLEVEL_DRYRUN=1` でdry-runモードを有効化
|
|
||||||
///
|
|
||||||
/// dry-runモード:
|
|
||||||
/// - JoinIR経路を試行しログ出力
|
|
||||||
/// - 実際のPHI生成は既存経路を使用(安全)
|
|
||||||
pub fn joinir_if_toplevel_dryrun_enabled() -> bool {
|
|
||||||
env_bool("HAKO_JOINIR_IF_TOPLEVEL_DRYRUN")
|
|
||||||
}
|
|
||||||
|
|
||||||
// VM legacy by-name call fallback was removed (Phase 2 complete).
|
|
||||||
// Phase 40-4.1: use_joinir_for_array_filter() removed (Route B now default).
|
|
||||||
|
|
||||||
// ---- Phase 11.8 MIR cleanup toggles ----
|
|
||||||
/// Core-13 minimal MIR mode toggle. Default ON unless 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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Core-13 "pure" mode: only the 13 canonical ops are allowed (verifier rejects others).
|
|
||||||
pub fn mir_core13_pure() -> bool {
|
|
||||||
env_bool("NYASH_MIR_CORE13_PURE")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Optimizer diagnostics ----
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Legacy compatibility (dev-only) ----
|
|
||||||
/// Enable legacy InstanceBox fields (SharedNyashBox map) for compatibility.
|
|
||||||
/// Default: OFF. Set NYASH_LEGACY_FIELDS_ENABLE=1 to materialize and use legacy fields.
|
|
||||||
pub fn legacy_fields_enable() -> bool {
|
|
||||||
env_bool("NYASH_LEGACY_FIELDS_ENABLE")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- GC/Runtime tracing (execution-affecting visibility) ----
|
|
||||||
pub fn gc_trace() -> bool {
|
|
||||||
env_bool("NYASH_GC_TRACE")
|
|
||||||
}
|
|
||||||
pub fn gc_barrier_trace() -> bool {
|
|
||||||
env_bool("NYASH_GC_BARRIER_TRACE")
|
|
||||||
}
|
|
||||||
pub fn runtime_checkpoint_trace() -> bool {
|
|
||||||
env_bool("NYASH_RUNTIME_CHECKPOINT_TRACE")
|
|
||||||
}
|
|
||||||
pub fn gc_barrier_strict() -> bool {
|
|
||||||
std::env::var("NYASH_GC_BARRIER_STRICT").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- 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")
|
|
||||||
}
|
|
||||||
/// 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()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- 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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Rewriter flags (optimizer transforms)
|
|
||||||
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")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Phase 12: Nyash ABI (vtable) toggles ----
|
|
||||||
pub fn abi_vtable() -> bool {
|
|
||||||
std::env::var("NYASH_ABI_VTABLE").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
/// ABI strict diagnostics: missing vtable methods become errors when enabled.
|
|
||||||
pub fn abi_strict() -> bool {
|
|
||||||
std::env::var("NYASH_ABI_STRICT").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Operator Boxes adopt defaults ----
|
|
||||||
/// CompareOperator.apply adopt: default ON (prod/devともに採用)
|
|
||||||
pub fn operator_box_compare_adopt() -> bool {
|
|
||||||
match std::env::var("NYASH_OPERATOR_BOX_COMPARE_ADOPT")
|
|
||||||
.ok()
|
|
||||||
.as_deref()
|
|
||||||
.map(|v| v.to_ascii_lowercase())
|
|
||||||
{
|
|
||||||
Some(ref s) if s == "0" || s == "false" || s == "off" => false,
|
|
||||||
Some(ref s) if s == "1" || s == "true" || s == "on" => true,
|
|
||||||
_ => true, // default ON
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// AddOperator.apply adopt: default OFF(順次昇格のため)
|
|
||||||
pub fn operator_box_add_adopt() -> bool {
|
|
||||||
match std::env::var("NYASH_OPERATOR_BOX_ADD_ADOPT")
|
|
||||||
.ok()
|
|
||||||
.as_deref()
|
|
||||||
.map(|v| v.to_ascii_lowercase())
|
|
||||||
{
|
|
||||||
Some(ref s) if s == "0" || s == "false" || s == "off" => false,
|
|
||||||
_ => true, // default ON (promoted after validation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Null/Missing Boxes (dev-only observe → adopt) ----
|
|
||||||
/// Enable NullBox/MissingBox observation path (no behavior change by default).
|
|
||||||
/// Default: OFF. Turn ON with `NYASH_NULL_MISSING_BOX=1`. May be auto-enabled in --dev later.
|
|
||||||
pub fn null_missing_box_enabled() -> bool {
|
|
||||||
std::env::var("NYASH_NULL_MISSING_BOX").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
/// Strict null policy for operators (when enabled): null in arithmetic/compare is an error.
|
|
||||||
/// Default: OFF (null propagates). Effective only when `null_missing_box_enabled()` is true.
|
|
||||||
pub fn null_strict() -> bool {
|
|
||||||
std::env::var("NYASH_NULL_STRICT").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Phase 12: thresholds and routing policies ----
|
|
||||||
// ---- Runner/CLI common toggles (hot-path centralization)
|
|
||||||
pub fn cli_verbose() -> bool {
|
|
||||||
cli_verbose_level() > 0
|
|
||||||
}
|
|
||||||
pub fn enable_using() -> bool {
|
|
||||||
// Phase 15: デフォルトON(using systemはメイン機能)
|
|
||||||
// NYASH_ENABLE_USING=0 で明示的に無効化可能。HAKO_ENABLE_USING は互換のため受理(警告)。
|
|
||||||
match std::env::var("NYASH_ENABLE_USING").ok().as_deref() {
|
|
||||||
Some("0") | Some("false") | Some("off") => return false,
|
|
||||||
Some(_) => return true,
|
|
||||||
None => {}
|
|
||||||
}
|
|
||||||
// Fallback to alias
|
|
||||||
if let Some(v) = std::env::var("HAKO_ENABLE_USING").ok() {
|
|
||||||
warn_alias_once("HAKO_ENABLE_USING", "NYASH_ENABLE_USING");
|
|
||||||
let lv = v.to_ascii_lowercase();
|
|
||||||
return !(lv == "0" || lv == "false" || lv == "off");
|
|
||||||
}
|
|
||||||
true // default ON
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- Using profiles (dev|ci|prod) ----
|
|
||||||
/// Return using profile string; default is "dev".
|
|
||||||
pub fn using_profile() -> String {
|
|
||||||
std::env::var("NYASH_USING_PROFILE").unwrap_or_else(|_| "dev".to_string())
|
|
||||||
}
|
|
||||||
/// True when using profile is prod (disables some dev-only behaviors).
|
|
||||||
pub fn using_is_prod() -> bool {
|
|
||||||
using_profile().eq_ignore_ascii_case("prod")
|
|
||||||
}
|
|
||||||
/// True when using profile is ci.
|
|
||||||
pub fn using_is_ci() -> bool {
|
|
||||||
using_profile().eq_ignore_ascii_case("ci")
|
|
||||||
}
|
|
||||||
/// True when using profile is dev (default).
|
|
||||||
pub fn using_is_dev() -> bool {
|
|
||||||
using_profile().eq_ignore_ascii_case("dev")
|
|
||||||
}
|
|
||||||
/// Allow `using "path"` statements in source (dev-only by default).
|
|
||||||
pub fn allow_using_file() -> bool {
|
|
||||||
// SSOT 徹底: 全プロファイルで既定禁止(nyash.toml を唯一の真実に)
|
|
||||||
// 明示オーバーライドでのみ許可(開発用緊急時)
|
|
||||||
match std::env::var("NYASH_ALLOW_USING_FILE").ok().as_deref() {
|
|
||||||
Some("1") | Some("true") | Some("on") => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Determine whether AST prelude merge for `using` is enabled.
|
|
||||||
/// Precedence:
|
|
||||||
/// 1) Explicit env `NYASH_USING_AST` = 1/true/on → enabled, = 0/false/off → disabled
|
|
||||||
/// 2) Default by profile: dev/ci → ON, prod → OFF
|
|
||||||
pub fn using_ast_enabled() -> bool {
|
|
||||||
match std::env::var("NYASH_USING_AST")
|
|
||||||
.ok()
|
|
||||||
.as_deref()
|
|
||||||
.map(|v| v.to_ascii_lowercase())
|
|
||||||
{
|
|
||||||
Some(ref s) if s == "1" || s == "true" || s == "on" => true,
|
|
||||||
Some(ref s) if s == "0" || s == "false" || s == "off" => false,
|
|
||||||
_ => !using_is_prod(), // dev/ci → true, prod → false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Policy: allow VM to fallback-dispatch user Instance BoxCall (dev only by default).
|
|
||||||
/// - prod: default false (disallow)
|
|
||||||
/// - dev/ci: default true (allow, with WARN)
|
|
||||||
/// Override with NYASH_VM_USER_INSTANCE_BOXCALL={0|1}
|
|
||||||
pub fn vm_allow_user_instance_boxcall() -> bool {
|
|
||||||
match std::env::var("NYASH_VM_USER_INSTANCE_BOXCALL")
|
|
||||||
.ok()
|
|
||||||
.as_deref()
|
|
||||||
.map(|v| v.to_ascii_lowercase())
|
|
||||||
{
|
|
||||||
Some(ref s) if s == "0" || s == "false" || s == "off" => false,
|
|
||||||
Some(ref s) if s == "1" || s == "true" || s == "on" => true,
|
|
||||||
_ => !using_is_prod(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Legacy resolve_fix_braces() removed (Phase 15 cleanup)
|
|
||||||
// AST-based integration handles syntax properly without text-level brace fixing
|
|
||||||
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")
|
|
||||||
}
|
|
||||||
/// (Deprecated) use dispatch-based VM route; currently disabled.
|
|
||||||
pub fn vm_use_dispatch() -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
/// Force VM fallback interpreter route (dev-only escape hatch).
|
|
||||||
pub fn vm_use_fallback() -> bool {
|
|
||||||
std::env::var("NYASH_VM_USE_FALLBACK").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
/// Trace VM route selection decisions.
|
|
||||||
pub fn vm_route_trace() -> bool {
|
|
||||||
std::env::var("NYASH_VM_ROUTE_TRACE").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Self-host compiler knobs
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
/// Emit-only flag for selfhost compiler (default ON to avoid execution).
|
|
||||||
pub fn ny_compiler_emit_only() -> bool {
|
|
||||||
std::env::var("NYASH_NY_COMPILER_EMIT_ONLY").unwrap_or_else(|_| "1".to_string()) == "1"
|
|
||||||
}
|
|
||||||
/// Path to external selfhost compiler executable (when enabled).
|
|
||||||
pub fn use_ny_compiler_exe() -> bool {
|
|
||||||
std::env::var("NYASH_USE_NY_COMPILER_EXE").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
/// Path to external selfhost compiler executable (when enabled).
|
|
||||||
pub fn ny_compiler_exe_path() -> Option<String> {
|
|
||||||
std::env::var("NYASH_NY_COMPILER_EXE_PATH").ok()
|
|
||||||
}
|
|
||||||
/// Pass `-- --min-json` to child selfhost compiler (minimal JSON output).
|
|
||||||
pub fn ny_compiler_min_json() -> bool {
|
|
||||||
std::env::var("NYASH_NY_COMPILER_MIN_JSON").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
/// When true, child reads tmp/ny_parser_input.ny instead of stdin/source text.
|
|
||||||
pub fn selfhost_read_tmp() -> bool {
|
|
||||||
std::env::var("NYASH_SELFHOST_READ_TMP").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
/// Pass `-- --stage3` to child selfhost compiler to allow Stage-3 surface.
|
|
||||||
pub fn ny_compiler_stage3() -> bool {
|
|
||||||
std::env::var("NYASH_NY_COMPILER_STAGE3").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
/// Core (Rust) parser Stage-3 gate (default ON).
|
|
||||||
/// Precedence:
|
|
||||||
/// 1) NYASH_FEATURES contains `stage3`/`parser-stage3`
|
|
||||||
/// 2) Legacy env aliases (NYASH_PARSER_STAGE3 / HAKO_PARSER_STAGE3)
|
|
||||||
/// 3) Default true (Stage-3 is standard syntax)
|
|
||||||
pub fn parser_stage3_enabled() -> bool {
|
|
||||||
if feature_stage3_enabled() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if let Some(v) = env_flag("NYASH_PARSER_STAGE3") {
|
|
||||||
warn_alias_once("NYASH_PARSER_STAGE3", "NYASH_FEATURES=stage3");
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
if let Some(v) = env_flag("HAKO_PARSER_STAGE3") {
|
|
||||||
warn_alias_once("HAKO_PARSER_STAGE3", "NYASH_FEATURES=stage3");
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
#[deprecated(note = "Use parser_stage3_enabled() instead")]
|
|
||||||
pub fn parser_stage3() -> bool {
|
|
||||||
parser_stage3_enabled()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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_enabled()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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_enabled()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Entry policy: allow top-level `main` resolution in addition to `Main.main`.
|
|
||||||
/// Default: true (prefer `Main.main` when both exist; otherwise accept `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 => true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parser gate for expression-level postfix catch/cleanup acceptance.
|
|
||||||
/// Enabled when Stage-3 gate is on (NYASH_FEATURES=stage3 or legacy aliases). Separate gate can
|
|
||||||
/// be introduced in future if needed, but we keep minimal toggles now.
|
|
||||||
pub fn expr_postfix_catch() -> bool {
|
|
||||||
parser_stage3_enabled()
|
|
||||||
}
|
|
||||||
/// 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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn ny_compiler_child_args() -> Option<String> {
|
|
||||||
// Pass-through args to selfhost child (space-separated).
|
|
||||||
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")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Use Python MVP harness for Ny compiler (NYASH_NY_COMPILER_USE_PY=1).
|
|
||||||
pub fn ny_compiler_use_py() -> bool {
|
|
||||||
std::env::var("NYASH_NY_COMPILER_USE_PY").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Macro pre-expand mode for selfhost (NYASH_MACRO_SELFHOST_PRE_EXPAND).
|
|
||||||
/// Returns "1", "auto", or None.
|
|
||||||
pub fn macro_selfhost_pre_expand() -> Option<String> {
|
|
||||||
std::env::var("NYASH_MACRO_SELFHOST_PRE_EXPAND").ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ScopeBox enable flag (NYASH_SCOPEBOX_ENABLE=1).
|
|
||||||
pub fn scopebox_enable() -> bool {
|
|
||||||
std::env::var("NYASH_SCOPEBOX_ENABLE").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// LoopForm normalize flag (NYASH_LOOPFORM_NORMALIZE=1).
|
|
||||||
pub fn loopform_normalize() -> bool {
|
|
||||||
std::env::var("NYASH_LOOPFORM_NORMALIZE").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Dev-only escape hatch: force inline selfhost path (NYASH_SELFHOST_INLINE_FORCE=1).
|
|
||||||
pub fn selfhost_inline_force() -> bool {
|
|
||||||
std::env::var("NYASH_SELFHOST_INLINE_FORCE").ok().as_deref() == Some("1")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unicode decode toggle for string literals (\uXXXX, optional surrogate pairs).
|
|
||||||
/// Enabled when either HAKO_PARSER_DECODE_UNICODE=1 or NYASH_PARSER_DECODE_UNICODE=1.
|
|
||||||
/// Default: OFF (for strict backward compatibility).
|
|
||||||
pub fn parser_decode_unicode() -> bool {
|
|
||||||
env_flag("HAKO_PARSER_DECODE_UNICODE")
|
|
||||||
.or_else(|| env_flag("NYASH_PARSER_DECODE_UNICODE"))
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
fn env_flag(var: &str) -> Option<bool> {
|
|
||||||
std::env::var(var).ok().map(|v| {
|
std::env::var(var).ok().map(|v| {
|
||||||
let lv = v.to_ascii_lowercase();
|
let lv = v.to_ascii_lowercase();
|
||||||
lv == "1" || lv == "true" || lv == "on"
|
lv == "1" || lv == "true" || lv == "on"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nyvm_core_wrapper() -> bool {
|
|
||||||
env_flag("HAKO_NYVM_CORE")
|
|
||||||
.or_else(|| env_flag("NYASH_NYVM_CORE"))
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn nyvm_bridge_inject_singleton() -> bool {
|
|
||||||
env_flag("HAKO_BRIDGE_INJECT_SINGLETON")
|
|
||||||
.or_else(|| env_flag("NYASH_BRIDGE_INJECT_SINGLETON"))
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn nyvm_bridge_early_phi_materialize() -> bool {
|
|
||||||
env_flag("HAKO_BRIDGE_EARLY_PHI_MATERIALIZE")
|
|
||||||
.or_else(|| env_flag("NYASH_BRIDGE_EARLY_PHI_MATERIALIZE"))
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn nyvm_v1_downconvert() -> bool {
|
|
||||||
env_flag("HAKO_NYVM_V1_DOWNCONVERT")
|
|
||||||
.or_else(|| env_flag("NYASH_NYVM_V1_DOWNCONVERT"))
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gate‑C(Core) strict OOB handling: when enabled, any observed OOB tag
|
|
||||||
/// (emitted by runtime during ArrayBox get/set with HAKO_OOB_STRICT=1) should
|
|
||||||
/// cause non‑zero exit at the end of JSON→VM execution.
|
|
||||||
pub fn oob_strict_fail() -> bool {
|
|
||||||
env_flag("HAKO_OOB_STRICT_FAIL")
|
|
||||||
.or_else(|| env_flag("NYASH_OOB_STRICT_FAIL"))
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Primary verification route: return true when Hakorune VM is requested as primary.
|
|
||||||
/// Accepts HAKO_VERIFY_PRIMARY=hakovm (preferred) or legacy HAKO_ROUTE_HAKOVM=1 (deprecated, warns).
|
|
||||||
pub fn verify_primary_is_hakovm() -> bool {
|
|
||||||
if std::env::var("HAKO_VERIFY_PRIMARY").ok().as_deref() == Some("hakovm") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if env_bool("HAKO_ROUTE_HAKOVM") {
|
|
||||||
warn_alias_once("HAKO_ROUTE_HAKOVM", "HAKO_VERIFY_PRIMARY=hakovm");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn warn_alias_once(alias: &str, primary: &str) {
|
pub(crate) fn warn_alias_once(alias: &str, primary: &str) {
|
||||||
let set = WARNED_ALIASES.get_or_init(|| Mutex::new(HashSet::new()));
|
let set = WARNED_ALIASES.get_or_init(|| Mutex::new(HashSet::new()));
|
||||||
if let Ok(mut s) = set.lock() {
|
if let Ok(mut s) = set.lock() {
|
||||||
@ -898,51 +193,3 @@ pub(crate) fn warn_alias_once(alias: &str, primary: &str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- ENV consolidation helpers (Phase 21.10/22.1) ----
|
|
||||||
/// LLVM opt level (primary: NYASH_LLVM_OPT_LEVEL; alias: HAKO_LLVM_OPT_LEVEL)
|
|
||||||
/// Returns string level (e.g., "0", "1", ...). Default: "0" when unset.
|
|
||||||
pub fn llvm_opt_level() -> String {
|
|
||||||
if let Some(v) = std::env::var("NYASH_LLVM_OPT_LEVEL").ok() {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
if let Some(v) = std::env::var("HAKO_LLVM_OPT_LEVEL").ok() {
|
|
||||||
warn_alias_once("HAKO_LLVM_OPT_LEVEL", "NYASH_LLVM_OPT_LEVEL");
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
"0".to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gate‑C(Core) route request (primary: NYASH_GATE_C_CORE; alias: HAKO_GATE_C_CORE)
|
|
||||||
pub fn gate_c_core() -> bool {
|
|
||||||
if env_bool("NYASH_GATE_C_CORE") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if env_bool("HAKO_GATE_C_CORE") {
|
|
||||||
warn_alias_once("HAKO_GATE_C_CORE", "NYASH_GATE_C_CORE");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Consolidated toggle for selfhost NY compiler pipeline.
|
|
||||||
/// Primary: NYASH_USE_NY_COMPILER=0|1(明示指定のみ有効)。Legacy disables accepted (with warning):
|
|
||||||
/// NYASH_DISABLE_NY_COMPILER/HAKO_DISABLE_NY_COMPILER (any true value disables).
|
|
||||||
pub fn use_ny_compiler() -> bool {
|
|
||||||
// Primary knob takes precedence when explicitly set
|
|
||||||
if let Some(v) = std::env::var("NYASH_USE_NY_COMPILER").ok() {
|
|
||||||
let lv = v.trim().to_ascii_lowercase();
|
|
||||||
return lv == "1" || lv == "true" || lv == "on";
|
|
||||||
}
|
|
||||||
// Legacy disable aliases — if any is true, treat as disabled and warn
|
|
||||||
if env_bool("NYASH_DISABLE_NY_COMPILER") {
|
|
||||||
warn_alias_once("NYASH_DISABLE_NY_COMPILER", "NYASH_USE_NY_COMPILER=0");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if env_bool("HAKO_DISABLE_NY_COMPILER") {
|
|
||||||
warn_alias_once("HAKO_DISABLE_NY_COMPILER", "NYASH_USE_NY_COMPILER=0");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Phase 25.1b: Default OFF(selfhost NY compiler は明示 opt-in のみ)
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user