@@ -384,6 +384,7 @@ where
384384 context. contribute_arg ( Argument :: Object ( Arc :: new ( Object :: Integer ( typ) ) ) ) ;
385385 }
386386 Opcode :: SizeOf => self . do_size_of ( & mut context, op) ?,
387+ Opcode :: Index => self . do_index ( & mut context, op) ?,
387388 Opcode :: BankField => {
388389 let [
389390 Argument :: TrackedPc ( start_pc) ,
@@ -826,7 +827,7 @@ where
826827 Opcode :: ConcatRes => todo ! ( ) ,
827828 Opcode :: Notify => todo ! ( ) ,
828829 Opcode :: SizeOf => context. start_in_flight_op ( OpInFlight :: new ( opcode, 1 ) ) ,
829- Opcode :: Index => todo ! ( ) ,
830+ Opcode :: Index => context . start_in_flight_op ( OpInFlight :: new ( opcode , 3 ) ) ,
830831 Opcode :: Match => todo ! ( ) ,
831832
832833 Opcode :: CreateBitField
@@ -1104,6 +1105,55 @@ where
11041105 context. contribute_arg ( Argument :: Object ( Arc :: new ( Object :: Integer ( result as u64 ) ) ) ) ;
11051106 Ok ( ( ) )
11061107 }
1108+
1109+ fn do_index ( & self , context : & mut MethodContext , op : OpInFlight ) -> Result < ( ) , AmlError > {
1110+ let [ Argument :: Object ( object) , Argument :: Object ( index_value) , target] = & op. arguments [ ..] else {
1111+ panic ! ( )
1112+ } ;
1113+ let Object :: Integer ( index_value) = * * index_value else {
1114+ Err ( AmlError :: ObjectNotOfExpectedType { expected : ObjectType :: Integer , got : index_value. typ ( ) } ) ?
1115+ } ;
1116+
1117+ let result = Arc :: new ( match * * object {
1118+ Object :: Buffer ( ref buffer) => {
1119+ if index_value as usize >= buffer. len ( ) {
1120+ Err ( AmlError :: IndexOutOfBounds ) ?
1121+ }
1122+
1123+ Object :: Reference {
1124+ kind : ReferenceKind :: RefOf ,
1125+ inner : Arc :: new ( Object :: BufferField {
1126+ buffer : object. clone ( ) ,
1127+ offset : index_value as usize * 8 ,
1128+ length : 8 ,
1129+ } ) ,
1130+ }
1131+ }
1132+ Object :: String ( ref string) => {
1133+ if index_value as usize >= string. len ( ) {
1134+ Err ( AmlError :: IndexOutOfBounds ) ?
1135+ }
1136+
1137+ Object :: Reference {
1138+ kind : ReferenceKind :: RefOf ,
1139+ inner : Arc :: new ( Object :: BufferField {
1140+ buffer : object. clone ( ) ,
1141+ offset : index_value as usize * 8 ,
1142+ length : 8 ,
1143+ } ) ,
1144+ }
1145+ }
1146+ Object :: Package ( ref package) => {
1147+ let Some ( element) = package. get ( index_value as usize ) else { Err ( AmlError :: IndexOutOfBounds ) ? } ;
1148+ Object :: Reference { kind : ReferenceKind :: RefOf , inner : element. clone ( ) }
1149+ }
1150+ _ => Err ( AmlError :: IndexOutOfBounds ) ?,
1151+ } ) ;
1152+
1153+ self . do_store ( context, target, result. clone ( ) ) ?;
1154+ context. contribute_arg ( Argument :: Object ( result) ) ;
1155+ Ok ( ( ) )
1156+ }
11071157 fn do_store (
11081158 & self ,
11091159 context : & mut MethodContext ,
@@ -1703,6 +1753,8 @@ pub enum AmlError {
17031753 MethodArgCountIncorrect ,
17041754
17051755 InvalidOperationOnObject ,
1756+ IndexOutOfBounds ,
1757+ ObjectNotOfExpectedType { expected : ObjectType , got : ObjectType } ,
17061758
17071759 InvalidResourceDescriptor ,
17081760 UnexpectedResourceType ,
0 commit comments