Skip to content

Commit bad0fd1

Browse files
committed
Restructure error handling
Most recoverable errors have been modified to trigger appropriate message dialogs instead of panics. Other `.expect()`s have been left with annotations about why they shouldn't fail.
1 parent 5da8bc3 commit bad0fd1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+524
-320
lines changed

core/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ mod disasm {
915915
Instr::Mrc => write!(file, "mrc_mcr::<true>"),
916916
Instr::Swi => write!(file, "swi"),
917917
Instr::Undefined { .. } => write!(file, "undefined"),
918-
oops => unreachable!("{:?}", oops),
918+
_ => unreachable!(),
919919
}?;
920920
write!(file, ",")?;
921921
}

core/src/audio/channel.rs

+2
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ impl Channel {
247247
}
248248

249249
#[inline]
250+
#[allow(clippy::unused_self)]
250251
fn check_loop_start(&self) {
251252
#[cfg(feature = "log")]
252253
if self.control.running() && self.format == Format::Adpcm && self.loop_start == 0 {
@@ -255,6 +256,7 @@ impl Channel {
255256
}
256257

257258
#[inline]
259+
#[allow(clippy::unused_self)]
258260
fn check_total_size(&self) {
259261
#[cfg(feature = "log")]
260262
if self.control.running()

core/src/audio/io.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use super::{capture, channel, Audio, Control};
22
use crate::cpu::bus::AccessType;
33

44
impl Audio {
5+
#[allow(clippy::extra_unused_type_parameters)]
56
pub(crate) fn read_8<A: AccessType>(&mut self, addr: u32) -> u8 {
67
if addr & 0x100 == 0 {
78
let channel = &self.channels[addr as usize >> 4 & 0xF];
@@ -51,6 +52,7 @@ impl Audio {
5152
0
5253
}
5354

55+
#[allow(clippy::extra_unused_type_parameters)]
5456
pub(crate) fn read_16<A: AccessType>(&mut self, addr: u32) -> u16 {
5557
if addr & 0x100 == 0 {
5658
let channel = &self.channels[addr as usize >> 4 & 0xF];
@@ -91,6 +93,7 @@ impl Audio {
9193
0
9294
}
9395

96+
#[allow(clippy::extra_unused_type_parameters)]
9497
pub(crate) fn read_32<A: AccessType>(&mut self, addr: u32) -> u32 {
9598
if addr & 0x100 == 0 {
9699
let channel = &self.channels[addr as usize >> 4 & 0xF];
@@ -122,6 +125,7 @@ impl Audio {
122125
0
123126
}
124127

128+
#[allow(clippy::extra_unused_type_parameters)]
125129
pub(crate) fn write_8<A: AccessType>(&mut self, addr: u32, value: u8) {
126130
if addr & 0x100 == 0 {
127131
let i = addr as usize >> 4 & 0xF;
@@ -253,6 +257,7 @@ impl Audio {
253257
}
254258
}
255259

260+
#[allow(clippy::extra_unused_type_parameters)]
256261
pub(crate) fn write_16<A: AccessType>(&mut self, addr: u32, value: u16) {
257262
if addr & 0x100 == 0 {
258263
let i = addr as usize >> 4 & 0xF;
@@ -332,6 +337,7 @@ impl Audio {
332337
}
333338
}
334339

340+
#[allow(clippy::extra_unused_type_parameters)]
335341
pub(crate) fn write_32<A: AccessType>(&mut self, addr: u32, value: u32) {
336342
if addr & 0x100 == 0 {
337343
let i = addr as usize >> 4 & 0xF;

core/src/ds_slot/rom.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ pub mod icon;
66
pub mod normal;
77

88
use super::RomOutputLen;
9-
use crate::utils::{BoxedByteSlice, ByteMutSlice, Bytes, Savestate};
9+
use crate::{
10+
utils::{BoxedByteSlice, ByteMutSlice, Bytes, Savestate},
11+
Model,
12+
};
1013

1114
#[allow(clippy::len_without_is_empty)]
1215
pub trait Contents {
@@ -112,3 +115,14 @@ impl Rom {
112115
}
113116

114117
impl_from_variants!(Rom; Normal, Empty; normal::Normal, Empty);
118+
119+
pub fn min_size_for_model(model: Model) -> usize {
120+
match model {
121+
Model::Ds | Model::Lite | Model::Ique | Model::IqueLite => 0x200,
122+
Model::Dsi => 0x1000,
123+
}
124+
}
125+
126+
pub fn is_valid_size(len: usize, model: Model) -> bool {
127+
len.is_power_of_two() && len >= min_size_for_model(model)
128+
}

core/src/ds_slot/rom/icon.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ use super::Contents;
22
use crate::utils::Bytes;
33

44
#[inline]
5-
pub fn decode(offset: u32, rom_contents: &mut impl Contents) -> Option<[u32; 32 * 32]> {
5+
pub fn decode(offset: usize, rom_contents: &mut impl Contents) -> Option<[u32; 32 * 32]> {
66
let mut icon_data = Bytes::new([0; 0x220]);
7-
rom_contents.read_slice(offset as usize, icon_data.as_byte_mut_slice());
7+
if offset + 0x220 > rom_contents.len() {
8+
return None;
9+
}
10+
rom_contents.read_slice(offset, icon_data.as_byte_mut_slice());
811

912
let mut palette = [0; 16];
1013
for (i, color) in palette.iter_mut().enumerate().skip(1) {

core/src/ds_slot/rom/normal.rs

+13-22
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
1-
use super::{super::RomOutputLen, key1, Contents};
1+
use super::{super::RomOutputLen, is_valid_size, key1, Contents};
22
use crate::{
33
cpu::arm7,
44
utils::{make_zero, zero, ByteMutSlice, Bytes, Savestate},
5+
Model,
56
};
6-
use core::fmt;
77

88
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
99
pub enum CreationError {
10-
SizeNotPowerOfTwo,
11-
SizeTooSmall,
12-
}
13-
14-
impl fmt::Display for CreationError {
15-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16-
match self {
17-
CreationError::SizeNotPowerOfTwo => f.write_str("ROM size not power of 2"),
18-
CreationError::SizeTooSmall => f.write_str("ROM size too small"),
19-
}
20-
}
10+
InvalidSize,
2111
}
2212

2313
#[derive(Clone, Copy, PartialEq, Eq, Savestate)]
@@ -47,19 +37,17 @@ pub struct Normal {
4737

4838
impl Normal {
4939
/// # Errors
50-
/// - [`CreationError::SizeNotPowerOfTwo`](CreationError::SizeNotPowerOfTwo): the ROM contents'
51-
/// size is not a power of two.
40+
/// - [`CreationError::InvalidSize`](CreationError::InvalidSize): the ROM contents' size is
41+
/// either not a power of two or too small.
5242
pub fn new(
5343
contents: Box<dyn Contents>,
5444
arm7_bios: Option<&Bytes<{ arm7::BIOS_SIZE }>>,
45+
model: Model,
5546
#[cfg(feature = "log")] logger: slog::Logger,
5647
) -> Result<Self, CreationError> {
5748
let len = contents.len();
58-
if !len.is_power_of_two() {
59-
return Err(CreationError::SizeNotPowerOfTwo);
60-
}
61-
if len < 0x200 {
62-
return Err(CreationError::SizeTooSmall);
49+
if !is_valid_size(len, model) {
50+
return Err(CreationError::InvalidSize);
6351
}
6452
let rom_mask = (len - 1) as u32;
6553
let chip_id = 0x0000_00C2
@@ -160,7 +148,10 @@ impl super::RomDevice for Normal {
160148
let Some(mut secure_area) = self.contents.secure_area_mut() else {
161149
return Ok(());
162150
};
163-
let key_buf = self.key_buf.as_ref().unwrap();
151+
let key_buf = self
152+
.key_buf
153+
.as_ref()
154+
.expect("key_buf should be initialized");
164155
if secure_area.read_le::<u64>(0) == 0xE7FF_DEFF_E7FF_DEFF {
165156
secure_area[..8].copy_from_slice(b"encryObj");
166157
let level_3_key_buf = key_buf.level_3::<2>();
@@ -244,7 +235,7 @@ impl super::RomDevice for Normal {
244235
let res = self
245236
.key_buf
246237
.as_ref()
247-
.unwrap()
238+
.expect("key_buf should be initialized")
248239
.decrypt_64_bit([cmd.read_be(4), cmd.read_be(0)]);
249240
cmd.write_be(4, res[0]);
250241
cmd.write_be(0, res[1]);

core/src/ds_slot/spi/eeprom_4k.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub struct Eeprom4k {
4141

4242
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4343
pub enum CreationError {
44-
IncorrectSize,
44+
InvalidSize,
4545
}
4646

4747
impl Eeprom4k {
@@ -51,7 +51,7 @@ impl Eeprom4k {
5151
#[cfg(feature = "log")] logger: slog::Logger,
5252
) -> Result<Self, CreationError> {
5353
if contents.len() != 512 {
54-
return Err(CreationError::IncorrectSize);
54+
return Err(CreationError::InvalidSize);
5555
}
5656
let mut result = Eeprom4k {
5757
#[cfg(feature = "log")]

core/src/ds_slot/spi/eeprom_fram.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub struct EepromFram {
5151

5252
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5353
pub enum CreationError {
54-
IncorrectSize,
54+
InvalidSize,
5555
}
5656

5757
pub enum CreationContents {}
@@ -63,7 +63,7 @@ impl EepromFram {
6363
#[cfg(feature = "log")] logger: slog::Logger,
6464
) -> Result<Self, CreationError> {
6565
if !matches!(contents.len(), 0x2000 | 0x1_0000 | 0x2_0000) {
66-
return Err(CreationError::IncorrectSize);
66+
return Err(CreationError::InvalidSize);
6767
}
6868
let contents_len_mask = (contents.len() - 1) as u32;
6969
let page_mask = match contents.len().trailing_zeros() {

core/src/ds_slot/spi/flash.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub struct Flash {
1717

1818
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1919
pub enum CreationError {
20-
IncorrectSize,
20+
InvalidSize,
2121
}
2222

2323
pub enum CreationContents {}
@@ -30,7 +30,7 @@ impl Flash {
3030
#[cfg(feature = "log")] logger: slog::Logger,
3131
) -> Result<Self, CreationError> {
3232
if !matches!(contents.len(), 0x4_0000 | 0x8_0000 | 0x10_0000) {
33-
return Err(CreationError::IncorrectSize);
33+
return Err(CreationError::InvalidSize);
3434
}
3535
Ok(Flash {
3636
contents: flash::Flash::new(
@@ -39,7 +39,8 @@ impl Flash {
3939
#[cfg(feature = "log")]
4040
logger.new(slog::o!("contents" => "")),
4141
)
42-
.unwrap(),
42+
// NOTE: The contents' length was just checked above, this should never occur.
43+
.expect("Couldn't create SPI FLASH device"),
4344
has_ir,
4445
ir_cmd: 0,
4546
first_ir_data_byte: false,

core/src/emu.rs

+3-23
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,9 @@ use crate::{
2828
wifi::WiFi,
2929
Model,
3030
};
31-
use core::fmt;
3231
#[cfg(feature = "xq-audio")]
3332
use core::num::NonZeroU32;
3433
use input::Input;
35-
use std::error::Error;
3634
use swram::Swram;
3735

3836
proc_bitfield::bitfield! {
@@ -193,26 +191,6 @@ pub enum BuildError {
193191
RomNeedsDecryptionButNoBiosProvided,
194192
}
195193

196-
impl Error for BuildError {}
197-
198-
impl fmt::Display for BuildError {
199-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200-
match self {
201-
BuildError::MissingSysFiles => f.write_str("missing system files"),
202-
BuildError::RomCreation(e) => write!(f, "ROM creation error: {e}"),
203-
BuildError::RomNeedsDecryptionButNoBiosProvided => {
204-
f.write_str("ROM needs decryption, but no original ARM7 BIOS provided")
205-
}
206-
}
207-
}
208-
}
209-
210-
impl fmt::Debug for BuildError {
211-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212-
<Self as fmt::Display>::fmt(self, f)
213-
}
214-
}
215-
216194
impl Builder {
217195
#[inline]
218196
#[allow(clippy::too_many_arguments)]
@@ -273,6 +251,7 @@ impl Builder {
273251
ds_slot::rom::normal::Normal::new(
274252
contents,
275253
self.arm7_bios.as_deref(),
254+
self.model,
276255
#[cfg(feature = "log")]
277256
self.logger.new(slog::o!("ds_rom" => "normal")),
278257
)
@@ -402,7 +381,8 @@ impl<E: cpu::Engine> Emu<E> {
402381
let mut header_bytes = Bytes::new([0; 0x170]);
403382
self.ds_slot.rom.read_header(&mut header_bytes);
404383
let header = ds_slot::rom::header::Header::new(header_bytes.as_byte_slice())
405-
.expect("invalid ROM header");
384+
// NOTE: The ROM file's size is ensured beforehand, this should never occur.
385+
.expect("Couldn't read DS slot ROM header");
406386
let chip_id = self.ds_slot.rom.chip_id();
407387

408388
macro_rules! write_main_mem {

core/src/flash.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub struct Flash {
4242

4343
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4444
pub enum CreationError {
45-
SizeNotPowerOfTwo,
45+
InvalidSize,
4646
}
4747

4848
impl Flash {
@@ -51,8 +51,8 @@ impl Flash {
5151
id: [u8; 20],
5252
#[cfg(feature = "log")] logger: slog::Logger,
5353
) -> Result<Self, CreationError> {
54-
if !contents.len().is_power_of_two() || contents.len() < 0x4_0000 {
55-
return Err(CreationError::SizeNotPowerOfTwo);
54+
if !contents.len().is_power_of_two() || contents.len() < 0x2_0000 {
55+
return Err(CreationError::InvalidSize);
5656
}
5757
let contents_len_mask = (contents.len() - 1) as u32;
5858
Ok(Flash {

core/src/gpu/engine_2d/io.rs

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use super::{
55
use crate::cpu::bus::AccessType;
66

77
impl<R: Role> Engine2d<R> {
8+
#[allow(clippy::extra_unused_type_parameters)]
89
pub(crate) fn read_8<A: AccessType>(&mut self, addr: u32) -> u8 {
910
let addr = addr & 0x7F;
1011
match addr {
@@ -34,6 +35,7 @@ impl<R: Role> Engine2d<R> {
3435
}
3536
}
3637

38+
#[allow(clippy::extra_unused_type_parameters)]
3739
pub(crate) fn read_16<A: AccessType>(&mut self, addr: u32) -> u16 {
3840
let addr = addr & 0x7E;
3941
match addr {
@@ -60,6 +62,7 @@ impl<R: Role> Engine2d<R> {
6062
}
6163
}
6264

65+
#[allow(clippy::extra_unused_type_parameters)]
6366
pub(crate) fn read_32<A: AccessType>(&mut self, addr: u32) -> u32 {
6467
let addr = addr & 0x7C;
6568
match addr {
@@ -85,6 +88,7 @@ impl<R: Role> Engine2d<R> {
8588
}
8689
}
8790

91+
#[allow(clippy::extra_unused_type_parameters)]
8892
pub(crate) fn write_8<A: AccessType>(&mut self, addr: u32, value: u8) {
8993
let addr = addr & 0x7F;
9094
match addr {
@@ -201,6 +205,7 @@ impl<R: Role> Engine2d<R> {
201205
}
202206
}
203207

208+
#[allow(clippy::extra_unused_type_parameters)]
204209
pub(crate) fn write_16<A: AccessType>(&mut self, addr: u32, value: u16) {
205210
let addr = addr & 0x7E;
206211
match addr {
@@ -311,6 +316,7 @@ impl<R: Role> Engine2d<R> {
311316
}
312317
}
313318

319+
#[allow(clippy::extra_unused_type_parameters)]
314320
pub(crate) fn write_32<A: AccessType>(&mut self, addr: u32, value: u32) {
315321
let addr = addr & 0x7C;
316322
match addr {

core/src/gpu/engine_3d.rs

+1
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,7 @@ impl Engine3d {
576576
}
577577

578578
#[inline]
579+
#[allow(clippy::unused_self, clippy::let_and_return)]
579580
fn params_for_command(&self, command: u8) -> u8 {
580581
let result = CMD_PARAMS[command as usize];
581582
#[cfg(feature = "log")]

0 commit comments

Comments
 (0)