Skip to content

Mover queries hand their visitors planes and segments of their own - #98

Merged
nicolas-maman merged 1 commit into
mainfrom
fix/mover-scratch-reentrancy
Oct 4, 2026
Merged

nicolas-maman merged 1 commit into
mainfrom
fix/mover-scratch-reentrancy

Conversation

@nicolas-maman

Copy link
Copy Markdown
Collaborator

I audited the character mover and the height field against Box3D e77352c. Both match upstream line for line, apart from one reentrancy hazard, which this fixes.

The hazard:

  • collide_mover passed its visitor the per-worker mover-plane scratch block, and body_collide_mover wrote into that same block.
  • cast_mover's proxy pointed at the per-worker segment scratch, which body_time_of_impact_mover and any nested cast_mover rewrote.

So a visitor or filter that queried the mover again (a character checking a moving platform mid-query, say) found the outer query's planes, or the capsule it was sweeping, silently replaced. Upstream keeps them on each call's stack.

The fix:

  • collide_mover gives its visitor a planes block of its own, allocated for the query and freed after it.
  • cast_mover keeps the segment in its own context and points the proxy there.
  • body_collide_mover writes each plane straight into the caller's result.

The shared plane scratch is gone, so test_physics_world's count of permanent allocations drops by one. test_mover_world's new test_nested_mover_queries has a visitor ask a platform body for its plane mid-query and checks its own plane is unchanged. On main it reads the platform's plane instead.

All 28 test programs pass locally on aether 0.772.0, with no warnings.

…of their own

collide_mover passed its visitor the per-worker mover-plane scratch, and
body_collide_mover wrote into the same block; cast_mover's proxy pointed at
the per-worker segment scratch, which body_time_of_impact_mover and any
nested cast_mover rewrote. A visitor or filter that queried the mover
again -- a character checking a moving platform mid-query -- found the
outer query's planes (or the capsule it was sweeping) silently replaced.
The reference keeps them on each call's stack. Now:

- collide_mover gives its visitor a planes block of its own, allocated
  for the query and freed after it;
- cast_mover keeps the segment in its context and points the proxy there;
- body_collide_mover writes each plane straight into the caller's result.

The shared plane scratch is gone (test_physics_world's permanent
allocations drop by one). test_mover_world's test_nested_mover_queries: a
visitor asking a platform body for its plane mid-query keeps its own plane
(on main it reads the platform's). Found by an audit of the mover and the
height field against Box3D e77352c, which found them otherwise faithful.
@nicolas-maman
nicolas-maman merged commit bdd1635 into main Oct 4, 2026
1 check passed
@nicolas-maman
nicolas-maman deleted the fix/mover-scratch-reentrancy branch October 6, 2026 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant