Skip to content

Commit d45879d

Browse files
committed
aml: support DefBreakpoint + some logical operations
1 parent 3f616f5 commit d45879d

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

aml/src/lib.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,17 @@ impl Interpreter {
130130

131131
*operand = new_value;
132132
}
133+
Opcode::LAnd
134+
| Opcode::LOr
135+
| Opcode::LNot
136+
| Opcode::LNotEqual
137+
| Opcode::LLessEqual
138+
| Opcode::LGreaterEqual
139+
| Opcode::LEqual
140+
| Opcode::LGreater
141+
| Opcode::LLess => {
142+
self.do_logical_op(&mut context, op)?;
143+
}
133144
Opcode::Name => {
134145
let [Argument::Namestring(name), Argument::Object(object)] = &op.arguments[..] else {
135146
panic!()
@@ -797,7 +808,9 @@ impl Interpreter {
797808
Opcode::Noop => {}
798809
Opcode::Return => context.start_in_flight_op(OpInFlight::new(Opcode::Return, 1)),
799810
Opcode::Break => todo!(),
800-
Opcode::Breakpoint => todo!(),
811+
Opcode::Breakpoint => {
812+
self.handler.breakpoint();
813+
}
801814
Opcode::Ones => {
802815
context.last_op()?.arguments.push(Argument::Object(Arc::new(Object::Integer(u64::MAX))));
803816
}
@@ -879,9 +892,48 @@ impl Interpreter {
879892
};
880893

881894
context.contribute_arg(Argument::Object(Arc::new(Object::Integer(result as u64))));
895+
Ok(())
896+
}
897+
898+
fn do_logical_op(&self, context: &mut MethodContext, op: OpInFlight) -> Result<(), AmlError> {
899+
if op.op == Opcode::LNot {
900+
let [Argument::Object(operand)] = &op.arguments[..] else { Err(AmlError::InvalidOperationOnObject)? };
901+
let Object::Integer(operand) = **operand else { Err(AmlError::InvalidOperationOnObject)? };
902+
let result = if operand == 0 { u64::MAX } else { 0 };
903+
904+
if let Some(prev_op) = context.in_flight.last_mut() {
905+
if prev_op.arguments.len() < prev_op.expected_arguments {
906+
prev_op.arguments.push(Argument::Object(Arc::new(Object::Integer(result))));
907+
}
882908
}
909+
910+
return Ok(());
883911
}
884912

913+
let [Argument::Object(left), Argument::Object(right)] = &op.arguments[..] else {
914+
Err(AmlError::InvalidOperationOnObject)?
915+
};
916+
917+
// TODO: for some of the ops, strings and buffers are also allowed :(
918+
// TODO: apparently when doing this conversion (^), NT's interpreter just takes the first 4
919+
// bytes of the string/buffer and casts them to an integer lmao
920+
let Object::Integer(left) = **left else { Err(AmlError::InvalidOperationOnObject)? };
921+
let Object::Integer(right) = **right else { Err(AmlError::InvalidOperationOnObject)? };
922+
923+
let result = match op.op {
924+
Opcode::LAnd => (left > 0) && (right > 0),
925+
Opcode::LOr => (left > 0) || (right > 0),
926+
Opcode::LNotEqual => left != right,
927+
Opcode::LLessEqual => left <= right,
928+
Opcode::LGreaterEqual => left >= right,
929+
Opcode::LEqual => left == right,
930+
Opcode::LGreater => left > right,
931+
Opcode::LLess => left < right,
932+
_ => panic!(),
933+
};
934+
let result = if result { Object::Integer(u64::MAX) } else { Object::Integer(0) };
935+
936+
context.contribute_arg(Argument::Object(Arc::new(result)));
885937
Ok(())
886938
}
887939
fn do_store(
@@ -1516,6 +1568,8 @@ pub trait Handler: Send + Sync {
15161568
/// time supported, and should relinquish the processor.
15171569
fn sleep(&self, milliseconds: u64);
15181570

1571+
fn breakpoint(&self) {}
1572+
15191573
fn handle_fatal_error(&self, fatal_type: u8, fatal_code: u32, fatal_arg: u64) {
15201574
panic!(
15211575
"Fatal error while executing AML (encountered DefFatalOp). fatal_type = {:?}, fatal_code = {:?}, fatal_arg = {:?}",

0 commit comments

Comments
 (0)