@@ -130,6 +130,17 @@ impl Interpreter {
130
130
131
131
* operand = new_value;
132
132
}
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
+ }
133
144
Opcode :: Name => {
134
145
let [ Argument :: Namestring ( name) , Argument :: Object ( object) ] = & op. arguments [ ..] else {
135
146
panic ! ( )
@@ -797,7 +808,9 @@ impl Interpreter {
797
808
Opcode :: Noop => { }
798
809
Opcode :: Return => context. start_in_flight_op ( OpInFlight :: new ( Opcode :: Return , 1 ) ) ,
799
810
Opcode :: Break => todo ! ( ) ,
800
- Opcode :: Breakpoint => todo ! ( ) ,
811
+ Opcode :: Breakpoint => {
812
+ self . handler . breakpoint ( ) ;
813
+ }
801
814
Opcode :: Ones => {
802
815
context. last_op ( ) ?. arguments . push ( Argument :: Object ( Arc :: new ( Object :: Integer ( u64:: MAX ) ) ) ) ;
803
816
}
@@ -879,9 +892,48 @@ impl Interpreter {
879
892
} ;
880
893
881
894
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
+ }
882
908
}
909
+
910
+ return Ok ( ( ) ) ;
883
911
}
884
912
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) ) ) ;
885
937
Ok ( ( ) )
886
938
}
887
939
fn do_store (
@@ -1516,6 +1568,8 @@ pub trait Handler: Send + Sync {
1516
1568
/// time supported, and should relinquish the processor.
1517
1569
fn sleep ( & self , milliseconds : u64 ) ;
1518
1570
1571
+ fn breakpoint ( & self ) { }
1572
+
1519
1573
fn handle_fatal_error ( & self , fatal_type : u8 , fatal_code : u32 , fatal_arg : u64 ) {
1520
1574
panic ! (
1521
1575
"Fatal error while executing AML (encountered DefFatalOp). fatal_type = {:?}, fatal_code = {:?}, fatal_arg = {:?}" ,
0 commit comments