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
* On Lua target, do **not** inline across callback/function-reference-heavy sites (IM `ImFuncRef`-containing callees).
268
+
* This avoids breaking callback context semantics (e.g. wrapper/xpcall/callback-native interactions such as force/group enum callbacks).
269
+
* This is a structural rule, not a name-based exclusion.
270
+
271
+
### Lua locals limit fallback (>200 locals)
272
+
273
+
* Lua has a hard local-variable limit per function.
274
+
* When a function exceeds the safe local threshold, rewrite locals to a locals-table fallback.
275
+
* Requirements for fallback correctness:
276
+
* locals-table declaration must be at function top before first use,
277
+
* rewritten accesses must target the declared table (no global fallback),
278
+
* nested block local initializations must be preserved,
279
+
* use deterministic **numeric slot indices** (`tbl[1]`, `tbl[2]`, ...) rather than string keys.
280
+
281
+
### Regression testing requirements
282
+
283
+
* Any backend parity fix must add/adjust regression tests in `tests.wurstscript.tests.*`.
284
+
* Include tests that check:
285
+
* generated backend output shape for the affected backend,
286
+
* no behavioral regression in the other backend when relevant,
287
+
* known fragile cases (dispatch binding, inlining boundaries, locals spilling).
288
+
289
+
---
290
+
291
+
## 9. Virtual Slot Binding and Determinism (New Generics + Lua)
292
+
293
+
Recent regressions showed that virtual-slot binding can silently degrade to base/no-op implementations in generated Lua while still compiling. Follow these rules for all related changes:
294
+
295
+
### Root-slot correctness is mandatory
296
+
297
+
* For FSM-style dispatch (`currentState.<rootSlot>(...)`), each concrete subclass must bind that **same root slot** to its own most-specific implementation.
298
+
* Never accept mappings where a subclass has its own update method but the dispatched root slot still points to `NoOpState_*` (or another base implementation).
299
+
* When verifying generated Lua, always inspect both:
300
+
* the slot invoked at call-site (`FSM_*update`), and
301
+
* class table assignments for each sibling state class.
* If override wrappers/bridges are created, preserve transitive override links (`wrapper -> real override`) so deeper subclasses remain reachable during slot/name normalization.
306
+
* Avoid transformations that disconnect root methods from concrete overrides in the method union graph.
307
+
308
+
### Deterministic Lua emission requirements
309
+
310
+
* Lua output must be deterministic for identical input (same input -> byte-identical output in test harness).
311
+
* Any iteration over methods/supertypes/union groups used for naming or table assignment must be deterministic (stable ordering).
312
+
* If multiple candidate methods exist for the same slot in a class, selection must be deterministic and must prefer the most specific non-abstract implementation for that class.
313
+
314
+
### Required regression tests for slot fixes
315
+
316
+
* Add a repro with:
317
+
*`State<T:>`, `NoOpState<T:>`, `FSM<T:>`,
318
+
* multiple sibling `NoOpState<Owner>` subclasses (including at least 4+ siblings),
319
+
* early constant state instantiation,
320
+
* root-slot call through `State<T>`.
321
+
* In generated Lua assertions:
322
+
* extract the actual dispatched slot name from `FSM_*update` call-site,
323
+
* assert each concrete sibling class binds that slot to its own implementation,
324
+
* assert no sibling binds that dispatched slot to `NoOpState_*`.
325
+
* Add a compile-twice determinism assertion for the same repro input.
0 commit comments