Summary
Two separate defects in node:net's createServer on Perry 0.5.1010 — distinct from #1121 (which is node:http).
Repro A — dotted form fails codegen
// /tmp/test_net_server.ts
import * as net from "node:net";
const server = net.createServer((sock: any) => { sock.end("ok\n"); });
console.log("server =", server);
server.listen(18997, () => { console.log("LISTENING"); });
$ PERRY_ALLOW_PERRY_FEATURES=1 perry /tmp/test_net_server.ts -o /tmp/test_net_server
Error compiling module 'test_net_server.ts' (...) with --backend llvm:
lowering entry of module 'test_net_server.ts':
lowering init statements of module 'test_net_server.ts':
perry-codegen Phase 2: expression NetCreateServer not yet supported
Repro B — named-import form compiles+links but returns undefined
// /tmp/test_net_server2.ts
import { createServer } from "node:net";
const server = createServer((sock: any) => { sock.end("ok\n"); });
console.log("server =", server);
if (server) server.listen(18996, () => { console.log("LISTENING"); });
$ PERRY_ALLOW_PERRY_FEATURES=1 perry /tmp/test_net_server2.ts -o /tmp/test_net_server2
Wrote executable: /tmp/test_net_server2
$ /tmp/test_net_server2
server = undefined
server is falsy, so server.listen(...) never gets called — silent failure. No listener bound, no error message.
Why
A — dotted form
HIR lowering creates Expr::NetCreateServer for net.createServer(...) (see crates/perry-hir/src/lower/expr_call.rs:1899 and :3393), and the variant is defined at crates/perry-hir/src/ir.rs:2024. But the LLVM codegen in crates/perry-codegen/src/expr.rs has no match arm for it — only perry-codegen-js (emit.rs:1782) and perry-codegen-wasm (emit.rs:9404) handle it. So it falls through to the generic "expression X not yet supported" at crates/perry-codegen/src/expr.rs:13659.
The runtime symbol js_net_create_server exists (crates/perry-runtime/src/net.rs:35) and is declared in crates/perry-codegen/src/runtime_decls.rs:2690 — only the lowering arm in LLVM codegen is missing.
B — named-import form
import { createServer } from "node:net"; createServer(handler) reaches a different lowering path that doesn't go through Expr::NetCreateServer. It compiles into something that produces undefined at runtime instead of a Server handle. Worth investigating whether this should also synthesize a NetCreateServer HIR node, or whether the bare-call path needs its own native-module dispatch.
Fix sketch
- A: Add an
Expr::NetCreateServer match arm in crates/perry-codegen/src/expr.rs that lowers to a call of js_net_create_server(options_i64, listener_i64) — mirror the shape of the existing NetCreateConnection / similar handlers (runtime_decls.rs:2690 already declares the signature: I64, &[I64, I64]).
- B: In
crates/perry-hir/src/lower/expr_call.rs, find the named-import-of-createServer path (parallel to the existing ("net", "createConnection") named-import handling at lines 1896-1899) and synthesize the same Expr::NetCreateServer node so both forms converge on (1).
Environment
perry 0.5.1010 (HEAD: 89786c6)
- macOS arm64
Refs
Summary
Two separate defects in
node:net'screateServeron Perry 0.5.1010 — distinct from #1121 (which isnode:http).Repro A — dotted form fails codegen
Repro B — named-import form compiles+links but returns undefined
serveris falsy, soserver.listen(...)never gets called — silent failure. No listener bound, no error message.Why
A — dotted form
HIR lowering creates
Expr::NetCreateServerfornet.createServer(...)(seecrates/perry-hir/src/lower/expr_call.rs:1899and:3393), and the variant is defined atcrates/perry-hir/src/ir.rs:2024. But the LLVM codegen incrates/perry-codegen/src/expr.rshas no match arm for it — onlyperry-codegen-js(emit.rs:1782) andperry-codegen-wasm(emit.rs:9404) handle it. So it falls through to the generic "expression X not yet supported" atcrates/perry-codegen/src/expr.rs:13659.The runtime symbol
js_net_create_serverexists (crates/perry-runtime/src/net.rs:35) and is declared incrates/perry-codegen/src/runtime_decls.rs:2690— only the lowering arm in LLVM codegen is missing.B — named-import form
import { createServer } from "node:net"; createServer(handler)reaches a different lowering path that doesn't go throughExpr::NetCreateServer. It compiles into something that producesundefinedat runtime instead of a Server handle. Worth investigating whether this should also synthesize aNetCreateServerHIR node, or whether the bare-call path needs its own native-module dispatch.Fix sketch
Expr::NetCreateServermatch arm incrates/perry-codegen/src/expr.rsthat lowers to a call ofjs_net_create_server(options_i64, listener_i64)— mirror the shape of the existingNetCreateConnection/ similar handlers (runtime_decls.rs:2690already declares the signature:I64, &[I64, I64]).crates/perry-hir/src/lower/expr_call.rs, find the named-import-of-createServerpath (parallel to the existing("net", "createConnection")named-import handling at lines 1896-1899) and synthesize the sameExpr::NetCreateServernode so both forms converge on (1).Environment
perry 0.5.1010(HEAD: 89786c6)Refs
node:httpcreateServer (sibling issue; my testing shows that one actually works on 0.5.1010 underPERRY_ALLOW_PERRY_FEATURES=1withimport { createServer } from "node:http"— separate followup will comment on http: createServer/Server.listen/ServerResponse.end missing from stdlib runtime (api manifest claims support) #1121)