package ampfn_test; // Direct-w6c asm-window gate over `&fn` address-of lowering (#180). // Port of the retired native carrier test/wcc/764_amp_fn_ident.c; // every unowned assertion preserved. Runtime for the five symmetric // rows is owned by the r764_amp_fn_ident_* fixtures (their sources // are compiled here IN PLACE so fixture and window can never drift); // pre-fix those fixtures still exit 0 on the junk store — the LEAQ // presence below is the actual discriminator the corpus cannot own. // // Rows 1-5: the cstage .s must contain the row's `LEAQ (SB)` // line (absent pre-#180: the cgen N_UN TK_AMP IDENT arm had no TY_FN // branch, so the assign site stored stale AX junk), and cstage vs // wwstage .s must be byte-identical (rule 10; the carrier compared // driver __root.s — same emitter output, direct w6c form per the // residual audit). // // cross_module: `&pkg.fn` over a real import tree. CSTAGE-ONLY — // wwstage bails asserttyped on the N_UN TK_AMP N_DOT-mod-ident shape // (open #184); its build/run and byte-id legs graduate when #184 // lifts. The M1 path-mangled `LEAQ wcamffn764mod.somefn(SB)` and the // build+run exit 0 are pinned; separate fresh trees keep the -S // compile and the full build from sharing a stale sepwork. import os; import os.exec; import strings; import testenv; import time; fn fail(label: str, why: str) void = { let m: str = strings.concat("ampfn FAIL: ", label, " -- ", why, "\n"); os.write(2, m.ptr, m.len: u64); assert(false); }; fn tmo() time.duration = { return (180i64 * (time.second: i64)): time.duration; }; fn emit(td: str, label: str, stage: str, drv: str, src: str, outname: str) void = { let av: []str = [drv, "-o", strings.concat(td, "/", outname), src]; let co: testenv.commandout; testenv.runcommand(td, td, stage, av, tmo(), &co); if (co.termination != exec.termination.EXIT || co.code != 0) { fail(label, strings.concat(stage, " compile failed")); }; }; fn leaqrow(label: str, fixture: str, needle: str) void = { let src: str = strings.concat(testenv.repo(), "/test/wcc/data/r764_amp_fn_ident_", fixture, "/case.ww"); let td: str = testenv.fresh(); emit(td, label, "cstage", testenv.driver("w6c"), src, "cs.s"); emit(td, label, "wwstage", testenv.driver("w6c_ww"), src, "ws.s"); let cs: str = testenv.readfile(strings.concat(td, "/cs.s")); let ws: str = testenv.readfile(strings.concat(td, "/ws.s")); if (!testenv.has(cs, needle)) { fail(label, strings.concat("missing `", needle, "` in cstage .s (silent TK_AMP IDENT drop)")); }; if (!testenv.same(cs, ws)) { fail(label, "cstage vs wwstage asm differs"); }; testenv.clean(td); }; @test fn ampfnleaq() void = { leaqrow("minimal", "minimal", "LEAQ\tmain.add1(SB)"); leaqrow("branched_callee", "branched", "LEAQ\tmain.bb(SB)"); leaqrow("alias_chain", "alias_chain", "LEAQ\tmain.add1(SB)"); leaqrow("fn_with_args", "args", "LEAQ\tmain.many(SB)"); leaqrow("fn_tuple_return", "tuple_return", "LEAQ\tmain.pair(SB)"); }; fn xmodtree() str = { let td: str = testenv.fresh(); assert(os.mkdir(strings.concat(td, "/wcamffn764mod"), 493) == 0); testenv.writefile( strings.concat(td, "/wcamffn764mod/wcamffn764mod.ww"), strings.concat( "package wcamffn764mod;\n", "export fn somefn(x: i32) i32 = { return x + 1; };\n")); testenv.writefile(strings.concat(td, "/main764.ww"), strings.concat( "package main;\n", "import wcamffn764mod;\n", "export fn main() i32 = {\n", " let f = &wcamffn764mod.somefn;\n", " return 0;\n", "};\n")); return td; }; fn runcode(dir: str, name: str, argv: []str) i32 = { let co: testenv.commandout; testenv.runcommand(dir, dir, name, argv, tmo(), &co); if (co.termination != exec.termination.EXIT) { return -1; }; return co.code; }; @test fn crossmodule() void = { let tda: str = xmodtree(); let av: []str = [testenv.driver("ww"), "build", "-S", "-o", strings.concat(tda, "/main764"), "main764.ww"]; if (runcode(tda, "compile", av) != 0) { fail("cross_module", "cstage ww build -S failed"); }; let s: str = testenv.readfile( strings.concat(tda, "/main764.sepwork/__root.s")); if (!testenv.has(s, "LEAQ\twcamffn764mod.somefn(SB)")) { fail("cross_module", "missing path-mangled LEAQ wcamffn764mod.somefn(SB)"); }; testenv.clean(tda); let tdb: str = xmodtree(); let bav: []str = [testenv.driver("ww"), "build", "-o", strings.concat(tdb, "/main764"), "main764.ww"]; if (runcode(tdb, "build", bav) != 0) { fail("cross_module", "cstage ww build failed"); }; let rav: []str = [strings.concat(tdb, "/main764")]; if (runcode(tdb, "run", rav) != 0) { fail("cross_module", "run-exit != 0"); }; testenv.clean(tdb); };