diff --git a/lang/src/compiler/entry/bundle_resolver.hako b/lang/src/compiler/entry/bundle_resolver.hako index 72c08249..90f29a7d 100644 --- a/lang/src/compiler/entry/bundle_resolver.hako +++ b/lang/src/compiler/entry/bundle_resolver.hako @@ -7,6 +7,15 @@ static box BundleResolver { // - --require-mod Name must appear in named bundles ([bundle/missing] Name) // - Merge order: bundle-src* → bundle-mod* (in given order) resolve(bundle_srcs, bundle_names, bundle_mod_srcs, require_mods) { + // Shallow recursion guard to prevent accidental self-recursion in Stage‑B bundler. + { + local depth = env.get("HAKO_STAGEB_BUNDLE_DEPTH") + if depth != null && ("" + depth) != "0" { + print("[stageb/recursion] BundleResolver.resolve recursion detected") + return null + } + env.set("HAKO_STAGEB_BUNDLE_DEPTH", "1") + } // Alias table via env: HAKO_BUNDLE_ALIAS_TABLE / NYASH_BUNDLE_ALIAS_TABLE // Format: entries separated by '|||', each entry as 'Name:code' local table = env.get("HAKO_BUNDLE_ALIAS_TABLE") @@ -101,6 +110,8 @@ static box BundleResolver { local i2 = 0; local m2 = bundle_mod_srcs.length() loop(i2 < m2) { merged = merged + bundle_mod_srcs.get(i2) + "\n" i2 = i2 + 1 } } + // Clear depth guard before returning + env.set("HAKO_STAGEB_BUNDLE_DEPTH", "0") return merged } } diff --git a/lang/src/compiler/entry/using_resolver_box.hako b/lang/src/compiler/entry/using_resolver_box.hako index 0eee4a4b..003bdeee 100644 --- a/lang/src/compiler/entry/using_resolver_box.hako +++ b/lang/src/compiler/entry/using_resolver_box.hako @@ -14,6 +14,16 @@ using selfhost.shared.json.utils.json_frag as JsonFragBox static box Stage1UsingResolverBox { resolve_for_source(src) { + // Shallow recursion guard to prevent accidental self-recursion in Stage‑1 using resolver. + { + local depth = env.get("HAKO_STAGEB_USING_DEPTH") + if depth != null && ("" + depth) != "0" { + print("[stageb/recursion] Stage1UsingResolverBox.resolve_for_source recursion detected") + return "" + } + env.set("HAKO_STAGEB_USING_DEPTH", "1") + } + if src == null { return "" } local apply_flag = env.get("HAKO_STAGEB_APPLY_USINGS") if apply_flag != null && ("" + apply_flag) == "0" { return "" } @@ -52,6 +62,8 @@ static box Stage1UsingResolverBox { i = i + 1 } + // Clear depth guard before returning + env.set("HAKO_STAGEB_USING_DEPTH", "0") return prefix }