Files
hakorune/docs/ENV_VARS.md
nyash-codex 8b44c5009f fix(mir): fix else block scope bug - PHI materialization order
Root Cause:
- Else blocks were not propagating variable assignments to outer scope
- Bug 1 (if_form.rs): PHI materialization happened before variable_map reset,
  causing PHI nodes to be lost
- Bug 2 (phi.rs): Variable merge didn't check if else branch modified variables

Changes:
- src/mir/builder/if_form.rs:93-127
  - Reordered: reset variable_map BEFORE materializing PHI nodes
  - Now matches then-branch pattern (reset → materialize → execute)
  - Applied to both "else" and "no else" branches for consistency
- src/mir/builder/phi.rs:137-154
  - Added else_modified_var check to detect variable modifications
  - Use modified value from else_var_map_end_opt when available
  - Fall back to pre-if value only when truly not modified

Test Results:
 Simple block: { x=42 } → 42
 If block: if 1 { x=42 } → 42
 Else block: if 0 { x=99 } else { x=42 } → 42 (FIXED!)
 Stage-B body extraction: "return 42" correctly extracted (was null)

Impact:
- Else block variable assignments now work correctly
- Stage-B compiler body extraction restored
- Selfhost builder path can now function
- Foundation for Phase 21.x progress

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-13 20:16:20 +09:00

8.3 KiB
Raw Blame History

ENV Variables Index (Core, Builder, Smokes)

Purpose: quick reference for toggles used frequently during development and in smokes. Defaults aim to be safe and failfast.

Runtime/VM

  • NYASH_FAIL_FAST=0

    • Global relaxation switch; when set to 0/false, paired legacy guards may allow otherwise failfast paths.
    • Use only for diagnosis; keep OFF in CI.
  • NYASH_LEGACY_FIELDS_ENABLE=1

    • Materialize legacy InstanceBox shared fields map for compatibility with older code paths.
    • Default: OFF. Dev/compat only; safe to keep disabled in CI and normal runs.
  • NYASH_JSON_ONLY=1

    • When tools/wrappers set this, StageB and related emitters print only JSON to stdout. Auxiliary logs should be routed to stderr.
    • Smokes expect singleline JSON on stdout for Program(JSON) and MIR(JSON) producers.
  • NYASH_ENABLE_USING=1, HAKO_ENABLE_USING=1

    • Enable using/alias resolution in dev/VM runs. Smokes set both for symmetry.

Extern/Providers

  • Arity suffix normalization
    • The VM accepts extern names with arity suffixes and normalizes them before dispatch:
      • Examples: env.get/1env.get, hostbridge.extern_invoke/3hostbridge.extern_invoke.
    • Implemented in src/backend/mir_interpreter/handlers/calls/externs.rs and handlers/externals.rs.

Plugins / Autoload

  • NYASH_USING_DYLIB_AUTOLOAD=1
    • Enable autoload of [using.<name>] entries with kind="dylib" from nyash.toml.
    • The runner loads the specified shared libraries at startup and registers providers for the boxes declared in each plugins nyash_box.toml.
    • Default: OFF. Guarded to avoid surprises; respects NYASH_DISABLE_PLUGINS=1.

Parser/StageB

  • HAKO_PARSER_STAGE3=1, NYASH_PARSER_STAGE3=1

    • Accept Stage3 syntax (Break/Continue/Try/Catch, etc.). Enabled in smokes for StageB runs.
  • HAKO_STAGEB_FUNC_SCAN=1

    • Devonly: inject a defs array into Program(JSON) with scanned method definitions for box Main.
  • HAKO_STAGEB_BODY_EXTRACT=0|1

    • Toggle StageB body extractor. When 0, skip methodbody extraction and pass the full --source to parse_program2. Useful to avoid environmentspecific drift in extractors; default is 1 (enabled).

Selfhost builders and wrappers

  • HAKO_SELFHOST_BUILDER_FIRST=1

    • Prefer the Hako MirBuilder path first; wrappers fall back to Rust CLI builder on failure to keep runs green.
  • NYASH_LLVM_USE_HARNESS=1

    • Enable LLVM harness mode (nyllvmc crate backend). Used by builder scripts for EXE/OBJ emission.

Smokes

  • SMOKES_DEFAULT_TIMEOUT
    • Pertest timeout (seconds) used by tools/smokes/v2/run.sh --timeout or auto profile defaults. Quick profile defaults to ~15s.
    • Some tests wrap heavy steps (e.g., running a built EXE) with a shorter internal timeout to convert hangs into SKIP.
  • HAKO_BUILD_TIMEOUT, HAKO_EXE_TIMEOUT
    • Internal timeouts (seconds) used by several phase2100 cratebackend tests to bound nyllvmc build/link and EXE execution steps under quick.
    • Defaults: HAKO_BUILD_TIMEOUT=10, HAKO_EXE_TIMEOUT=5.

Notes

  • Keep default behavior unchanged for users. Use these toggles in development and CI wrappers only.
  • Avoid enabling legacy paths except for targeted diagnosis. The unified call system is the default in both builder and VM.

Using/Resolver

  • HAKO_USING_RESOLVER_FIRST=1
    • Try the SSOT using resolver (using::resolver::resolve_using_target_common) first in the runner pipeline.
    • On failure, the pipeline falls back to the existing runner logic (aliases/builtins/plugins/relative search).
    • Default: OFF. Use to validate resolverfirst migration without changing defaults.

