Explorar o código

Search for opregion during parse of DefField

Since we already have the correct scope to search for the OpRegion that a
DefField is referring to, we can simply do the search during the parse and
record the handle to the OpRegion. This simplifies field lookups later on,
and should also actually make the FieldUnit representation smaller.
Isaac Woods %!s(int64=4) %!d(string=hai) anos
pai
achega
26a0fb1708
Modificáronse 2 ficheiros con 17 adicións e 6 borrados
  1. 15 4
      aml/src/term_object.rs
  2. 2 2
      aml/src/value.rs

+ 15 - 4
aml/src/term_object.rs

@@ -22,6 +22,7 @@ use crate::{
     value::{AmlValue, FieldFlags, MethodFlags, RegionSpace},
     AmlContext,
     AmlError,
+    AmlHandle,
     DebugVerbosity,
 };
 use alloc::string::String;
@@ -233,11 +234,21 @@ where
      * DefField = ExtOpPrefix 0x81 PkgLength NameString FieldFlags FieldList
      * FieldFlags := ByteData
      */
+    let opregion_as_handle = name_string().map_with_context(|region_name, context| {
+        /*
+         * We search for the opregion that this field is referencing here as we already have the correct starting
+         * scope. If we leave this to later, it becomes much harder as we also need to know the field's scope.
+         */
+        let (_, handle) =
+            try_with_context!(context, context.namespace.search(&region_name, &context.current_scope));
+        (Ok(handle), context)
+    });
+
     ext_opcode(opcode::EXT_DEF_FIELD_OP)
         .then(comment_scope(
             DebugVerbosity::Scopes,
             "DefField",
-            pkg_length().then(name_string()).then(take()).feed(|((list_length, region_name), flags)| {
+            pkg_length().then(opregion_as_handle).then(take()).feed(|((list_length, region_handle), flags)| {
                 move |mut input: &'a [u8], mut context: &'c mut AmlContext| -> ParseResult<'a, 'c, ()> {
                     /*
                      * FieldList := Nothing | <FieldElement FieldList>
@@ -246,7 +257,7 @@ where
                     let mut current_offset = 0;
                     while list_length.still_parsing(input) {
                         let (new_input, new_context, field_length) =
-                            field_element(region_name.clone(), FieldFlags::new(flags), current_offset)
+                            field_element(region_handle, FieldFlags::new(flags), current_offset)
                                 .parse(input, context)?;
                         input = new_input;
                         context = new_context;
@@ -263,7 +274,7 @@ where
 /// Parses a `FieldElement`. Takes the current offset within the field list, and returns the length
 /// of the field element parsed.
 pub fn field_element<'a, 'c>(
-    region_name: AmlName,
+    region_handle: AmlHandle,
     flags: FieldFlags,
     current_offset: u64,
 ) -> impl Parser<'a, 'c, u64>
@@ -308,7 +319,7 @@ where
                 AmlName::from_name_seg(name_seg),
                 &context.current_scope,
                 AmlValue::Field {
-                    region: region_name.clone(),
+                    region: region_handle,
                     flags,
                     offset: current_offset,
                     length: length.raw_length as u64,

+ 2 - 2
aml/src/value.rs

@@ -1,4 +1,4 @@
-use crate::{misc::ArgNum, namespace::AmlName, AmlError};
+use crate::{misc::ArgNum, AmlContext, AmlError, AmlHandle};
 use alloc::{string::String, vec::Vec};
 use bit_field::BitField;
 
@@ -146,7 +146,7 @@ pub enum AmlValue {
     Integer(u64),
     String(String),
     OpRegion { region: RegionSpace, offset: u64, length: u64 },
-    Field { region: AmlName, flags: FieldFlags, offset: u64, length: u64 },
+    Field { region: AmlHandle, flags: FieldFlags, offset: u64, length: u64 },
     Method { flags: MethodFlags, code: Vec<u8> },
     Buffer { bytes: Vec<u8>, size: u64 },
     Processor { id: u8, pblk_address: u32, pblk_len: u8 },