Ver código fonte

Implement DefBreak

Isaac Woods 3 anos atrás
pai
commit
da5f5cec80
4 arquivos alterados com 26 adições e 1 exclusões
  1. 3 0
      aml/src/lib.rs
  2. 1 0
      aml/src/opcode.rs
  3. 1 0
      aml/src/parser.rs
  4. 21 1
      aml/src/type1.rs

+ 3 - 0
aml/src/lib.rs

@@ -189,6 +189,7 @@ impl AmlContext {
                             // If the method doesn't return a value, we implicitly return `0`
                             Ok(_) => Ok(AmlValue::Integer(0)),
                             Err((_, _, Propagate::Return(result))) => Ok(result),
+                            Err((_, _, Propagate::Break)) => Err(AmlError::BreakInInvalidPosition),
                             Err((_, _, Propagate::Err(err))) => {
                                 error!("Failed to execute control method: {:?}", err);
                                 Err(err)
@@ -740,6 +741,8 @@ pub enum AmlError {
     InvalidLocalAccess(LocalNum),
     /// Tried to invoke a method with too many arguments.
     TooManyArgs,
+    /// A `DefBreak` operation was performed outside of a `DefWhile` or `DefSwitch`.
+    BreakInInvalidPosition,
 
     /*
      * Errors produced parsing the PCI routing tables (_PRT objects).

+ 1 - 0
aml/src/opcode.rs

@@ -50,6 +50,7 @@ pub const DEF_ELSE_OP: u8 = 0xa1;
 pub const DEF_WHILE_OP: u8 = 0xa2;
 pub const DEF_NOOP_OP: u8 = 0xa3;
 pub const DEF_RETURN_OP: u8 = 0xa4;
+pub const DEF_BREAK_OP: u8 = 0xa5;
 pub const DEF_BREAKPOINT_OP: u8 = 0xcc;
 
 /*

+ 1 - 0
aml/src/parser.rs

@@ -21,6 +21,7 @@ impl AmlContext {
 pub enum Propagate {
     Err(AmlError),
     Return(AmlValue),
+    Break,
 }
 
 impl From<AmlError> for Propagate {

+ 21 - 1
aml/src/type1.rs

@@ -33,10 +33,26 @@ where
     comment_scope(
         DebugVerbosity::AllScopes,
         "Type1Opcode",
-        choice!(def_breakpoint(), def_fatal(), def_if_else(), def_noop(), def_return(), def_while()),
+        choice!(def_break(), def_breakpoint(), def_fatal(), def_if_else(), def_noop(), def_return(), def_while()),
     )
 }
 
+fn def_break<'a, 'c>() -> impl Parser<'a, 'c, ()>
+where
+    'c: 'a,
+{
+    /*
+     * DefBreak := 0xa5
+     */
+    opcode(opcode::DEF_BREAK_OP)
+        .then(comment_scope(
+            DebugVerbosity::AllScopes,
+            "DefBreak",
+            id().map(|()| -> Result<(), Propagate> { Err(Propagate::Break) }),
+        ))
+        .discard_result()
+}
+
 fn def_breakpoint<'a, 'c>() -> impl Parser<'a, 'c, ()>
 where
     'c: 'a,
@@ -197,6 +213,10 @@ where
                                 context = new_context;
                             }
                             // TODO: differentiate real errors and special Propagates (e.g. break, continue, etc.)
+                            Err((_, new_context, Propagate::Break)) => {
+                                context = new_context;
+                                break;
+                            }
                             Err((_, context, err)) => return (Err(err), context),
                         }