diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index 3dcdb2503a4a28a07f3ede5f86dfaf579a410584..64ebb058cf4b64fe3b199581fc751feb8735fb84 100644 --- a/src/acpi/aml/namespace.rs +++ b/src/acpi/aml/namespace.rs @@ -123,7 +123,43 @@ impl Debug for AmlValue { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { Ok(()) } } -impl AmlValue { +impl AmlValue { + pub fn get_as_type(&self, t: AmlValue) -> Result<AmlValue, AmlError> { + match t { + AmlValue::None => Ok(AmlValue::None), + AmlValue::Uninitialized => Ok(self.clone()), + AmlValue::Alias(_) => match *self { + AmlValue::Alias(_) => Ok(self.clone()), + _ => Err(AmlError::AmlValueError) + }, + AmlValue::Buffer(_) => Ok(AmlValue::Buffer(self.get_as_buffer()?)), + AmlValue::BufferField(_) => Ok(AmlValue::BufferField(self.get_as_buffer_field()?)), + AmlValue::DDBHandle(_) => Ok(AmlValue::DDBHandle(self.get_as_ddb_handle()?)), + AmlValue::DebugObject => match *self { + AmlValue::DebugObject => Ok(self.clone()), + _ => Err(AmlError::AmlValueError) + }, + AmlValue::Device(_) => Ok(AmlValue::Device(self.get_as_device()?)), + AmlValue::Event(_) => Ok(AmlValue::Event(self.get_as_event()?)), + AmlValue::FieldUnit(_) => Ok(AmlValue::FieldUnit(self.get_as_field_unit()?)), + AmlValue::Integer(_) => Ok(AmlValue::Integer(self.get_as_integer()?)), + AmlValue::IntegerConstant(_) => Ok(AmlValue::IntegerConstant(self.get_as_integer_constant()?)), + AmlValue::Method(_) => Ok(AmlValue::Method(self.get_as_method()?)), + AmlValue::Mutex(_) => Ok(AmlValue::Mutex(self.get_as_mutex()?)), + AmlValue::ObjectReference(_) => Ok(AmlValue::ObjectReference(self.get_as_object_reference()?)), + AmlValue::OperationRegion(_) => match *self { + AmlValue::OperationRegion(_) => Ok(self.clone()), + _ => Err(AmlError::AmlValueError) + }, + AmlValue::Package(_) => Ok(AmlValue::Package(self.get_as_package()?)), + AmlValue::String(_) => Ok(AmlValue::String(self.get_as_string()?)), + AmlValue::PowerResource(_) => Ok(AmlValue::PowerResource(self.get_as_power_resource()?)), + AmlValue::Processor(_) => Ok(AmlValue::Processor(self.get_as_processor()?)), + AmlValue::RawDataBuffer(_) => Ok(AmlValue::RawDataBuffer(self.get_as_raw_data_buffer()?)), + AmlValue::ThermalZone(_) => Ok(AmlValue::ThermalZone(self.get_as_thermal_zone()?)) + } + } + pub fn get_as_buffer(&self) -> Result<Vec<u8>, AmlError> { match *self { AmlValue::Buffer(ref b) => Ok(b.clone()), diff --git a/src/acpi/aml/parser.rs b/src/acpi/aml/parser.rs index 7ef78e79f8abe0552c7a1084c5e7a66b75382783..3b382d414cab3e127dad34ff2138a06d1cd8c570 100644 --- a/src/acpi/aml/parser.rs +++ b/src/acpi/aml/parser.rs @@ -285,13 +285,23 @@ impl AmlExecutionContext { } fn modify_local_obj(&mut self, local: usize, value: AmlValue) -> Result<(), AmlError> { - self.local_vars[local] = value; + self.local_vars[local] = value.get_as_type(self.local_vars[local].clone())?; Ok(()) } fn modify_object(&mut self, name: String, value: AmlValue) -> Result<(), AmlError> { if let Some(ref mut namespace) = *ACPI_TABLE.namespace.write() { - namespace.insert(name, value); + let coercion_obj = { + let obj = namespace.get(&name); + + if let Some(o) = obj { + o.clone() + } else { + AmlValue::Uninitialized + } + }; + + namespace.insert(name, value.get_as_type(coercion_obj)?); Ok(()) } else { Err(AmlError::AmlHardFatal)