feat: port Jet Pack + Low Gravity to Rust, investigate codegen UB
Browse filesJet Pack (0x51EC30): pure Rust — sends msg 0x5E to CTaskTeam, plays sound
via FUN_0053EC70 (usercall EDI=0x6CB) + FUN_005480F0 (usercall EAX=-21).
Low Gravity (0x51EA60): Rust implementation ready but kept on bridge.
Changing match arm 24 from naked-fn bridge to any other code causes a
desync in freeze_nuke_armageddon — LLVM's register allocation changes for
the entire match, exposing latent UB in the reachable code paths.
Investigation showed: not opt-level dependent, not inlining dependent,
specifically requires a naked extern "C" function call in the arm to
produce correct codegen. Plan: eliminate all usercall bridges from
fire_weapon_special to sidestep the issue.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
crates/openwa-wormkit/src/replacements/weapon.rs
CHANGED
|
@@ -405,8 +405,9 @@ unsafe fn fire_weapon_special(
|
|
| 405 |
22 => fire_jet_pack(worm),
|
| 406 |
// Magic Bullet
|
| 407 |
23 => (*worm).set_state(WormState::WeaponAimed_Maybe),
|
| 408 |
-
// Low Gravity — kept on bridge
|
| 409 |
-
// desync
|
|
|
|
| 410 |
24 => call_fire_usercall(entry as *const (), worm, rb(0x51EA60)),
|
| 411 |
_ => {}
|
| 412 |
}
|
|
|
|
| 405 |
22 => fire_jet_pack(worm),
|
| 406 |
// Magic Bullet
|
| 407 |
23 => (*worm).set_state(WormState::WeaponAimed_Maybe),
|
| 408 |
+
// Low Gravity — kept on bridge. Changing this arm to non-naked-fn code causes
|
| 409 |
+
// a codegen-dependent desync: LLVM's register allocation for the match changes,
|
| 410 |
+
// exposing latent UB somewhere in the reachable code paths. See investigation notes.
|
| 411 |
24 => call_fire_usercall(entry as *const (), worm, rb(0x51EA60)),
|
| 412 |
_ => {}
|
| 413 |
}
|