@@ -191,6 +191,27 @@ where
191191 self . do_logical_op ( & mut context, op) ?;
192192 }
193193 Opcode :: Mid => self . do_mid ( & mut context, op) ?,
194+ Opcode :: Concat => self . do_concat ( & mut context, op) ?,
195+ Opcode :: ConcatRes => {
196+ let [ Argument :: Object ( source1) , Argument :: Object ( source2) , target] = & op. arguments [ ..]
197+ else {
198+ panic ! ( )
199+ } ;
200+ let source1 = source1. as_buffer ( ) ?;
201+ let source2 = source2. as_buffer ( ) ?;
202+ let result = {
203+ let mut buffer = Vec :: from ( source1) ;
204+ buffer. extend_from_slice ( source2) ;
205+ // Add a new end-tag
206+ buffer. push ( 0x78 ) ;
207+ // Don't calculate the new real checksum - just use 0
208+ buffer. push ( 0x00 ) ;
209+ Arc :: new ( Object :: Buffer ( buffer) )
210+ } ;
211+ // TODO: use potentially-updated result for return value here
212+ self . do_store ( & mut context, target, result. clone ( ) ) ?;
213+ context. contribute_arg ( Argument :: Object ( result) ) ;
214+ }
194215 Opcode :: FromBCD => self . do_from_bcd ( & mut context, op) ?,
195216 Opcode :: ToBCD => self . do_to_bcd ( & mut context, op) ?,
196217 Opcode :: Name => {
@@ -914,8 +935,8 @@ where
914935 context. start_in_flight_op ( OpInFlight :: new ( opcode, 2 ) )
915936 }
916937 Opcode :: DerefOf => todo ! ( ) ,
917- Opcode :: ConcatRes => todo ! ( ) ,
918938 Opcode :: Notify => todo ! ( ) ,
939+ Opcode :: ConcatRes => context. start_in_flight_op ( OpInFlight :: new ( opcode, 3 ) ) ,
919940 Opcode :: SizeOf => context. start_in_flight_op ( OpInFlight :: new ( opcode, 1 ) ) ,
920941 Opcode :: Index => context. start_in_flight_op ( OpInFlight :: new ( opcode, 3 ) ) ,
921942 Opcode :: Match => todo ! ( ) ,
@@ -1263,6 +1284,62 @@ where
12631284 Ok ( ( ) )
12641285 }
12651286
1287+ fn do_concat( & self , context: & mut MethodContext , op: OpInFlight ) -> Result <( ) , AmlError > {
1288+ let [ Argument :: Object ( source1) , Argument :: Object ( source2) , target] = & op. arguments [ ..] else { panic ! ( ) } ;
1289+ fn resolve_as_string ( obj : & Object ) -> String {
1290+ match obj {
1291+ Object :: Uninitialized => "[Uninitialized Object]" . to_string ( ) ,
1292+ Object :: Buffer ( bytes) => String :: from_utf8_lossy ( & bytes) . into_owned ( ) ,
1293+ Object :: BufferField { .. } => "[Buffer Field]" . to_string ( ) ,
1294+ Object :: Device => "[Device]" . to_string ( ) ,
1295+ Object :: Event => "[Event]" . to_string ( ) ,
1296+ Object :: FieldUnit ( _) => "[Field]" . to_string ( ) ,
1297+ Object :: Integer ( value) => value. to_string ( ) ,
1298+ Object :: Method { .. } => "[Control Method]" . to_string ( ) ,
1299+ Object :: Mutex { .. } => "[Mutex]" . to_string ( ) ,
1300+ Object :: Reference { inner, .. } => resolve_as_string ( & * ( inner. clone ( ) . unwrap_reference ( ) ) ) ,
1301+ Object :: OpRegion ( _) => "[Operation Region]" . to_string ( ) ,
1302+ Object :: Package ( _) => "[Package]" . to_string ( ) ,
1303+ Object :: PowerResource { .. } => "[Power Resource]" . to_string ( ) ,
1304+ Object :: Processor { .. } => "[Processor]" . to_string ( ) ,
1305+ // TODO: what even is one of these??
1306+ Object :: RawDataBuffer => todo ! ( ) ,
1307+ Object :: String ( value) => value. clone ( ) ,
1308+ Object :: ThermalZone => "[Thermal Zone]" . to_string ( ) ,
1309+ Object :: Debug => "[Debug Object]" . to_string ( ) ,
1310+ }
1311+ }
1312+ let result = match source1. typ ( ) {
1313+ ObjectType :: Integer => {
1314+ let source1 = source1. as_integer ( ) ?;
1315+ let source2 = source2. to_integer ( if self . dsdt_revision >= 2 { 8 } else { 4 } ) ?;
1316+ let mut buffer = Vec :: new ( ) ;
1317+ if self . dsdt_revision >= 2 {
1318+ buffer. extend_from_slice ( & source1. to_le_bytes ( ) ) ;
1319+ buffer. extend_from_slice ( & source2. to_le_bytes ( ) ) ;
1320+ } else {
1321+ buffer. extend_from_slice ( & ( source1 as u32 ) . to_le_bytes ( ) ) ;
1322+ buffer. extend_from_slice ( & ( source2 as u32 ) . to_le_bytes ( ) ) ;
1323+ }
1324+ Arc :: new ( Object :: Buffer ( buffer) )
1325+ }
1326+ ObjectType :: Buffer => {
1327+ let mut buffer = source1. as_buffer ( ) ?. to_vec ( ) ;
1328+ buffer. extend ( source2. to_buffer ( if self . dsdt_revision >= 2 { 8 } else { 4 } ) ?) ;
1329+ Arc :: new ( Object :: Buffer ( buffer) )
1330+ }
1331+ ObjectType :: String | _ => {
1332+ let source1 = resolve_as_string ( & source1) ;
1333+ let source2 = resolve_as_string ( & source2) ;
1334+ Arc :: new ( Object :: String ( source1 + & source2) )
1335+ }
1336+ } ;
1337+ // TODO: use result of store
1338+ self . do_store ( context, target, result. clone ( ) ) ?;
1339+ context. contribute_arg ( Argument :: Object ( result) ) ;
1340+ Ok ( ( ) )
1341+ }
1342+
12661343 fn do_from_bcd( & self , context: & mut MethodContext , op: OpInFlight ) -> Result <( ) , AmlError > {
12671344 let [ Argument :: Object ( value) ] = & op. arguments [ ..] else { Err ( AmlError :: InvalidOperationOnObject ) ? } ;
12681345 let mut value = value. clone ( ) . unwrap_transparent_reference ( ) . as_integer ( ) ?;
0 commit comments