浏览代码

Implement ToInteger

Isaac Woods 3 年之前
父节点
当前提交
00a61d8b74
共有 2 个文件被更改,包括 47 次插入2 次删除
  1. 1 0
      aml/src/opcode.rs
  2. 46 2
      aml/src/type2.rs

+ 1 - 0
aml/src/opcode.rs

@@ -71,6 +71,7 @@ pub const DEF_L_NOT_OP: u8 = 0x92;
 pub const DEF_L_EQUAL_OP: u8 = 0x93;
 pub const DEF_L_GREATER_OP: u8 = 0x94;
 pub const DEF_L_LESS_OP: u8 = 0x95;
+pub const DEF_TO_INTEGER_OP: u8 = 0x99;
 pub const DEF_MID_OP: u8 = 0x9e;
 
 /*

+ 46 - 2
aml/src/type2.rs

@@ -14,7 +14,7 @@ use crate::{
     },
     pkg_length::pkg_length,
     term_object::{data_ref_object, term_arg},
-    value::{AmlValue, Args},
+    value::{AmlType, AmlValue, Args},
     AmlError,
     DebugVerbosity,
 };
@@ -36,7 +36,7 @@ where
      *                DefCondRefOf | DefCopyObject | DefDecrement | DefDerefOf | DefDivide |
      *                DefFindSetLeftBit | DefFindSetRightBit | DefFromBCD | DefIncrement | DefIndex |
      *                DefLAnd | DefLEqual | DefLGreater | DefLGreaterEqual | DefLLess | DefLLessEqual |
-     *                DefMid | DefLNot | DefLNotEqual | DefLoadTable | DefLOr | DefMatch | DefMod |
+     *                DefMid | DefLNot | DefLNotEqual | DefLoad | DefLoadTable | DefLOr | DefMatch | DefMod |
      *                DefMultiply | DefNAnd | DefNOr | DefNot | DefObjectType | DefOr | DefPackage |
      *                DefVarPackage | DefRefOf | DefShiftLeft | DefShiftRight | DefSizeOf | DefStore |
      *                DefSubtract | DefTimer | DefToBCD | DefToBuffer | DefToDecimalString |
@@ -65,6 +65,7 @@ where
             def_shift_left(),
             def_shift_right(),
             def_store(),
+            def_to_integer(),
             method_invocation() // XXX: this must always appear last. See how we have to parse it to see why.
         ),
     ))
@@ -629,6 +630,49 @@ where
         })
 }
 
+fn def_to_integer<'a, 'c>() -> impl Parser<'a, 'c, AmlValue>
+where
+    'c: 'a,
+{
+    /*
+     * DefToInteger := 0x99 Operand Target
+     * Operand := TermArg
+     */
+    opcode(opcode::DEF_TO_INTEGER_OP)
+        .then(comment_scope(DebugVerbosity::AllScopes, "DefToInteger", term_arg().then(target())))
+        .map_with_context(|((), (operand, target)), context| {
+            let result = match operand {
+                AmlValue::Integer(value) => AmlValue::Integer(value),
+                AmlValue::Buffer(data) => {
+                    AmlValue::Integer(try_with_context!(context, AmlValue::Buffer(data).as_integer(context)))
+                }
+                AmlValue::String(string) => AmlValue::Integer(try_with_context!(
+                    context,
+                    if string.starts_with("0x") {
+                        u64::from_str_radix(string.trim_start_matches("0x"), 16)
+                    } else {
+                        string.parse::<u64>()
+                    }
+                    .map_err(|_| AmlError::IncompatibleValueConversion {
+                        current: AmlType::String,
+                        target: AmlType::Integer,
+                    })
+                )),
+                _ => {
+                    return (
+                        Err(Propagate::Err(AmlError::IncompatibleValueConversion {
+                            current: operand.type_of(),
+                            target: AmlType::Integer,
+                        })),
+                        context,
+                    )
+                }
+            };
+            try_with_context!(context, context.store(target, result.clone()));
+            (Ok(result), context)
+        })
+}
+
 fn method_invocation<'a, 'c>() -> impl Parser<'a, 'c, AmlValue>
 where
     'c: 'a,