diff --git a/bend2/comp.ts b/bend2/comp.ts index f2c29dad0..840ba25d0 100644 --- a/bend2/comp.ts +++ b/bend2/comp.ts @@ -3291,8 +3291,8 @@ function js_def(fl: File, k: Bend.Name, def: Def): void { js_func(fl, def.h ?? die("unelaborated def " + k), def.T, params); } else { const n = eff_name(k); - file_push(fl, `return { $: "$FFI", run: $0eff.${n}, need: $0eff.${n - }_need, args: [${params.join(", ")}], kont: ${kont[0]} };`); + file_push(fl, `return { $: "$FFI", run: $0eff.${n}.run, need: $0eff.${n + }.need, args: [${params.join(", ")}], kont: ${kont[0]} };`); } }); file_push(fl, ""); @@ -3317,9 +3317,8 @@ export function js_lib(book: Bend.Book, roots: Bend.Name[], ms.push(n); const rows = grps.get(path) ?? []; grps.set(path, rows); - for (const m of [n, n + "_need"]) { - rows.push(` ${m}: typeof ${m} === "function" ? ${m} : undefined,`); - } + rows.push(` ["${n}"]: { run: typeof ${n} === "function" ? ${n} : undefined,` + + ` need: typeof ${n}_need === "function" ? ${n}_need : undefined },`); } const dup = ms.find((m, i) => ms.indexOf(m) < i); if (dup !== undefined) die("two names mangle to " + dup); diff --git a/tests/io/effect_need_collision.bend b/tests/io/effect_need_collision.bend new file mode 100644 index 000000000..1036e8d05 --- /dev/null +++ b/tests/io/effect_need_collision.bend @@ -0,0 +1,16 @@ +# An effect named like another module's scheduling helper keeps its value. +import Base + +def A.run(ms: U32) -> IO(U32): + import "./effect_need_worker.js" + +def A.run_need() -> IO(U32): + import "./effect_need_name.js" + +def main() -> IO(Unit): + do IO: + y : U32 <- A.run_need() + x : U32 <- A.run(1) + IO.print(U32.show(x) ++ " " ++ U32.show(y)) + +#|11 22 diff --git a/tests/io/effect_need_collision_reverse.bend b/tests/io/effect_need_collision_reverse.bend new file mode 100644 index 000000000..fbc63aa03 --- /dev/null +++ b/tests/io/effect_need_collision_reverse.bend @@ -0,0 +1,16 @@ +# Reversing discovery order also preserves the scheduling helper's call. +import Base + +def A.run(ms: U32) -> IO(U32): + import "./effect_need_worker.js" + +def A.run_need() -> IO(U32): + import "./effect_need_name.js" + +def main() -> IO(Unit): + do IO: + x : U32 <- A.run(1) + y : U32 <- A.run_need() + IO.print(U32.show(x) ++ " " ++ U32.show(y)) + +#|11 22 diff --git a/tests/io/effect_need_name.js b/tests/io/effect_need_name.js new file mode 100644 index 000000000..a2de7f6e6 --- /dev/null +++ b/tests/io/effect_need_name.js @@ -0,0 +1,3 @@ +function a_run_need() { + return 22; +} diff --git a/tests/io/effect_need_worker.js b/tests/io/effect_need_worker.js new file mode 100644 index 000000000..969153e5b --- /dev/null +++ b/tests/io/effect_need_worker.js @@ -0,0 +1,12 @@ +let asked = false; + +function a_run(ms) { + const value = asked ? 11 : 99; + asked = false; + return value; +} + +function a_run_need() { + asked = true; + return { time: true }; +} diff --git a/tests/io/effect_proto.bend b/tests/io/effect_proto.bend new file mode 100644 index 000000000..8bd2b0d08 --- /dev/null +++ b/tests/io/effect_proto.bend @@ -0,0 +1,12 @@ +# The foreign table keeps __proto__ as an own effect entry. +import Base + +def __proto__() -> IO(U32): + import "./effect_proto.js" + +def main() -> IO(Unit): + do IO: + x : U32 <- __proto__() + IO.print(U32.show(x)) + +#|77 diff --git a/tests/io/effect_proto.js b/tests/io/effect_proto.js new file mode 100644 index 000000000..bb0cb6fd8 --- /dev/null +++ b/tests/io/effect_proto.js @@ -0,0 +1,3 @@ +function __proto__() { + return 77; +}