Builder/Emit (Selfhost)

  • HAKO_SELFHOST_BUILDER_FIRST=1

    • Prefer Hako MirBuilder path first; delegates to provider/legacy on failure. Used by tools/hakorune_emit_mir.sh and bench scripts.
  • HAKO_MIR_BUILDER_BOX=hako.mir.builder|min

    • Choose selfhost builder box (full or minimal runner).
  • HAKO_SELFHOST_TRACE=1

    • Print additional traces during MIR emit bench/wrappers.
  • HAKO_MIR_BUILDER_LOOP_FORCE_JSONFRAG=1devonly

    • 最小 MIR(JSON)const/phi/compare/branch/jump/ret のみ)を強制生成する緊急回避。
    • emit が壊れているときの診断用途に限定。ベンチ/本番経路では使用しない。
  • HAKO_MIR_BUILDER_JSONFRAG_NORMALIZE=1, HAKO_MIR_BUILDER_JSONFRAG_PURIFY=1devonly

    • JsonFrag の整形/純化ユーティリティ。比較/可視化の安定化が目的で、意味論や性能を変える“最適化”ではない。

Provider path (delegate)

  • HAKO_MIR_NORMALIZE_PROVIDER=1

    • ProviderRust出力の MIR(JSON) に対して、Hako の JsonFrag 正規化パスを適用するtools/hakorune_emit_mir.sh 内部)。
    • 互換維持のため既定はOFF。Box 系で ret ブロックに副作用命令が残るようなケースの暫定純化に利用できる。
  • NYASH_LLVM_FAST_INT=1

    • Opt-in toggle for integer hot paths in LLVM MIR/IR. When 1, binopcompare は同一ブロックの vmap 定義を最優先し、resolver/PHI を経由しない i64 経路を選びます。ループや分岐で i64 が綺麗に残るときだけ ON にして、CI 等では unset のまま。
  • NYASH_MIR_DEV_IDEMP=1

  • Dev-only: Enable idempotence markers inside MIR normalize passes. Each pass stamps pass:function in the module metadata after rewriting a function once, and subsequent optimizer runs skip reprocessing that function for the same pass. 仕様不変既定OFF。診断時に複数回最適化を呼んでも差分が出ないことを保証するための保険だよ。

  • NYASH_LLVM_FAST=1

    • Enables NyRT-based FAST helpers (string length via nyrt_string_length, pointer re-use, etc.) and now caches literal-backed length/len results so loops reuse the same constant value instead of re-calling the helper. Default OFF.
  • NYASH_MIR_LOOP_HOIST=1

    • AOT 前準備AotPrepBoxでの軽ホイスティングを有効化。固定文字列の length/len を即値に置換JSON 書換え)する。制御フローは変更しない。既定 OFF。
  • NYASH_AOT_COLLECTIONS_HOT=1

    • AOT 前準備AotPrepBoxで Array/Map の boxcallexterncallnyash.array.* / nyash.map.*のホットパスに張り替える。AOT 専用の最短経路で、診断を省いてオーバーヘッドを抑える。既定 OFF。
  • HAKO_MIR_NORMALIZE_PRINT=1

    • AotPrep の正規化パス(.hakoを有効化して、print 命令を externcall env.console.log(value) に書き換えるCFG 不変)。既定 OFF。
  • HAKO_MIR_NORMALIZE_REF=1

    • AotPrep の正規化パス(.hakoを有効化して、ref_get/ref_setboxcall getField/setField に書き換えるCFG 不変、best-effort。既定 OFF。
  • HAKO_MIR_NORMALIZE_ARRAY=1

    • AotPrep の正規化パス(.hakoを有効化して、array_get/array_set(および一部の map_get/map_set)を boxcall get/set に書き換えるCFG 不変、best-effort。CollectionsHot の前処理として有効。既定 OFF。
  • NYASH_AOT_INDEX_WINDOW=1

    • AotPrep(CollectionsHot 内部) の index 共有をブロック境界をまたいだ短窓で行う実験的トグル(デフォルト OFF
    • 窓はバイト数で固定2048。誤共有のリスクがあるため初期はベンチ限定で使用。
  • NYASH_VERIFY_RET_PURITY=1

    • Ret ブロック純化の Fail-Fast トグル。Return の直前に ConstCopyPhiNop 以外があると MIR/VM 実行が失敗するようにする開発ガード。既定 OFF。
  • tools/perf/dump_mir.sh

    • MIR(JSON) を provider-first → jsonfrag フォールバックで吐く小さな wrapper。--mode provider で通常 builder 主導、--mode jsonfrag で最小化ループを強制。内部でブロックごとの op カウンターを出力するので、branch/map/kilo などのホットパスをすばやく可視化できるよ。

AOT/LLVM (ny-llvmc)

  • HAKO_LLVM_OPT_LEVEL=0|1
    • ny-llvmc optimization level (default 0/O0). Bench scripts keep O0 unless overridden.
  • NYASH_LLVM_DUMP_MIR_IN=/path/to/out.json
    • ny-llvmc が受け取る MIR(JSON) をそのまま保存する開発用トグル。AotPrep 適用後の実入力を観測するのに使う。既定 OFF。

Bench helpers

  • PERF_USE_PROVIDER=1
    • tools/perf/microbench.sh で provider/selfhost-first の MIR emit を優先jsonfrag 強制を解除)。環境により provider 失敗時は自動で最小ループにフォールバック。