Skip to content

Commit 8378db4

Browse files
committed
aml: better type mismatch errors + DefNot support
1 parent 4c24b08 commit 8378db4

File tree

2 files changed

+47
-36
lines changed

2 files changed

+47
-36
lines changed

aml/src/lib.rs

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,17 @@ where
121121
| Opcode::Xor => {
122122
self.do_binary_maths(&mut context, op)?;
123123
}
124-
Opcode::FindSetLeftBit | Opcode::FindSetRightBit => {
124+
Opcode::Not | Opcode::FindSetLeftBit | Opcode::FindSetRightBit => {
125125
self.do_unary_maths(&mut context, op)?;
126126
}
127127
Opcode::Increment | Opcode::Decrement => {
128128
let [Argument::Object(operand)] = &op.arguments[..] else { panic!() };
129-
let Object::Integer(operand) = operand.gain_mut() else { panic!() };
129+
let Object::Integer(operand) = operand.gain_mut() else {
130+
Err(AmlError::ObjectNotOfExpectedType {
131+
expected: ObjectType::Integer,
132+
got: operand.typ(),
133+
})?
134+
};
130135

131136
let new_value = match op.op {
132137
Opcode::Increment => operand.wrapping_add(1),
@@ -163,7 +168,7 @@ where
163168
else {
164169
panic!()
165170
};
166-
let Object::Integer(arg) = **arg else { panic!() };
171+
let arg = arg.as_integer()?;
167172
self.handler.handle_fatal_error(*typ, *code, arg);
168173
}
169174
Opcode::OpRegion => {
@@ -176,9 +181,8 @@ where
176181
else {
177182
panic!()
178183
};
179-
let Object::Integer(region_offset) = **region_offset else { panic!() };
180-
let Object::Integer(region_length) = **region_length else { panic!() };
181-
184+
let region_offset = region_offset.as_integer()?;
185+
let region_length = region_length.as_integer()?;
182186
let region_space = RegionSpace::from(*region_space);
183187

184188
let region = Object::OpRegion(OpRegion {
@@ -197,7 +201,7 @@ where
197201
else {
198202
panic!()
199203
};
200-
let Object::Integer(buffer_size) = **buffer_size else { panic!() };
204+
let buffer_size = buffer_size.as_integer()?;
201205

202206
let buffer_len = pkg_length - (context.current_block.pc - start_pc);
203207
let mut buffer = vec![0; buffer_size as usize];
@@ -242,7 +246,7 @@ where
242246
panic!()
243247
};
244248

245-
let Object::Integer(predicate) = **predicate else { panic!() };
249+
let predicate = predicate.as_integer()?;
246250
let remaining_then_length = then_length - (context.current_block.pc - start_pc);
247251

248252
if predicate > 0 {
@@ -267,7 +271,7 @@ where
267271
panic!()
268272
};
269273
let name = context.namestring()?;
270-
let Object::Integer(index) = **index else { panic!() };
274+
let index = index.as_integer()?;
271275
let (offset, length) = match opcode {
272276
Opcode::CreateBitField => (index, 1),
273277
Opcode::CreateByteField => (index * 8, 8),
@@ -292,8 +296,9 @@ where
292296
panic!()
293297
};
294298
let name = context.namestring()?;
295-
let Object::Integer(bit_index) = **bit_index else { panic!() };
296-
let Object::Integer(num_bits) = **num_bits else { panic!() };
299+
let bit_index = bit_index.as_integer()?;
300+
let num_bits = num_bits.as_integer()?;
301+
297302
self.namespace.lock().insert(
298303
name.resolve(&context.current_scope)?,
299304
Arc::new(Object::BufferField {
@@ -309,13 +314,11 @@ where
309314
}
310315
Opcode::Sleep => {
311316
let [Argument::Object(msec)] = &op.arguments[..] else { panic!() };
312-
let Object::Integer(msec) = **msec else { panic!() };
313-
self.handler.sleep(msec);
317+
self.handler.sleep(msec.as_integer()?);
314318
}
315319
Opcode::Stall => {
316320
let [Argument::Object(usec)] = &op.arguments[..] else { panic!() };
317-
let Object::Integer(usec) = **usec else { panic!() };
318-
self.handler.stall(usec);
321+
self.handler.stall(usec.as_integer()?);
319322
}
320323
Opcode::InternalMethodCall => {
321324
let [Argument::Object(method), Argument::Namestring(method_scope)] = &op.arguments[0..2]
@@ -396,8 +399,7 @@ where
396399
else {
397400
panic!()
398401
};
399-
let Object::Integer(bank_value) = **bank_value else { panic!() };
400-
402+
let bank_value = bank_value.as_integer()?;
401403
let field_flags = context.next()?;
402404

403405
let (region, bank) = {
@@ -954,12 +956,8 @@ where
954956
None
955957
};
956958

957-
let Object::Integer(left) = *left.clone().unwrap_transparent_reference() else {
958-
Err(AmlError::InvalidOperationOnObject)?
959-
};
960-
let Object::Integer(right) = *right.clone().unwrap_transparent_reference() else {
961-
Err(AmlError::InvalidOperationOnObject)?
962-
};
959+
let left = left.clone().unwrap_transparent_reference().as_integer()?;
960+
let right = right.clone().unwrap_transparent_reference().as_integer()?;
963961

964962
let value = match op.op {
965963
Opcode::Add => left.wrapping_add(right),
@@ -989,7 +987,7 @@ where
989987

990988
fn do_unary_maths(&self, context: &mut MethodContext, op: OpInFlight) -> Result<(), AmlError> {
991989
let [Argument::Object(operand)] = &op.arguments[..] else { Err(AmlError::InvalidOperationOnObject)? };
992-
let Object::Integer(operand) = **operand else { Err(AmlError::InvalidOperationOnObject)? };
990+
let operand = operand.clone().unwrap_transparent_reference().as_integer()?;
993991

994992
let result = match op.op {
995993
Opcode::FindSetLeftBit => {
@@ -1000,27 +998,34 @@ where
1000998
* TODO: this is a particular instance where not respecting integers being
1001999
* 32-bit on revision 1 tables does cause properly incorrect behaviour...
10021000
*/
1003-
operand.leading_zeros() + 1
1001+
(operand.leading_zeros() + 1) as u64
10041002
}
10051003
}
10061004
Opcode::FindSetRightBit => {
10071005
if operand == 0 {
10081006
0
10091007
} else {
1010-
operand.trailing_zeros() + 1
1008+
(operand.trailing_zeros() + 1) as u64
1009+
}
1010+
}
1011+
Opcode::Not => {
1012+
if operand == 0 {
1013+
u64::MAX
1014+
} else {
1015+
0
10111016
}
10121017
}
10131018
_ => panic!(),
10141019
};
10151020

1016-
context.contribute_arg(Argument::Object(Arc::new(Object::Integer(result as u64))));
1021+
context.contribute_arg(Argument::Object(Arc::new(Object::Integer(result))));
10171022
Ok(())
10181023
}
10191024

10201025
fn do_logical_op(&self, context: &mut MethodContext, op: OpInFlight) -> Result<(), AmlError> {
10211026
if op.op == Opcode::LNot {
10221027
let [Argument::Object(operand)] = &op.arguments[..] else { Err(AmlError::InvalidOperationOnObject)? };
1023-
let Object::Integer(operand) = **operand else { Err(AmlError::InvalidOperationOnObject)? };
1028+
let operand = operand.clone().unwrap_transparent_reference().as_integer()?;
10241029
let result = if operand == 0 { u64::MAX } else { 0 };
10251030

10261031
if let Some(prev_op) = context.in_flight.last_mut() {
@@ -1039,8 +1044,8 @@ where
10391044
// TODO: for some of the ops, strings and buffers are also allowed :(
10401045
// TODO: apparently when doing this conversion (^), NT's interpreter just takes the first 4
10411046
// bytes of the string/buffer and casts them to an integer lmao
1042-
let Object::Integer(left) = **left else { Err(AmlError::InvalidOperationOnObject)? };
1043-
let Object::Integer(right) = **right else { Err(AmlError::InvalidOperationOnObject)? };
1047+
let left = left.clone().unwrap_transparent_reference().as_integer()?;
1048+
let right = right.clone().unwrap_transparent_reference().as_integer()?;
10441049

10451050
let result = match op.op {
10461051
Opcode::LAnd => (left > 0) && (right > 0),
@@ -1061,7 +1066,7 @@ where
10611066

10621067
fn do_from_bcd(&self, context: &mut MethodContext, op: OpInFlight) -> Result<(), AmlError> {
10631068
let [Argument::Object(value)] = &op.arguments[..] else { Err(AmlError::InvalidOperationOnObject)? };
1064-
let Object::Integer(mut value) = **value else { Err(AmlError::InvalidOperationOnObject)? };
1069+
let mut value = value.clone().unwrap_transparent_reference().as_integer()?;
10651070

10661071
let mut result = 0;
10671072
let mut i = 1;
@@ -1077,7 +1082,7 @@ where
10771082

10781083
fn do_to_bcd(&self, context: &mut MethodContext, op: OpInFlight) -> Result<(), AmlError> {
10791084
let [Argument::Object(value)] = &op.arguments[..] else { Err(AmlError::InvalidOperationOnObject)? };
1080-
let Object::Integer(mut value) = **value else { Err(AmlError::InvalidOperationOnObject)? };
1085+
let mut value = value.clone().unwrap_transparent_reference().as_integer()?;
10811086

10821087
let mut result = 0;
10831088
let mut i = 0;
@@ -1110,9 +1115,7 @@ where
11101115
let [Argument::Object(object), Argument::Object(index_value), target] = &op.arguments[..] else {
11111116
panic!()
11121117
};
1113-
let Object::Integer(index_value) = **index_value else {
1114-
Err(AmlError::ObjectNotOfExpectedType { expected: ObjectType::Integer, got: index_value.typ() })?
1115-
};
1118+
let index_value = index_value.as_integer()?;
11161119

11171120
let result = Arc::new(match **object {
11181121
Object::Buffer(ref buffer) => {
@@ -1319,7 +1322,7 @@ impl MethodContext {
13191322
};
13201323
Ok(context)
13211324
} else {
1322-
panic!()
1325+
Err(AmlError::ObjectNotOfExpectedType { expected: ObjectType::Method, got: method.typ() })
13231326
}
13241327
}
13251328

aml/src/object.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ impl Object {
4444
}
4545
}
4646

47+
pub fn as_integer(&self) -> Result<u64, AmlError> {
48+
if let Object::Integer(value) = self {
49+
Ok(*value)
50+
} else {
51+
Err(AmlError::ObjectNotOfExpectedType { expected: ObjectType::Integer, got: self.typ() })
52+
}
53+
}
54+
4755
pub fn read_buffer_field(&self, dst: &mut [u8]) -> Result<(), AmlError> {
4856
if let Self::BufferField { buffer, offset, length } = self {
4957
let buffer = match **buffer {

0 commit comments

Comments
 (0)