Browse Source

Make `read_field` and friends take a mutable context

This is necessary because these methods will need to invoke methods in
the future.

Co-authored-by: Ron Williams <ron.williams.redox@gmail.com>
Isaac Woods 1 year ago
parent
commit
20865883e0
4 changed files with 25 additions and 13 deletions
  1. 8 2
      aml/src/expression.rs
  2. 10 4
      aml/src/lib.rs
  3. 2 2
      aml/src/statement.rs
  4. 5 5
      aml/src/value.rs

+ 8 - 2
aml/src/expression.rs

@@ -331,7 +331,10 @@ where
             DebugVerbosity::AllScopes,
             "DefIncrement",
             super_name().map_with_context(|addend, context| {
-                let value = try_with_context!(context, context.read_target(&addend));
+                let value = {
+                    let value = try_with_context!(context, context.read_target(&addend));
+                    value.clone()
+                };
                 let value = try_with_context!(context, value.as_integer(context));
                 let new_value = AmlValue::Integer(value + 1);
                 try_with_context!(context, context.store(addend, new_value.clone()));
@@ -353,7 +356,10 @@ where
             DebugVerbosity::AllScopes,
             "DefDecrement",
             super_name().map_with_context(|minuend, context| {
-                let value = try_with_context!(context, context.read_target(&minuend));
+                let value = {
+                    let value = try_with_context!(context, context.read_target(&minuend));
+                    value.clone()
+                };
                 let value = try_with_context!(context, value.as_integer(context));
                 let new_value = AmlValue::Integer(value - 1);
                 try_with_context!(context, context.store(minuend, new_value.clone()));

+ 10 - 4
aml/src/lib.rs

@@ -389,14 +389,19 @@ impl AmlContext {
 
     /// Read from an operation-region, performing only standard-sized reads (supported powers-of-2 only. If a field
     /// is not one of these sizes, it may need to be masked, or multiple reads may need to be performed).
-    pub(crate) fn read_region(&self, region_handle: AmlHandle, offset: u64, length: u64) -> Result<u64, AmlError> {
+    pub(crate) fn read_region(
+        &mut self,
+        region_handle: AmlHandle,
+        offset: u64,
+        length: u64,
+    ) -> Result<u64, AmlError> {
         use bit_field::BitField;
         use core::convert::TryInto;
         use value::RegionSpace;
 
         let (region_space, region_base, _region_length, parent_device) = {
             if let AmlValue::OpRegion { region, offset, length, parent_device } =
-                self.namespace.get(region_handle)?
+                self.namespace.get(region_handle)?.clone()
             {
                 (region, offset, length, parent_device)
             } else {
@@ -488,7 +493,7 @@ impl AmlContext {
 
         let (region_space, region_base, _region_length, parent_device) = {
             if let AmlValue::OpRegion { region, offset, length, parent_device } =
-                self.namespace.get(region_handle)?
+                self.namespace.get(region_handle)?.clone()
             {
                 (region, offset, length, parent_device)
             } else {
@@ -605,7 +610,8 @@ impl AmlContext {
             .add_value(
                 AmlName::from_str("\\_OSI").unwrap(),
                 AmlValue::native_method(1, false, 0, |context| {
-                    Ok(match context.current_arg(0)?.as_string(context)?.as_str() {
+                    let value = context.current_arg(0)?.clone();
+                    Ok(match value.as_string(context)?.as_str() {
                         "Windows 2000" => true,       // 2000
                         "Windows 2001" => true,       // XP
                         "Windows 2001 SP1" => true,   // XP SP1

+ 2 - 2
aml/src/statement.rs

@@ -224,7 +224,7 @@ where
             DebugVerbosity::Scopes,
             "DefSleep",
             term_arg().map_with_context(|milliseconds, context| {
-                let milliseconds = try_with_context!(context, milliseconds.as_integer(&context));
+                let milliseconds = try_with_context!(context, milliseconds.as_integer(context));
                 context.handler.sleep(milliseconds);
                 (Ok(()), context)
             }),
@@ -245,7 +245,7 @@ where
             DebugVerbosity::Scopes,
             "DefStall",
             term_arg().map_with_context(|microseconds, context| {
-                let microseconds = try_with_context!(context, microseconds.as_integer(&context));
+                let microseconds = try_with_context!(context, microseconds.as_integer(context));
                 context.handler.stall(microseconds);
                 (Ok(()), context)
             }),

+ 5 - 5
aml/src/value.rs

@@ -288,7 +288,7 @@ impl AmlValue {
         }
     }
 
-    pub fn as_integer(&self, context: &AmlContext) -> Result<u64, AmlError> {
+    pub fn as_integer(&self, context: &mut AmlContext) -> Result<u64, AmlError> {
         match self {
             AmlValue::Integer(value) => Ok(*value),
             AmlValue::Boolean(value) => Ok(if *value { u64::max_value() } else { 0 }),
@@ -320,7 +320,7 @@ impl AmlValue {
         }
     }
 
-    pub fn as_buffer(&self, context: &AmlContext) -> Result<Arc<Spinlock<Vec<u8>>>, AmlError> {
+    pub fn as_buffer(&self, context: &mut AmlContext) -> Result<Arc<Spinlock<Vec<u8>>>, AmlError> {
         match self {
             AmlValue::Buffer(ref bytes) => Ok(bytes.clone()),
             // TODO: implement conversion of String and Integer to Buffer
@@ -330,7 +330,7 @@ impl AmlValue {
         }
     }
 
-    pub fn as_string(&self, context: &AmlContext) -> Result<String, AmlError> {
+    pub fn as_string(&self, context: &mut AmlContext) -> Result<String, AmlError> {
         match self {
             AmlValue::String(ref string) => Ok(string.clone()),
             // TODO: implement conversion of Buffer to String
@@ -404,7 +404,7 @@ impl AmlValue {
     ///     `Integer` from: `Buffer`, `BufferField`, `DdbHandle`, `FieldUnit`, `String`, `Debug`
     ///     `Package` from: `Debug`
     ///     `String` from: `Integer`, `Buffer`, `Debug`
-    pub fn as_type(&self, desired_type: AmlType, context: &AmlContext) -> Result<AmlValue, AmlError> {
+    pub fn as_type(&self, desired_type: AmlType, context: &mut AmlContext) -> Result<AmlValue, AmlError> {
         // If the value is already of the correct type, just return it as is
         if self.type_of() == desired_type {
             return Ok(self.clone());
@@ -423,7 +423,7 @@ impl AmlValue {
 
     /// Reads from a field of an opregion, returning either a `AmlValue::Integer` or an `AmlValue::Buffer`,
     /// depending on the size of the field.
-    pub fn read_field(&self, context: &AmlContext) -> Result<AmlValue, AmlError> {
+    pub fn read_field(&self, context: &mut AmlContext) -> Result<AmlValue, AmlError> {
         if let AmlValue::Field { region, flags, offset, length } = self {
             let _maximum_access_size = {
                 if let AmlValue::OpRegion { region, .. } = context.namespace.get(*region)? {