-
Notifications
You must be signed in to change notification settings - Fork 329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rust backend can panic because of 'attempt to multiply with overflow' #432
Comments
The problem is known and yes the overflow is needed. And I would be interested to know the correct solution. |
As a quick test I have edited the generated code to: let mut iTemp0: Wrapping<i32> = (Wrapping(1103515245) * Wrapping(self.iRec0[1] + 12345));
self.iRec0[0] = (Wrapping(1103515245i32) * (iTemp0 + Wrapping(12345))).0;
let mut iRec1: i32 = iTemp0.0; and then there is no panic. Since the example is noise anyway, it is hard to say if it has the right semantics, but most likely it does. So basically the generator would have to use |
|
I'm no expert on this, but given Rust focus on being explicit about safety, it is likely that this is the only option. My hacky example above maybe made it look more ugly than it has to be. Basically it comes down to:
At least the first two could be made nicer by using type aliases and a macro for the literals. For instance: use std::num::Wrapping;
type I32 = Wrapping<i32>;
macro_rules! w {
($lit:expr) => {
Wrapping($lit)
};
}
fn main() {
// syntax becomes relatively lightweight
let a: I32 = w!(1) * w!(2);
} If the code uses these types consistently there shouldn't be many places where unwrapping is needed. |
Yes, using macro is probably the way to go, I'll have a look ASAP. As curiosity, in what use-case are you testing the Rust backend ? |
No hurry, I should have mentioned that this is only a problem in debug builds. For now it is easy to work-around via
I've always been a fan of Faust, but I never found the time to learn it. I heard that it has Rust support now, and thought that is a nice combination, and a good opportunity to look into it again. For now I'm just experimenting to see how it works / what is possible. (It was actually pretty straightforward to get something running. Now I'm at a point where I can run examples through the portaudiorust architecture, but I have like ~1 sec audio pauses every 0.2 sec or so -- will investigate that, most likely an issue with portaudio. Edit: Turned out to be an issue with the duplex mode of portaudio, see RustAudio/rust-portaudio#180. Switching to a pure output stream works fine, and is sufficient since I don't need audio input.) |
I actually see that there are standard methods implemented for overflowing integer operations. This would do the job: let mut iTemp0: i32 = 1103515245.wrapping_mul(self.iRec0[1].wrapping_add(12345)); |
I've opened a PR implementing the As of now, a possible workaround for now is to disable entirely the overflow checks. It can be done in [profile.dev]
overflow-checks = false This is however global to the entire project. I did not manage to scope it to the module with |
I also think your PR #802 is the way to go. I simply never had the time to figure out where it has to be integrated. Thanks for taking care of that!
Yes, the generated code isn't supposed to be the most human-readable piece of code anyway. If we really care, we could later shorten it slightly by introducing a macro, but I'm not sure if it is worth the effort / added complexity. |
AFAICS it should yes. |
An easy way to reproduce this problem is to use
Running
cargo run
crashes with:Full traceback
The problematic line of code is:
The overflows here are probably on purpose for noise generation. We'll have to look into how this is possible in Rust.
Edit: It looks like
std::num::Wrapping
could be used to allow for intentionally-wrapped arithmetic.CC @bkfox maybe you're more experienced on this.
The text was updated successfully, but these errors were encountered: