feat(phase21.5/22.1): MirBuilder JsonFrag refactor + FileBox ring-1 + registry tests

Phase 21.5 (AOT/LLVM Optimization Prep)
- FileBox ring-1 (core-ro) provider: priority=-100, always available, no panic path
  - src/runner/modes/common_util/provider_registry.rs: CoreRoFileProviderFactory
  - Auto-registers at startup, eliminates fallback panic structurally
- StringBox fast path prototypes (length/size optimization)
- Performance benchmarks (C/Python/Hako comparison baseline)

Phase 22.1 (JsonFrag Unification)
- JsonFrag.last_index_of_from() for backward search (VM fallback)
- Replace hand-written lastIndexOf in lower_loop_sum_bc_box.hako
- SentinelExtractorBox for Break/Continue pattern extraction

MirBuilder Refactor (Box → JsonFrag Migration)
- 20+ lower_*_box.hako: Box-heavy → JsonFrag text assembly
- MirBuilderMinBox: lightweight using set for dev env
- Registry-only fast path with [registry:*] tag observation
- pattern_util_box.hako: enhanced pattern matching

Dev Environment & Testing
- Dev toggles: SMOKES_DEV_PREINCLUDE=1 (point-enable), HAKO_MIR_BUILDER_SKIP_LOOPS=1
- phase2160: registry opt-in tests (array/map get/set/push/len) - content verification
- phase2034: rc-dependent → token grep (grep -F based validation)
- run_quick.sh: fast smoke testing harness
- ENV documentation: docs/ENV_VARS.md

Test Results
 quick phase2034: ALL GREEN (MirBuilder internal patterns)
 registry phase2160: ALL GREEN (array/map get/set/push/len)
 rc-dependent tests → content token verification complete
 PREINCLUDE policy: default OFF, point-enable only where needed

Technical Notes
- No INCLUDE by default (maintain minimalism)
- FAIL_FAST=0 in Bring-up contexts only (explicit dev toggles)
- Tag-based route observation ([mirbuilder/min:*], [registry:*])
- MIR structure validation (not just rc parity)

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-10 19:42:42 +09:00
parent fc5706e3f2
commit 6055d53eff
135 changed files with 3983 additions and 1150 deletions

View File

@ -28,6 +28,27 @@ pub fn register_provider_factory(factory: Arc<dyn ProviderFactory>) {
registry.lock().unwrap().push(factory);
}
/// Builtin ring1 FileBox provider (corero) — always available, lowest priority
struct CoreRoFileProviderFactory;
impl ProviderFactory for CoreRoFileProviderFactory {
fn box_name(&self) -> &str { "FileBox" }
fn create_provider(&self) -> Arc<dyn FileIo> { Arc::new(CoreRoFileIo::new()) }
fn is_available(&self) -> bool { true }
fn priority(&self) -> i32 { -100 } // ring1: lower than any plugin/provider
}
/// Ensure ring1 (corero) provider is present in the registry
fn ensure_builtin_file_provider_registered() {
let reg = PROVIDER_FACTORIES.get_or_init(|| Mutex::new(Vec::new()));
let mut guard = reg.lock().unwrap();
// If at least one FileBox provider exists, we still keep ring1 present for safety; avoid duplicates by checking any corero present by priority
let has_core_ro = guard.iter().any(|f| f.box_name() == "FileBox" && f.priority() <= -100);
if !has_core_ro {
guard.push(Arc::new(CoreRoFileProviderFactory));
}
}
/// Read FileBox mode from environment variables
#[allow(dead_code)]
pub fn read_filebox_mode_from_env() -> FileBoxMode {
@ -45,8 +66,10 @@ pub fn read_filebox_mode_from_env() -> FileBoxMode {
/// Select provider based on mode and registered factories (SSOT)
#[allow(dead_code)]
pub fn select_file_provider(mode: FileBoxMode) -> Arc<dyn FileIo> {
let registry = PROVIDER_FACTORIES.get();
let quiet_pipe = crate::config::env::env_bool("NYASH_JSON_ONLY");
// Always ensure ring1 (corero) exists before inspecting registry
ensure_builtin_file_provider_registered();
let registry = PROVIDER_FACTORIES.get();
match mode {
FileBoxMode::Auto => {
@ -69,11 +92,27 @@ pub fn select_file_provider(mode: FileBoxMode) -> Arc<dyn FileIo> {
}
}
// Fallback to core-ro
if !quiet_pipe {
eprintln!("[provider-registry] FileBox: using core-ro fallback");
// Fallback policy
// Allow a narrow, explicit carveout:
// - When JSONonly pipeline is active (quiet structured I/O), or
// - When NYASH_FILEBOX_ALLOW_FALLBACK=1 is set,
// always use corero provider even if FailFast is ON.
let allow_fb_override =
crate::config::env::env_bool("NYASH_JSON_ONLY") ||
crate::config::env::env_bool("NYASH_FILEBOX_ALLOW_FALLBACK");
if crate::config::env::fail_fast() && !allow_fb_override {
eprintln!("[failfast/provider/filebox:auto-fallback-blocked]");
panic!("Fail-Fast: FileBox provider fallback is disabled (NYASH_FAIL_FAST=0 or NYASH_FILEBOX_ALLOW_FALLBACK=1 to override)");
} else {
if !quiet_pipe {
eprintln!(
"[provider-registry] FileBox: using core-ro fallback{}",
if allow_fb_override { " (override)" } else { "" }
);
}
Arc::new(CoreRoFileIo::new())
}
Arc::new(CoreRoFileIo::new())
}
FileBoxMode::PluginOnly => {
// Try only registered providers, Fail-Fast if none available
@ -105,4 +144,3 @@ pub fn select_file_provider(mode: FileBoxMode) -> Arc<dyn FileIo> {
}
}
}