Class CallbackReachableOperations

java.lang.Object
org.ek9lang.compiler.phase9.CallbackReachableOperations
All Implemented Interfaces:
Function<Collection<IRConstruct>, Set<OperationInstr>>

public final class CallbackReachableOperations extends Object implements Function<Collection<IRConstruct>, Set<OperationInstr>>
THE callback-reachable operations of a program: those the runtime may call - directly, or through other operations - while one of its C frames is live below them (EK9_NATIVE_CYCLE_COLLECTOR_DESIGN.md §14.3). Such a frame holds pointers it never counted, so no cycle collection may run inside one of these; every other operation may collect at its safe points. Use this - never a second list of runtime entry routes.

Roots - every way the runtime calls generated code:

  1. the operators in the vtable's Any prefix (PREFIX_OPERATORS, as CanonicalVTableLayout names them): a container, sort or $ of a collection calls them through the vtable;
  2. a function's _call where a value of that function is anything but the receiver of one _call - passed, stored, merged: it may reach the runtime (a stream stage, sort by, a handler);
  3. every operation of a class (any aggregate) with a core supertype or trait (other than Any): the runtime knows those members' slots;
  4. every operation of a service, and of a @Test program (the runtime dispatches them);
  5. fail closed: an operation no CALL in the IR reaches, other than a program's _main and a _c_init (the generated entry point and static initialisation call those) - when the IR cannot say who calls it, the runtime may.

Not a root (route B, Steve 2026-11-03; design §14.3 refined): the _call of a TCPHandler. The runtime's one route to it is the TCP connection worker (tcp_connection_worker via ek9_tcp_guarded_handle), whose frames hold only counted references, so a collection may run inside the handler - its loop's back edge gets a safe point, a collection per line on a long connection. EK9 code that calls a handler from a callback-reachable operation still reaches it through the call edges below.

Propagation follows every CALL in the operations already reached: to the operations of the named type with that name (overloads together - more reached is never unsafe), and, for a virtual or trait call, to the same name on every type in the program that has the named type as a supertype or trait. Stateless: hold one.