diff --git a/aml/src/expression.rs b/aml/src/expression.rs index 888657a5..10a1083e 100644 --- a/aml/src/expression.rs +++ b/aml/src/expression.rs @@ -4,7 +4,7 @@ use crate::{ opcode::{self, opcode}, parser::{choice, comment_scope, n_of, take, take_to_end_of_pkglength, try_with_context, Parser, Propagate}, pkg_length::pkg_length, - term_object::{data_ref_object, term_arg}, + term_object::{data_ref_object, term_arg, def_cond_ref_of}, value::{AmlType, AmlValue, Args}, AmlError, DebugVerbosity, @@ -58,6 +58,7 @@ where def_shift_right(), def_store(), def_to_integer(), + def_cond_ref_of(), method_invocation() // XXX: this must always appear last. See how we have to parse it to see why. ), ) diff --git a/aml/src/lib.rs b/aml/src/lib.rs index 89b01f19..f2866ee0 100644 --- a/aml/src/lib.rs +++ b/aml/src/lib.rs @@ -796,6 +796,9 @@ pub enum AmlError { TypeCannotBeSliced(AmlType), TypeCannotBeWrittenToBufferField(AmlType), BufferFieldIndexesOutOfBounds, + + /// Unimplemented functionality - return error rather than abort + Unimplemented, } #[cfg(test)] diff --git a/aml/src/opcode.rs b/aml/src/opcode.rs index b5f1a6f1..55f57b1e 100644 --- a/aml/src/opcode.rs +++ b/aml/src/opcode.rs @@ -33,6 +33,7 @@ pub const DEF_CREATE_BYTE_FIELD_OP: u8 = 0x8c; pub const DEF_CREATE_BIT_FIELD_OP: u8 = 0x8d; pub const DEF_CREATE_QWORD_FIELD_OP: u8 = 0x8f; pub const EXT_DEF_MUTEX_OP: u8 = 0x01; +pub const EXT_DEF_COND_REF_OF_OP: u8 = 0x12; pub const EXT_DEF_CREATE_FIELD_OP: u8 = 0x13; pub const EXT_REVISION_OP: u8 = 0x30; pub const EXT_DEF_FATAL_OP: u8 = 0x32; diff --git a/aml/src/term_object.rs b/aml/src/term_object.rs index 4d5973b9..6178496c 100644 --- a/aml/src/term_object.rs +++ b/aml/src/term_object.rs @@ -1,7 +1,7 @@ use crate::{ expression::{def_buffer, def_package, expression_opcode}, misc::{arg_obj, local_obj}, - name_object::{name_seg, name_string}, + name_object::{name_seg, name_string, target, Target}, namespace::{AmlName, LevelType}, opcode::{self, ext_opcode, opcode}, parser::{ @@ -851,6 +851,32 @@ where .discard_result() } +pub fn def_cond_ref_of<'a, 'c>() -> impl Parser<'a, 'c, AmlValue> +where + 'c: 'a, +{ + /* + * DefCondRefOf := ExtOpPrefix 0x12 NameString Target => boolean + */ + ext_opcode(opcode::EXT_DEF_COND_REF_OF_OP) + .then(comment_scope( + DebugVerbosity::Scopes, + "DefCondRefOf", + name_string().then(target()).map_with_context(|(source, target), context| { + let handle = context.namespace.search(&source, &context.current_scope); + let result = AmlValue::Boolean(handle.is_ok()); + if let Ok((_name, _handle)) = handle { + match target { + Target::Null => { /* just return the result of the check */ } + _ => {return (Err(Propagate::Err(AmlError::Unimplemented)), context) }, + } + } + (Ok(result), context) + }), + )) + .map(|((), result)| Ok(result)) +} + pub fn term_arg<'a, 'c>() -> impl Parser<'a, 'c, AmlValue> where 'c: 'a,