We were noticing behavioral differences with our program transpiled with Wasynth running on Roblox on Windows and other platforms.
@vegorov-rbx investigated this; thanks a ton! His (paraphrased) findings are below:
In the Luau Wasynth runtime, to_u32
is defined as bit32.band
.
https://github.com/Rerumu/Wasynth/blob/0394aa8895e7f0429342adb2a88b3b3d6cbcf67c/codegen/luau/runtime/runtime.lua#L3
In div.i32
and div.u32
, the results of division is passed directly to to_u32
.
https://github.com/Rerumu/Wasynth/blob/0394aa8895e7f0429342adb2a88b3b3d6cbcf67c/codegen/luau/runtime/runtime.lua#L78-L91
Luau 5.2, from which Luau was forked, specifies the following:
Unless otherwise stated, all functions accept numeric arguments in the range (-251,+251); each argument is normalized to the remainder of its division by 232 and truncated to an integer (in some unspecified way), so that its final value falls in the range [0,232 - 1].
The behavior varies based on platform:
- Lua 5.2 x86 depends on processor rounding mode (default round to +Inf)
- Lua 5.2 x64 uses round to +Inf
- Luau x86 depends on processor rounding mode (default round to +Inf)
- Luau x64/arm truncates (round to 0)
Some differences can be observed in the Luau codebase. For example, here is how numbers are converted to unsigned integers on Windows x86.
This can be fixed by changing the runtime to truncate the numbers before passing to bit32.band
. One potential way of doing this is using modf:
local i, _ = math.modf(lhs / rhs)
return to_u32(i)
The LuaJIT runtime also seems to have some truncation logic baked in which could be adopted for Luau as well.
I can confirm adding the math.modf
fix resolves the behavioral differences on the Windows Roblox client for our transpiled program. I was unable to get a minimal CLI repro as Luau Windows CLI appears to be compiled to an x64 target and the bug affects x86. It should be pretty straightforward to repro this in Roblox if necessary by observing the rounding/truncation on a published place on the Windows Roblox client (note that the bug doesn't repro in Studio.)