Compiler segfaults on become inside an @On handler for a runtime-declared event (e.g. UiClicked) #91
Labels
No labels
area:ci
area:docs
area:input
area:net
area:rendering
area:repo
area:stdlib
area:tooling
area:types
cleanup
dx
priority:high
priority:low
priority:medium
proposal
status:in-progress
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: workshopsoft/ludic#91
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A program that lists
@On(UiClicked) handler Nav { ... become SomeScene ... }— an event listener for the engine's built-inUiClickedevent (declared/emitted in runtime/native/ui_draw.ludic) whose body usesbecome— crashes ludicc with SIGSEGV (no diagnostic).Minimal repro:
Notes narrowing it:
becomeinside an @On handler for a GAME-declared event works;@On(UiClicked)withoutbecomeworks (a listener that only sets a var is fine). It is the combination —becomeinside a listener for a runtime-spliced event — that segfaults. Likely the scene-register/emit_becomelowering assumes an enclosing scene/handler context that an onlisten block for a spliced event doesn't provide.Workaround: read
Ui.clickedin an ordinaryphase Updatehandler instead of@On(UiClicked). A crash should be a diagnostic, andbecomefrom any handler ought to work.Fixed on main — the repro compiles and runs (no diagnostic needed:
becomefrom any handler now works).Two things were wrong, both in the compiler:
becomeoutside a scene's own layers (an@On(Event)listener, a global handler, a plain function) has no enclosing scene at compile time. The lowering reused the last emitted handler's scene id — or dereferenced nothing and crashed, which is the SIGSEGV. The compiler now emits@L_scene_leave(), a dispatch on the live scene id that runs the leaving scene'son exit, and calls it from such sites; so a listener'sbecomealso fires the correcton exit(a global handler'sbecomeused to skip it entirely).UI_Namehandle read from a listener / plain function (if id == UI_Go) indexed the widget table before@ui_buildhad been emitted, which came after functions and listeners — a second crash on the same repro. The table is now built on first use.Regression:
examples/library/scene_menus.ludic(inx test) doesbecomefrom an@On(UiClicked)listener into a second scene and checks the exit/enter sequence. The engine also firesUiClicked { id }itself now, so the@On(UiClicked)form in your repro is the intended one — no need for theUi.clickedpolling workaround.Commit:
ad54884