Browse Source

Rewrite search to pass back a handle & give better errors

This allows us to use the same search code for both getting a shared and
a mutable reference to an object, and actually makes the parser for dealing
with a MethodInvocation a bit cleaner and more efficient.
Isaac Woods 5 years ago
parent
commit
c7b96865f3
2 changed files with 17 additions and 12 deletions
  1. 9 5
      aml_parser/src/namespace.rs
  2. 8 7
      aml_parser/src/type2.rs

+ 9 - 5
aml_parser/src/namespace.rs

@@ -88,8 +88,9 @@ impl Namespace {
     }
 
     /// Search for an object at the given path of the namespace, applying the search rules
-    /// described in §5.3 of the ACPI specification, if they are applicable.
-    pub fn search(&self, path: &AmlName, starting_scope: &AmlName) -> Result<&AmlValue, AmlError> {
+    /// described in §5.3 of the ACPI specification, if they are applicable. Returns the handle of
+    /// the first valid object, if found.
+    pub fn search(&self, path: &AmlName, starting_scope: &AmlName) -> Result<AmlHandle, AmlError> {
         if path.search_rules_apply() {
             /*
              * If search rules apply, we need to recursively look through the namespace. If the
@@ -100,8 +101,8 @@ impl Namespace {
             assert!(scope.is_absolute());
             loop {
                 // Search for the name at this namespace level. If we find it, we're done.
-                if let Ok(value) = self.get_by_path(&path.resolve(&scope).unwrap()) {
-                    return Ok(value);
+                if let Some(handle) = self.name_map.get(&path.resolve(&scope)?) {
+                    return Ok(*handle);
                 }
 
                 // If we don't find it, go up a level in the namespace and search for it there,
@@ -117,7 +118,10 @@ impl Namespace {
             }
         } else {
             // If search rules don't apply, simply resolve it against the starting scope
-            self.get_by_path(&path.resolve(starting_scope)?)
+            self.name_map
+                .get(&path.resolve(starting_scope)?)
+                .map(|&handle| handle)
+                .ok_or(AmlError::ObjectDoesNotExist(path.as_string()))
         }
     }
 }

+ 8 - 7
aml_parser/src/type2.rs

@@ -66,15 +66,16 @@ where
         "MethodInvocation",
         name_string()
             .map_with_context(move |name, context| {
-                let object =
+                let handle =
                     try_with_context!(context, context.namespace.search(&name, &context.current_scope))
                         .clone();
-                (Ok(object), context)
+                (Ok(handle), context)
             })
-            .feed(|object| {
-                move |input: &'a [u8], context| -> ParseResult<'a, 'c, AmlValue> {
+            .feed(|handle| {
+                id().map_with_context(move |(), context| {
+                    let object = try_with_context!(context, context.namespace.get(handle));
                     match object.clone() {
-                        AmlValue::Name(boxed_value) => Ok((input, context, unbox(boxed_value))),
+                        AmlValue::Name(boxed_value) => (Ok(unbox(boxed_value)), context),
 
                         AmlValue::Method { flags, ref code } => {
                             // TODO: before we do this, we need to restructure the structures to allow us
@@ -83,9 +84,9 @@ where
                             unimplemented!()
                         }
 
-                        _ => Err((input, context, AmlError::IncompatibleValueConversion)),
+                        _ => (Err(AmlError::IncompatibleValueConversion), context),
                     }
-                }
+                })
             }),
     )
 }