You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ChadScript's codegen only handles direct calls via named function symbols (call @foo(args) in LLVM IR). Calling through a function pointer — arr[i](args), getCb()(args), obj.field(args) where field holds a function — fails with "Immediately invoked function expressions (IIFE) are not supported".
LLVM supports indirect calls natively (call <sigtype> %ptr(args)) — this is purely a chad codegen gap.
First-class functions stored in class fields and indexed through
Higher-order functions that aren't inlineable (arr.forEach(userCb) where userCb isn't a lambda literal)
Any port of existing TS libraries that use these patterns (Postgres driver, Redis, etc.)
Currently every chad library author hits this and works around with single-slot-per-event (see lib/net.ts in #585 — sock.on() can only have ONE listener per event because of this limitation).
Scope
This is a new codegen capability, not a drive-by fix. Rough shape:
Type inferencer needs to track function type signatures (not just function names) so a Socket["onConnect"] expression has a known (data: string) => void type.
Codegen needs an indirect-call lowering path: load fn pointer into SSA, emit call <sigtype> %ptr(args) instead of call @<name>(args).
Estimated 200-500 LOC of codegen + type-inferencer work. Should be queued behind the current typeOf-migration loop finishing (it touches the same type-inference hotspots).
Until fixed, libraries use single-slot-per-event with explicit if (event === "foo") { this._fooCb = cb; } chains. See lib/net.ts Socket class for the pattern.
Summary
ChadScript's codegen only handles direct calls via named function symbols (
call @foo(args)in LLVM IR). Calling through a function pointer —arr[i](args),getCb()(args),obj.field(args)wherefieldholds a function — fails with "Immediately invoked function expressions (IIFE) are not supported".LLVM supports indirect calls natively (
call <sigtype> %ptr(args)) — this is purely a chad codegen gap.Why it matters
Blocks:
listeners[event].forEach(cb => cb(arg)))handlers[opcode](payload))arr.forEach(userCb)whereuserCbisn't a lambda literal)Currently every chad library author hits this and works around with single-slot-per-event (see
lib/net.tsin #585 —sock.on()can only have ONE listener per event because of this limitation).Scope
This is a new codegen capability, not a drive-by fix. Rough shape:
Socket["onConnect"]expression has a known(data: string) => voidtype.call <sigtype> %ptr(args)instead ofcall @<name>(args).Estimated 200-500 LOC of codegen + type-inferencer work. Should be queued behind the current typeOf-migration loop finishing (it touches the same type-inference hotspots).
Related
arr[i](args)(parser fix landed in fix: three codegen/parser/ffi bugs (#587, #589, #591) #593; this issue is the codegen side of the same problem)Workaround pattern
Until fixed, libraries use single-slot-per-event with explicit
if (event === "foo") { this._fooCb = cb; }chains. Seelib/net.tsSocket class for the pattern.