From 60edb9da68a16ea947ee1fb07a58da8c7669fe6a Mon Sep 17 00:00:00 2001 From: Connor Wood <connorwood71@gmail.com> Date: Tue, 29 Aug 2017 10:11:01 +0100 Subject: [PATCH] Implemented type checking and coersion upon store --- src/acpi/aml/namespace.rs | 38 +++++++++++++++++++++++++++++++++++++- src/acpi/aml/parser.rs | 14 ++++++++++++-- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/acpi/aml/namespace.rs b/src/acpi/aml/namespace.rs index 3dcdb250..64ebb058 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 7ef78e79..3b382d41 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) -- GitLab