@@ -191,6 +191,27 @@ where
191
191
self . do_logical_op ( & mut context, op) ?;
192
192
}
193
193
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
+ }
194
215
Opcode :: FromBCD => self . do_from_bcd ( & mut context, op) ?,
195
216
Opcode :: ToBCD => self . do_to_bcd ( & mut context, op) ?,
196
217
Opcode :: Name => {
@@ -914,8 +935,8 @@ where
914
935
context. start_in_flight_op ( OpInFlight :: new ( opcode, 2 ) )
915
936
}
916
937
Opcode :: DerefOf => todo ! ( ) ,
917
- Opcode :: ConcatRes => todo ! ( ) ,
918
938
Opcode :: Notify => todo ! ( ) ,
939
+ Opcode :: ConcatRes => context. start_in_flight_op ( OpInFlight :: new ( opcode, 3 ) ) ,
919
940
Opcode :: SizeOf => context. start_in_flight_op ( OpInFlight :: new ( opcode, 1 ) ) ,
920
941
Opcode :: Index => context. start_in_flight_op ( OpInFlight :: new ( opcode, 3 ) ) ,
921
942
Opcode :: Match => todo ! ( ) ,
@@ -1263,6 +1284,62 @@ where
1263
1284
Ok ( ( ) )
1264
1285
}
1265
1286
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
+
1266
1343
fn do_from_bcd( & self , context: & mut MethodContext , op: OpInFlight ) -> Result <( ) , AmlError > {
1267
1344
let [ Argument :: Object ( value) ] = & op. arguments [ ..] else { Err ( AmlError :: InvalidOperationOnObject ) ? } ;
1268
1345
let mut value = value. clone ( ) . unwrap_transparent_reference ( ) . as_integer ( ) ?;
0 commit comments