phase-20.45: PRIMARY no-fallback reps + MIR v0 shape fixes

- Fix MIR v0 shape in lowers: functions[] + name="main" + blocks.id
  * lower_return_int_box.hako
  * lower_return_binop_box.hako
- runner_min: adopt LowerReturnBinOpBox before ReturnInt
- Add PRIMARY no-fallback canaries (all PASS):
  * return-binop / array-size / load-store / return-logical (OR)
- Fix phase2043 runner_min canary alias (Runner -> BuilderRunnerMinBox)
- Update docs: phase-20.45 README (PRIMARY reps), CURRENT_TASK progress

Ancillary: keep builder/provider/canary files in sync; no unrelated behavior changes.
This commit is contained in:
nyash-codex
2025-11-05 18:57:03 +09:00
parent 0996090d6d
commit 96ea3892af
119 changed files with 4746 additions and 316 deletions

View File

@ -368,17 +368,19 @@ HCODE
verify_program_via_builder_to_core() {
local prog_json_path="$1"
# Step 1: Use MirBuilderBox to convert Program → MIRenv経由でJSONを渡す
# Step 1: Use minimal runner to convert Program → MIRenv経由でJSONを渡す
local mir_json_path="/tmp/builder_output_$$.json"
local builder_code=$(cat <<'HCODE'
using "hako.mir.builder" as MirBuilderBox
local builder_code_min=$(cat <<'HCODE'
using "hako.mir.builder.internal.runner_min" as BuilderRunnerMinBox
static box Main { method main(args) {
local prog_json = env.get("NYASH_VERIFY_JSON")
local prog_json = env.get("HAKO_BUILDER_PROGRAM_JSON")
if prog_json == null { print("Builder failed"); return 1 }
local mir_out = MirBuilderBox.emit_from_program_json_v0(prog_json, null)
local mir_out = BuilderRunnerMinBox.run(prog_json)
if mir_out == null { print("Builder failed"); return 1 }
print("[MIR_OUT_BEGIN]")
print("" + mir_out)
print("[MIR_OUT_END]")
return 0
} }
HCODE
@ -389,21 +391,70 @@ HCODE
prog_json_raw="$(cat "$prog_json_path")"
# Run builder with internal lowers enabled using v1 dispatcher
local mir_json
local mir_json=""
local builder_stderr="/tmp/builder_stderr_$$.log"
mir_json=$(HAKO_MIR_BUILDER_INTERNAL=1 \
local builder_stdout="/tmp/builder_stdout_$$.log"
# Try minimal runner first (fast path), unless HAKO_PREFER_MIRBUILDER=1
if [ "${HAKO_PREFER_MIRBUILDER:-0}" = "1" ]; then
: # skip minimal runner
else
mir_json=$(HAKO_MIR_BUILDER_INTERNAL=1 \
HAKO_MIR_RUNNER_MIN_NO_METHODS=1 \
HAKO_FAIL_FAST_ON_HAKO_IN_NYASH_VM=0 \
HAKO_ROUTE_HAKOVM=1 \
NYASH_ENABLE_USING=1 HAKO_ENABLE_USING=1 \
NYASH_USING_AST=1 \
NYASH_RESOLVE_FIX_BRACES=1 \
NYASH_DISABLE_NY_COMPILER=1 \
NYASH_PARSER_STAGE3=1 \
HAKO_PARSER_STAGE3=1 \
NYASH_ENTRY_ALLOW_TOPLEVEL_MAIN=1 \
NYASH_VERIFY_JSON="$prog_json_raw" \
run_nyash_vm -c "$builder_code" 2>"$builder_stderr" | tail -n 1)
HAKO_BUILDER_PROGRAM_JSON="$prog_json_raw" \
run_nyash_vm -c "$builder_code_min" 2>"$builder_stderr" | tee "$builder_stdout" | awk '/\[MIR_OUT_BEGIN\]/{flag=1;next}/\[MIR_OUT_END\]/{flag=0}flag')
fi
# Fallback Option A: use Rust CLI builder when Hako builder fails
if [ "${HAKO_MIR_BUILDER_DEBUG:-0}" = "1" ]; then
echo "[builder debug] stdout (tail):" >&2
tail -n 60 "$builder_stdout" >&2 || true
echo "[builder debug] stderr (tail):" >&2
tail -n 60 "$builder_stderr" >&2 || true
fi
# Fallback Option A: try full MirBuilderBox (emit) when minimal runner fails
if [ "$mir_json" = "Builder failed" ] || [ -z "$mir_json" ]; then
local builder_code_full=$(cat <<'HCODE'
using "hako.mir.builder" as MirBuilderBox
static box Main { method main(args) {
local prog_json = env.get("HAKO_BUILDER_PROGRAM_JSON")
if prog_json == null { print("Builder failed"); return 1 }
local mir_out = MirBuilderBox.emit_from_program_json_v0(prog_json, null)
if mir_out == null { print("Builder failed"); return 1 }
print("[MIR_OUT_BEGIN]")
print("" + mir_out)
print("[MIR_OUT_END]")
return 0
} }
HCODE
)
mir_json=$(HAKO_MIR_BUILDER_INTERNAL=1 \
HAKO_FAIL_FAST_ON_HAKO_IN_NYASH_VM=0 \
HAKO_ROUTE_HAKOVM=1 \
NYASH_ENABLE_USING=1 HAKO_ENABLE_USING=1 \
NYASH_USING_AST=1 NYASH_RESOLVE_FIX_BRACES=1 \
NYASH_DISABLE_NY_COMPILER=1 NYASH_PARSER_STAGE3=1 HAKO_PARSER_STAGE3=1 \
NYASH_ENTRY_ALLOW_TOPLEVEL_MAIN=1 \
HAKO_BUILDER_PROGRAM_JSON="$prog_json_raw" \
run_nyash_vm -c "$builder_code_full" 2>>"$builder_stderr" | tee -a "$builder_stdout" | awk '/\[MIR_OUT_BEGIN\]/{flag=1;next}/\[MIR_OUT_END\]/{flag=0}flag')
fi
# PRIMARY no-fallback: if requested, do not fall back to Rust CLI builder
if [ "${HAKO_PRIMARY_NO_FALLBACK:-0}" = "1" ]; then
if [ "$mir_json" = "Builder failed" ] || [ -z "$mir_json" ]; then
return 1
fi
fi
# Fallback Option B: use Rust CLI builder when Hako builder fails
if [ "$mir_json" = "Builder failed" ] || [ -z "$mir_json" ]; then
if [ "${HAKO_MIR_BUILDER_DEBUG:-0}" = "1" ] && [ -f "$builder_stderr" ]; then
echo "[builder debug] Hako builder failed, falling back to Rust CLI" >&2
@ -413,18 +464,30 @@ HCODE
rm -f "$builder_stderr"
local tmp_mir="/tmp/ny_builder_conv_$$.json"
if "$NYASH_BIN" --program-json-to-mir "$tmp_mir" --json-file "$prog_json_path" >/dev/null 2>&1; then
"$NYASH_BIN" --mir-json-file "$tmp_mir" >/dev/null 2>&1
local rc=$?
rm -f "$tmp_mir"
return $rc
if [ "${HAKO_VERIFY_BUILDER_ONLY:-0}" = "1" ]; then
# Builder-only: check structure only
if grep -q '"functions"' "$tmp_mir" && grep -q '"blocks"' "$tmp_mir"; then
rm -f "$tmp_mir"; return 0
else
rm -f "$tmp_mir"; return 1
fi
else
"$NYASH_BIN" --mir-json-file "$tmp_mir" >/dev/null 2>&1
local rc=$?
rm -f "$tmp_mir"
return $rc
fi
else
return 1
fi
fi
rm -f "$builder_stderr"
rm -f "$builder_stderr" "$builder_stdout"
# Validate builder output looks like MIR JSON; otherwise fallback to Rust CLI
# Validate builder output looks like MIR JSON; otherwise fallback to Rust CLI (unless PRIMARY no-fallback)
if ! echo "$mir_json" | grep -q '"functions"' || ! echo "$mir_json" | grep -q '"blocks"'; then
if [ "${HAKO_PRIMARY_NO_FALLBACK:-0}" = "1" ]; then
return 1
fi
# fallback: Rust CLI builder
local tmp_mir="/tmp/ny_builder_conv_$$.json"
if "$NYASH_BIN" --program-json-to-mir "$tmp_mir" --json-file "$prog_json_path" >/dev/null 2>&1; then
@ -437,7 +500,48 @@ HCODE
fi
fi
# Write MIR JSON to temp file and execute
# Route: if builder output contains v1 hints, run hv1 dispatcher inline.
if echo "$mir_json" | grep -q '"schema_version"' || echo "$mir_json" | grep -q '"op"\s*:\s*"mir_call"'; then
local hv1_rc
local mir_literal; mir_literal="$(printf '%s' "$mir_json" | jq -Rs .)"
hv1_rc=$(run_hv1_inline_alias_wrapper "$mir_literal")
if [[ "$hv1_rc" =~ ^-?[0-9]+$ ]]; then
local n=$hv1_rc; if [ $n -lt 0 ]; then n=$(( (n % 256 + 256) % 256 )); else n=$(( n % 256 )); fi
return $n
fi
fi
# Route: if builder output is v0 but contains unified-only ops (newbox/boxcall),
# execute via Hako Core dispatcher (NyVmDispatcher.run) which supports extended v0.
if echo "$mir_json" | grep -q '"op"\s*:\s*"newbox"' || echo "$mir_json" | grep -q '"op"\s*:\s*"boxcall"'; then
local mir_literal2; mir_literal2="$(printf '%s' "$mir_json" | jq -Rs .)"
local code=$(cat <<'HCODE'
include "lang/src/vm/core/dispatcher.hako"
static box Main { method main(args) {
local j = env.get("NYASH_VERIFY_JSON")
local r = NyVmDispatcher.run(j)
print("" + r)
return r
} }
HCODE
)
local out; out=$(NYASH_VERIFY_JSON="$mir_literal2" NYASH_PREINCLUDE=1 run_nyash_vm -c "$code" 2>/dev/null | tr -d '\r' | awk '/^-?[0-9]+$/{n=$0} END{if(n!="") print n}')
if [[ "$out" =~ ^-?[0-9]+$ ]]; then
local n=$out; if [ $n -lt 0 ]; then n=$(( (n % 256 + 256) % 256 )); else n=$(( n % 256 )); fi
return $n
fi
fi
# Optional: structure-only check (builder only) for fast mode
if [ "${HAKO_VERIFY_BUILDER_ONLY:-0}" = "1" ]; then
if echo "$mir_json" | grep -q '"functions"' && echo "$mir_json" | grep -q '"blocks"'; then
return 0
else
return 1
fi
fi
# Write MIR JSON to temp file and execute via Core
echo "$mir_json" > "$mir_json_path"
"$NYASH_BIN" --mir-json-file "$mir_json_path" >/dev/null 2>&1
local rc=$?
@ -446,6 +550,24 @@ HCODE
return $rc
}
# hv1 inline alias-only wrapper (env JSON → hv1 dispatcher)
# Usage: run_hv1_inline_alias_wrapper "$json_literal" → prints rc line; returns rc
run_hv1_inline_alias_wrapper() {
local json_literal="$1"
local code=$(cat <<'HCODE'
using "selfhost.vm.hv1.dispatch" as NyVm
static box Main { method main(args) {
local j = env.get("NYASH_VERIFY_JSON")
local r = NyVm.NyVmDispatcherV1Box.run(j)
print("" + r)
return r
} }
HCODE
)
HAKO_FAIL_FAST_ON_HAKO_IN_NYASH_VM=0 NYASH_USING_AST=1 NYASH_RESOLVE_FIX_BRACES=1 \
NYASH_VERIFY_JSON="$json_literal" run_nyash_vm -c "$code" 2>/dev/null | tr -d '\r' | awk '/^-?[0-9]+$/{n=$0} END{if(n!="") print n}'
}
# Nyash実行ヘルパーLLVM
run_nyash_llvm() {
local program="$1"