Parcourir la source

Switch from features to proper runtime debug verbosity for parser output

WARNING: this breaks semver compatibility and so will need a new major
version.
Isaac Woods il y a 4 ans
Parent
commit
44e7781ea0
7 fichiers modifiés avec 97 ajouts et 67 suppressions
  1. 24 4
      aml/src/lib.rs
  2. 8 4
      aml/src/misc.rs
  3. 10 4
      aml/src/name_object.rs
  4. 14 27
      aml/src/parser.rs
  5. 19 7
      aml/src/term_object.rs
  6. 8 4
      aml/src/type1.rs
  7. 14 17
      aml/src/type2.rs

+ 24 - 4
aml/src/lib.rs

@@ -60,7 +60,6 @@ pub use crate::{
     value::AmlValue,
 };
 
-use alloc::string::String;
 use log::error;
 use misc::{ArgNum, LocalNum};
 use parser::Parser;
@@ -72,10 +71,23 @@ use value::Args;
 /// what this is actually used for, but this is ours.
 pub const AML_INTERPRETER_REVISION: u64 = 0;
 
+/// Describes how much debug information the parser should emit. Set the "maximum" expected verbosity in
+/// the context's `debug_verbosity` - everything will be printed that is less or equal in 'verbosity'.
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
+pub enum DebugVerbosity {
+    /// Print no debug information
+    None,
+    /// Print heads and tails when entering and leaving scopes of major objects, but not more minor ones.
+    Scopes,
+    /// Print heads and tails when entering and leaving scopes of all objects.
+    AllScopes,
+    /// Print heads and tails of all objects, and extra debug information as it's parsed.
+    All,
+}
+
 #[derive(Debug)]
 pub struct AmlContext {
     pub namespace: Namespace,
-    current_scope: AmlName,
 
     /*
      * AML local variables. These are used when we invoke a control method. A `None` value
@@ -93,13 +105,18 @@ pub struct AmlContext {
     /// If we're currently invoking a control method, this stores the arguments that were passed to
     /// it. It's `None` if we aren't invoking a method.
     current_args: Option<Args>,
+
+    /*
+     * These track the state of the context while it's parsing an AML table.
+     */
+    current_scope: AmlName,
+    debug_verbosity: DebugVerbosity,
 }
 
 impl AmlContext {
-    pub fn new() -> AmlContext {
+    pub fn new(debug_verbosity: DebugVerbosity) -> AmlContext {
         AmlContext {
             namespace: Namespace::new(),
-            current_scope: AmlName::root(),
             local_0: None,
             local_1: None,
             local_2: None,
@@ -109,6 +126,9 @@ impl AmlContext {
             local_6: None,
             local_7: None,
             current_args: None,
+
+            current_scope: AmlName::root(),
+            debug_verbosity,
         }
     }
 

+ 8 - 4
aml/src/misc.rs

@@ -1,6 +1,7 @@
 use crate::{
     opcode::{self, ext_opcode, opcode},
-    parser::{choice, comment_scope_verbose, id, Parser},
+    parser::{choice, comment_scope, id, Parser},
+    DebugVerbosity,
 };
 
 pub fn debug_obj<'a, 'c>() -> impl Parser<'a, 'c, ()>
@@ -32,7 +33,9 @@ where
      * Local7Op := 0x67
      */
     let local_parser = |i, local_opcode| {
-        opcode(local_opcode).then(comment_scope_verbose("LocalObj", id())).map(move |((), _)| Ok(i))
+        opcode(local_opcode)
+            .then(comment_scope(DebugVerbosity::AllScopes, "LocalObj", id()))
+            .map(move |((), _)| Ok(i))
     };
 
     choice!(
@@ -64,8 +67,9 @@ where
      * Arg5Op = 0x6d
      * Arg6Op = 0x6e
      */
-    let arg_parser =
-        |i, arg_opcode| opcode(arg_opcode).then(comment_scope_verbose("ArgObj", id())).map(move |((), _)| Ok(i));
+    let arg_parser = |i, arg_opcode| {
+        opcode(arg_opcode).then(comment_scope(DebugVerbosity::AllScopes, "ArgObj", id())).map(move |((), _)| Ok(i))
+    };
 
     choice!(
         arg_parser(0, opcode::ARG0_OP),

+ 10 - 4
aml/src/name_object.rs

@@ -2,9 +2,10 @@ use crate::{
     misc::{arg_obj, debug_obj, local_obj, ArgNum, LocalNum},
     namespace::{AmlName, NameComponent},
     opcode::{opcode, DUAL_NAME_PREFIX, MULTI_NAME_PREFIX, NULL_NAME, PREFIX_CHAR, ROOT_CHAR},
-    parser::{choice, comment_scope_verbose, consume, n_of, take, take_while, Parser},
+    parser::{choice, comment_scope, consume, n_of, take, take_while, Parser},
     AmlContext,
     AmlError,
+    DebugVerbosity,
 };
 use alloc::vec::Vec;
 use core::{fmt, str};
@@ -26,7 +27,11 @@ where
      * SuperName := SimpleName | DebugObj | Type6Opcode
      * TODO: this doesn't cover Type6Opcode yet
      */
-    comment_scope_verbose("SuperName", choice!(debug_obj().map(|()| Ok(Target::Debug)), simple_name()))
+    comment_scope(
+        DebugVerbosity::AllScopes,
+        "SuperName",
+        choice!(debug_obj().map(|()| Ok(Target::Debug)), simple_name()),
+    )
 }
 
 pub fn simple_name<'a, 'c>() -> impl Parser<'a, 'c, Target>
@@ -36,7 +41,8 @@ where
     /*
      * SimpleName := NameString | ArgObj | LocalObj
      */
-    comment_scope_verbose(
+    comment_scope(
+        DebugVerbosity::AllScopes,
         "SimpleName",
         choice!(
             name_string().map(move |name| Ok(Target::Name(name))),
@@ -68,7 +74,7 @@ where
         });
 
     // TODO: combinator to select a parser based on a peeked byte?
-    comment_scope_verbose("NameString", move |input: &'a [u8], context| {
+    comment_scope(DebugVerbosity::AllScopes, "NameString", move |input: &'a [u8], context| {
         let first_char = match input.first() {
             Some(&c) => c,
             None => return Err((input, context, AmlError::UnexpectedEndOfStream)),

+ 14 - 27
aml/src/parser.rs

@@ -1,6 +1,7 @@
-use crate::{pkg_length::PkgLength, AmlContext, AmlError};
+use crate::{pkg_length::PkgLength, AmlContext, AmlError, DebugVerbosity};
 use alloc::vec::Vec;
 use core::marker::PhantomData;
+use log::trace;
 
 pub type ParseResult<'a, 'c, R> =
     Result<(&'a [u8], &'c mut AmlContext, R), (&'a [u8], &'c mut AmlContext, AmlError)>;
@@ -224,41 +225,27 @@ where
     }
 }
 
-pub fn comment_scope<'a, 'c, P, R>(scope_name: &'a str, parser: P) -> impl Parser<'a, 'c, R>
-where
-    'c: 'a,
-    R: core::fmt::Debug,
-    P: Parser<'a, 'c, R>,
-{
-    move |input, context| {
-        #[cfg(feature = "debug_parser")]
-        log::trace!("--> {}", scope_name);
-
-        // Return if the parse fails, so we don't print the tail. Makes it easier to debug.
-        let (new_input, context, result) = parser.parse(input, context)?;
-
-        #[cfg(feature = "debug_parser")]
-        log::trace!("<-- {}", scope_name);
-
-        Ok((new_input, context, result))
-    }
-}
-
-pub fn comment_scope_verbose<'a, 'c, P, R>(scope_name: &'a str, parser: P) -> impl Parser<'a, 'c, R>
+pub fn comment_scope<'a, 'c, P, R>(
+    verbosity: DebugVerbosity,
+    scope_name: &'a str,
+    parser: P,
+) -> impl Parser<'a, 'c, R>
 where
     'c: 'a,
     R: core::fmt::Debug,
     P: Parser<'a, 'c, R>,
 {
-    move |input, context| {
-        #[cfg(feature = "debug_parser_verbose")]
-        log::trace!("--> {}", scope_name);
+    move |input, context: &'c mut AmlContext| {
+        if verbosity <= context.debug_verbosity {
+            trace!("--> {}", scope_name);
+        }
 
         // Return if the parse fails, so we don't print the tail. Makes it easier to debug.
         let (new_input, context, result) = parser.parse(input, context)?;
 
-        #[cfg(feature = "debug_parser_verbose")]
-        log::trace!("<-- {}", scope_name);
+        if verbosity <= context.debug_verbosity {
+            trace!("<-- {}", scope_name);
+        }
 
         Ok((new_input, context, result))
     }

+ 19 - 7
aml/src/term_object.rs

@@ -6,7 +6,6 @@ use crate::{
     parser::{
         choice,
         comment_scope,
-        comment_scope_verbose,
         make_parser_concrete,
         take,
         take_to_end_of_pkglength,
@@ -23,6 +22,7 @@ use crate::{
     value::{AmlValue, FieldFlags, MethodFlags, RegionSpace},
     AmlContext,
     AmlError,
+    DebugVerbosity,
 };
 use alloc::string::String;
 use core::str;
@@ -56,7 +56,8 @@ where
     /*
      * TermObj := NamespaceModifierObj | NamedObj | Type1Opcode | Type2Opcode
      */
-    comment_scope_verbose(
+    comment_scope(
+        DebugVerbosity::AllScopes,
         "TermObj",
         choice!(
             namespace_modifier().map(|()| Ok(None)),
@@ -90,7 +91,8 @@ where
      * XXX: DefMethod and DefMutex (at least) are not included in any rule in the AML grammar,
      * but are defined in the NamedObj section so we assume they're part of NamedObj
      */
-    comment_scope_verbose(
+    comment_scope(
+        DebugVerbosity::AllScopes,
         "NamedObj",
         choice!(def_op_region(), def_field(), def_method(), def_device(), def_processor(), def_mutex()),
     )
@@ -105,6 +107,7 @@ where
      */
     opcode(opcode::DEF_NAME_OP)
         .then(comment_scope(
+            DebugVerbosity::Scopes,
             "DefName",
             name_string().then(data_ref_object()).map_with_context(|(name, data_ref_object), context| {
                 try_with_context!(
@@ -126,6 +129,7 @@ where
      */
     opcode(opcode::DEF_SCOPE_OP)
         .then(comment_scope(
+            DebugVerbosity::Scopes,
             "DefScope",
             pkg_length()
                 .then(name_string())
@@ -174,6 +178,7 @@ where
      */
     ext_opcode(opcode::EXT_DEF_OP_REGION_OP)
         .then(comment_scope(
+            DebugVerbosity::Scopes,
             "DefOpRegion",
             name_string().then(take()).then(term_arg()).then(term_arg()).map_with_context(
                 |(((name, space), offset), length), context| {
@@ -225,6 +230,7 @@ where
      */
     ext_opcode(opcode::EXT_DEF_FIELD_OP)
         .then(comment_scope(
+            DebugVerbosity::Scopes,
             "DefField",
             pkg_length().then(name_string()).then(take()).feed(|((list_length, region_name), flags)| {
                 move |mut input: &'a [u8], mut context: &'c mut AmlContext| -> ParseResult<'a, 'c, ()> {
@@ -323,6 +329,7 @@ where
      */
     opcode(opcode::DEF_METHOD_OP)
         .then(comment_scope(
+            DebugVerbosity::Scopes,
             "DefMethod",
             pkg_length()
                 .then(name_string())
@@ -354,6 +361,7 @@ where
      */
     ext_opcode(opcode::EXT_DEF_DEVICE_OP)
         .then(comment_scope(
+            DebugVerbosity::Scopes,
             "DefDevice",
             pkg_length()
                 .then(name_string())
@@ -387,6 +395,7 @@ where
      */
     ext_opcode(opcode::EXT_DEF_PROCESSOR_OP)
         .then(comment_scope(
+            DebugVerbosity::Scopes,
             "DefProcessor",
             pkg_length()
                 .then(name_string())
@@ -429,6 +438,7 @@ where
      */
     ext_opcode(opcode::EXT_DEF_MUTEX_OP)
         .then(comment_scope(
+            DebugVerbosity::Scopes,
             "DefMutex",
             name_string().then(take()).map_with_context(|(name, sync_level), context| {
                 try_with_context!(
@@ -452,7 +462,8 @@ where
     /*
      * TermArg := Type2Opcode | DataObject | ArgObj | LocalObj
      */
-    comment_scope_verbose(
+    comment_scope(
+        DebugVerbosity::AllScopes,
         "TermArg",
         choice!(
             data_object(),
@@ -474,7 +485,7 @@ where
     /*
      * DataRefObject := DataObject | ObjectReference | DDBHandle
      */
-    comment_scope_verbose("DataRefObject", choice!(data_object()))
+    comment_scope(DebugVerbosity::AllScopes, "DataRefObject", choice!(data_object()))
 }
 
 pub fn data_object<'a, 'c>() -> impl Parser<'a, 'c, AmlValue>
@@ -488,7 +499,7 @@ where
      * accidently parsed as ComputationalDatas.
      */
     // TODO: this doesn't yet parse DefVarPackage
-    comment_scope_verbose("DataObject", choice!(def_package(), computational_data()))
+    comment_scope(DebugVerbosity::AllScopes, "DataObject", choice!(def_package(), computational_data()))
 }
 
 pub fn computational_data<'a, 'c>() -> impl Parser<'a, 'c, AmlValue>
@@ -546,7 +557,8 @@ where
         }
     };
 
-    comment_scope_verbose(
+    comment_scope(
+        DebugVerbosity::AllScopes,
         "ComputationalData",
         choice!(
             ext_opcode(opcode::EXT_REVISION_OP).map(|_| Ok(AmlValue::Integer(crate::AML_INTERPRETER_REVISION))),

+ 8 - 4
aml/src/type1.rs

@@ -1,9 +1,10 @@
 use crate::{
     opcode::{self, opcode},
-    parser::{choice, comment_scope, comment_scope_verbose, take_to_end_of_pkglength, ParseResult, Parser},
+    parser::{choice, comment_scope, take_to_end_of_pkglength, ParseResult, Parser},
     pkg_length::{pkg_length, PkgLength},
     term_object::{term_arg, term_list},
     AmlError,
+    DebugVerbosity,
 };
 
 /// Type 1 opcodes do not return a value and so can't be used in expressions.
@@ -16,7 +17,7 @@ where
      *                DefNotify | DefRelease | DefReset | DefReturn | DefSignal | DefSleep | DefStall |
      *                DefWhile
      */
-    comment_scope_verbose("Type1Opcode", choice!(def_if_else(), def_return()))
+    comment_scope(DebugVerbosity::AllScopes, "Type1Opcode", choice!(def_if_else(), def_return()))
 }
 
 fn def_if_else<'a, 'c>() -> impl Parser<'a, 'c, ()>
@@ -30,6 +31,7 @@ where
      */
     opcode(opcode::DEF_IF_ELSE_OP)
         .then(comment_scope(
+            DebugVerbosity::Scopes,
             "DefIfElse",
             pkg_length()
                 .then(term_arg())
@@ -39,7 +41,8 @@ where
                 })
                 .then(choice!(
                     opcode(opcode::DEF_ELSE_OP)
-                        .then(comment_scope_verbose(
+                        .then(comment_scope(
+                            DebugVerbosity::AllScopes,
                             "DefElse",
                             pkg_length().feed(|length| take_to_end_of_pkglength(length))
                         ))
@@ -75,7 +78,8 @@ where
      * ArgObject := TermArg => DataRefObject
      */
     opcode(opcode::DEF_RETURN_OP)
-        .then(comment_scope_verbose(
+        .then(comment_scope(
+            DebugVerbosity::Scopes,
             "DefReturn",
             term_arg().map(|return_arg| -> Result<(), AmlError> {
                 /*

+ 14 - 17
aml/src/type2.rs

@@ -1,20 +1,12 @@
 use crate::{
     name_object::{name_string, super_name, Target},
     opcode::{self, opcode},
-    parser::{
-        choice,
-        comment_scope,
-        comment_scope_verbose,
-        id,
-        take,
-        take_to_end_of_pkglength,
-        try_with_context,
-        Parser,
-    },
+    parser::{choice, comment_scope, id, take, take_to_end_of_pkglength, try_with_context, Parser},
     pkg_length::pkg_length,
     term_object::{data_ref_object, term_arg},
     value::AmlValue,
     AmlError,
+    DebugVerbosity,
 };
 use alloc::vec::Vec;
 
@@ -34,7 +26,8 @@ where
      *                DefSubtract | DefTimer | DefToBCD | DefToBuffer | DefToDecimalString |
      *                DefToHexString | DefToInteger | DefToString | DefWait | DefXOr | MethodInvocation
      */
-    comment_scope_verbose(
+    comment_scope(
+        DebugVerbosity::AllScopes,
         "Type2Opcode",
         choice!(def_buffer(), def_l_equal(), def_package(), def_store(), method_invocation()),
     )
@@ -54,6 +47,7 @@ where
      */
     opcode(opcode::DEF_BUFFER_OP)
         .then(comment_scope(
+            DebugVerbosity::Scopes,
             "DefBuffer",
             pkg_length().then(term_arg()).feed(|(pkg_length, buffer_size)| {
                 take_to_end_of_pkglength(pkg_length)
@@ -72,7 +66,8 @@ where
      * Operand := TermArg => Integer
      */
     opcode(opcode::DEF_L_EQUAL_OP)
-        .then(comment_scope_verbose(
+        .then(comment_scope(
+            DebugVerbosity::AllScopes,
             "DefLEqual",
             term_arg().then(term_arg()).map(|(left_arg, right_arg)| {
                 Ok(AmlValue::Boolean(left_arg.as_integer()? == right_arg.as_integer()?))
@@ -93,6 +88,7 @@ where
      */
     opcode(opcode::DEF_PACKAGE_OP)
         .then(comment_scope(
+            DebugVerbosity::Scopes,
             "DefPackage",
             pkg_length().then(take()).feed(|(pkg_length, num_elements)| {
                 move |mut input, mut context| {
@@ -134,8 +130,9 @@ where
      * after the store (as opposed to the data we think we put into it), because some stores can
      * alter the data during the store.
      */
-    opcode(opcode::DEF_STORE_OP).then(comment_scope("DefStore", term_arg().then(super_name()))).map_with_context(
-        |((), (value, target)), context| {
+    opcode(opcode::DEF_STORE_OP)
+        .then(comment_scope(DebugVerbosity::Scopes, "DefStore", term_arg().then(super_name())))
+        .map_with_context(|((), (value, target)), context| {
             match target {
                 Target::Name(ref path) => {
                     let (_, handle) =
@@ -162,8 +159,7 @@ where
                     unimplemented!()
                 }
             }
-        },
-    )
+        })
 }
 
 fn method_invocation<'a, 'c>() -> impl Parser<'a, 'c, AmlValue>
@@ -179,7 +175,8 @@ where
      * so parsing them properly can be very difficult.
      * NOTE: We don't support the case of the definition appearing after the invocation.
      */
-    comment_scope_verbose(
+    comment_scope(
+        DebugVerbosity::Scopes,
         "MethodInvocation",
         name_string()
             .map_with_context(move |name, context| {