浏览代码

Store DefNames transparently in namespace

It turns out we never need to be able to tell that a object is defined as
a name, so we can just store them transparently in the namespace. This
simplifies a few bits of code and also saves up a heap allocation for every
name.
Isaac Woods 4 年之前
父节点
当前提交
3b08721981
共有 4 个文件被更改,包括 15 次插入25 次删除
  1. 3 6
      aml/src/pci_routing.rs
  2. 1 5
      aml/src/term_object.rs
  3. 11 12
      aml/src/type2.rs
  4. 0 2
      aml/src/value.rs

+ 3 - 6
aml/src/pci_routing.rs

@@ -171,12 +171,9 @@ impl PciRoutingTable {
                 let link_crs =
                     context.namespace.get_by_path(&AmlName::from_str("_CRS").unwrap().resolve(name)?)?;
 
-                match link_crs {
-                    AmlValue::Name(ref boxed_object) => match resource::resource_descriptor(boxed_object)? {
-                        Resource::Irq(descriptor) => Ok(descriptor),
-                        _ => Err(AmlError::IncompatibleValueConversion),
-                    },
-                    _ => return Err(AmlError::IncompatibleValueConversion),
+                match resource::resource_descriptor(link_crs)? {
+                    Resource::Irq(descriptor) => Ok(descriptor),
+                    obj => Err(AmlError::IncompatibleValueConversion),
                 }
             }
         }

+ 1 - 5
aml/src/term_object.rs

@@ -109,11 +109,7 @@ where
             name_string().then(data_ref_object()).map_with_context(|(name, data_ref_object), context| {
                 try_with_context!(
                     context,
-                    context.namespace.add_at_resolved_path(
-                        name,
-                        &context.current_scope,
-                        AmlValue::Name(box data_ref_object)
-                    )
+                    context.namespace.add_at_resolved_path(name, &context.current_scope, data_ref_object,)
                 );
                 (Ok(()), context)
             }),

+ 11 - 12
aml/src/type2.rs

@@ -143,8 +143,7 @@ where
                     let desired_type = context.namespace.get(handle).unwrap().type_of();
                     let converted_object = try_with_context!(context, value.as_type(desired_type));
 
-                    *try_with_context!(context, context.namespace.get_mut(handle)) =
-                        AmlValue::Name(box converted_object);
+                    *try_with_context!(context, context.namespace.get_mut(handle)) = converted_object;
                     (Ok(context.namespace.get(handle).unwrap().clone()), context)
                 }
 
@@ -174,15 +173,11 @@ where
     /*
      * MethodInvocation := NameString TermArgList
      *
-     * MethodInvocation is the worst of the AML structures, because you're meant to figure out how
-     * much you're meant to parse using the name of the method (by knowing from its definition how
-     * how many arguments it takes). However, the definition of a method can in theory appear after
-     * an invocation of that method, and so parsing them properly can be very difficult.
+     * MethodInvocation is the worst of the AML structures, because you're meant to figure out how much you're
+     * meant to parse using the name of the method (by knowing from its definition how how many arguments it
+     * takes). However, the definition of a method can in theory appear after an invocation of that method, and
+     * so parsing them properly can be very difficult.
      * NOTE: We don't support the case of the definition appearing after the invocation.
-     *
-     * It's also not clear whether things that aren't methods can be "invoked" using
-     * MethodInvocation with 0 arguments. It seems that references to DefNames can be encoded using
-     * MethodInvocation, at least, and should just be looked up.
      */
     comment_scope_verbose(
         "MethodInvocation",
@@ -196,8 +191,6 @@ where
                 id().map_with_context(move |(), context| {
                     let object = try_with_context!(context, context.namespace.get(handle));
                     match object.clone() {
-                        AmlValue::Name(boxed_value) => (Ok(unbox(boxed_value)), context),
-
                         AmlValue::Method { ref code, .. } => {
                             // TODO: before we do this, we need to restructure the structures to allow us
                             // to execute control methods from inside other control methods
@@ -205,6 +198,12 @@ where
                             unimplemented!()
                         }
 
+                        // We appear to be seeing AML where a MethodInvocation actually doesn't point to a method
+                        // at all, which isn't mentioned in the spec afaict.  However, if we treat it as an
+                        // "invocation" with 0 arguments and simply return the object, the AML seems to do sensible
+                        // things.
+                        object => (Ok(object), context),
+
                         _ => (Err(AmlError::IncompatibleValueConversion), context),
                     }
                 })

+ 0 - 2
aml/src/value.rs

@@ -120,7 +120,6 @@ pub enum AmlValue {
     Boolean(bool),
     Integer(u64),
     String(String),
-    Name(Box<AmlValue>),
     OpRegion { region: RegionSpace, offset: u64, length: u64 },
     Field { region: AmlName, flags: FieldFlags, offset: u64, length: u64 },
     Device,
@@ -138,7 +137,6 @@ impl AmlValue {
             AmlValue::Boolean(_) => AmlType::Integer,
             AmlValue::Integer(_) => AmlType::Integer,
             AmlValue::String(_) => AmlType::String,
-            AmlValue::Name(boxed_value) => boxed_value.type_of(),
             AmlValue::OpRegion { .. } => AmlType::OpRegion,
             AmlValue::Field { .. } => AmlType::FieldUnit,
             AmlValue::Device => AmlType::Device,