Added object modification

This commit is contained in:
Connor Wood
2017-07-03 11:11:07 +01:00
parent 7527915027
commit 2a6bbeb584
4 changed files with 108 additions and 71 deletions

View File

@@ -39,10 +39,7 @@ pub enum AmlError {
pub fn parse_aml_table(sdt: &'static Sdt) -> Result<BTreeMap<String, AmlValue>, AmlError> {
let data = sdt.data();
let mut ctx = AmlExecutionContext {
namespace: &mut BTreeMap::new(),
scope: String::from_str("\\").unwrap()
};
let mut ctx = AmlExecutionContext::new(String::from_str("\\").unwrap());
let term_list = parse_term_list(data, &mut ctx)?;

View File

@@ -342,11 +342,7 @@ fn parse_def_device(data: &[u8],
let (pkg_length, pkg_length_len) = parse_pkg_length(&data[2..])?;
let name = parse_name_string(&data[2 + pkg_length_len .. 2 + pkg_length], ctx)?;
let mut local_ctx = AmlExecutionContext {
namespace: &mut BTreeMap::new(),
scope: String::new()
};
let mut local_ctx = AmlExecutionContext::new(String::new());
let obj_list = parse_object_list(&data[2 + pkg_length_len + name.len .. 2 + pkg_length], &mut local_ctx)?;
let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val);
@@ -682,11 +678,7 @@ fn parse_def_power_res(data: &[u8],
let resource_order: u16 = (data[3 + pkg_len_len + name.len] as u16) +
((data[4 + pkg_len_len + name.len] as u16) << 8);
let mut local_ctx = AmlExecutionContext {
namespace: &mut BTreeMap::new(),
scope: String::new()
};
let mut local_ctx = AmlExecutionContext::new(String::new());
parse_object_list(&data[5 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?;
ctx.namespace.insert(local_scope_string, AmlValue::PowerResource {
@@ -717,11 +709,7 @@ fn parse_def_processor(data: &[u8],
((data[6 + pkg_len_len + name.len] as u32) << 24);
let p_blk_len = data[7 + pkg_len_len + name.len];
let mut local_ctx = AmlExecutionContext {
namespace: &mut BTreeMap::new(),
scope: String::new()
};
let mut local_ctx = AmlExecutionContext::new(String::new());
parse_object_list(&data[8 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?;
ctx.namespace.insert(local_scope_string, AmlValue::Processor {
@@ -745,11 +733,7 @@ fn parse_def_thermal_zone(data: &[u8],
let local_scope_string = get_namespace_string(ctx.scope.clone(), name.val);
let mut local_ctx = AmlExecutionContext {
namespace: &mut BTreeMap::new(),
scope: String::new()
};
let mut local_ctx = AmlExecutionContext::new(String::new());
parse_object_list(&data[2 + pkg_len_len + name.len .. 2 + pkg_len], &mut local_ctx)?;
ctx.namespace.insert(local_scope_string, AmlValue::ThermalZone(local_ctx.namespace.clone()));

View File

@@ -1,7 +1,7 @@
use collections::string::String;
use collections::btree_map::BTreeMap;
use super::namespace::AmlValue;
use super::namespace::{ AmlValue, ObjectReference };
use super::AmlError;
pub type ParseResult = Result<AmlParseType, AmlError>;
@@ -12,7 +12,48 @@ pub struct AmlParseTypeGeneric<T> {
pub len: usize
}
pub struct AmlExecutionContext<'a> {
pub namespace: &'a mut BTreeMap<String, AmlValue>,
pub scope: String
pub struct AmlExecutionContext {
pub namespace: BTreeMap<String, AmlValue>,
pub scope: String,
pub local_vars: [AmlValue; 8],
pub arg_vars: [AmlValue; 8]
}
impl AmlExecutionContext {
pub fn new(scope: String) -> AmlExecutionContext {
AmlExecutionContext {
namespace: BTreeMap::new(),
scope: scope,
local_vars: [AmlValue::Uninitialized,
AmlValue::Uninitialized,
AmlValue::Uninitialized,
AmlValue::Uninitialized,
AmlValue::Uninitialized,
AmlValue::Uninitialized,
AmlValue::Uninitialized,
AmlValue::Uninitialized],
arg_vars: [AmlValue::Uninitialized,
AmlValue::Uninitialized,
AmlValue::Uninitialized,
AmlValue::Uninitialized,
AmlValue::Uninitialized,
AmlValue::Uninitialized,
AmlValue::Uninitialized,
AmlValue::Uninitialized]
}
}
pub fn modify(&mut self, name: AmlValue, value: AmlValue) {
// TODO: throw errors
// TODO: return DRO
match name {
AmlValue::None => (),
AmlValue::ObjectReference(r) => match r {
ObjectReference::ArgObj(i) => (),
ObjectReference::LocalObj(i) => self.local_vars[i as usize] = value,
_ => ()
},
_ => ()
}
}
}

View File

@@ -429,17 +429,18 @@ fn parse_def_to_string(data: &[u8],
fn parse_def_subtract(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
parser_opcode!(data, 0x74);
let lhs = parse_term_arg(&data[1..], ctx)?;
let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
let result = lhs.val.get_as_integer()? - rhs.val.get_as_integer()?;
let result = AmlValue::Integer(lhs.val.get_as_integer()? - rhs.val.get_as_integer()?);
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 1 + lhs.len + rhs.len + target.len
})
}
@@ -459,11 +460,13 @@ fn parse_def_size_of(data: &[u8],
fn parse_def_store(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Perform the store
// TODO: Return the DRO
parser_opcode!(data, 0x70);
let operand = parse_term_arg(&data[1..], ctx)?;
let target = parse_super_name(&data[1 + operand.len..], ctx)?;
ctx.modify(target.val, operand.val);
Ok(AmlParseType {
val: AmlValue::Uninitialized,
@@ -473,102 +476,108 @@ fn parse_def_store(data: &[u8],
fn parse_def_or(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
parser_opcode!(data, 0x7D);
let lhs = parse_term_arg(&data[1..], ctx)?;
let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
let result = lhs.val.get_as_integer()? | rhs.val.get_as_integer()?;
let result = AmlValue::Integer(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?);
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 1 + lhs.len + rhs.len + target.len
})
}
fn parse_def_shift_left(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
parser_opcode!(data, 0x79);
let lhs = parse_term_arg(&data[1..], ctx)?;
let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
let result = lhs.val.get_as_integer()? >> rhs.val.get_as_integer()?;
let result = AmlValue::Integer(lhs.val.get_as_integer()? >> rhs.val.get_as_integer()?);
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 1 + lhs.len + rhs.len + target.len
})
}
fn parse_def_shift_right(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
parser_opcode!(data, 0x7A);
let lhs = parse_term_arg(&data[1..], ctx)?;
let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
let result = lhs.val.get_as_integer()? << rhs.val.get_as_integer()?;
let result = AmlValue::Integer(lhs.val.get_as_integer()? << rhs.val.get_as_integer()?);
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 1 + lhs.len + rhs.len + target.len
})
}
fn parse_def_add(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
parser_opcode!(data, 0x72);
let lhs = parse_term_arg(&data[1..], ctx)?;
let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
let result = lhs.val.get_as_integer()? + rhs.val.get_as_integer()?;
let result = AmlValue::Integer(lhs.val.get_as_integer()? + rhs.val.get_as_integer()?);
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 1 + lhs.len + rhs.len + target.len
})
}
fn parse_def_and(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
parser_opcode!(data, 0x7B);
let lhs = parse_term_arg(&data[1..], ctx)?;
let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
let result = lhs.val.get_as_integer()? & rhs.val.get_as_integer()?;
let result = AmlValue::Integer(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?);
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 1 + lhs.len + rhs.len + target.len
})
}
fn parse_def_xor(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
parser_opcode!(data, 0x7F);
let lhs = parse_term_arg(&data[1..], ctx)?;
let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
let result = lhs.val.get_as_integer()? ^ rhs.val.get_as_integer()?;
let result = AmlValue::Integer(lhs.val.get_as_integer()? ^ rhs.val.get_as_integer()?);
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 1 + lhs.len + rhs.len + target.len
})
}
@@ -771,14 +780,13 @@ fn parse_def_match(data: &[u8],
fn parse_def_from_bcd(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
// TODO: Clean up match block
parser_opcode_extended!(data, 0x28);
let operand = parse_term_arg(&data[2..], ctx)?;
let target = parse_target(&data[2 + operand.len..], ctx)?;
let result = match target.val.get_as_integer() {
let result = AmlValue::Integer(match target.val.get_as_integer() {
Ok(i) => {
let mut i = i;
let mut ires = 0;
@@ -796,10 +804,12 @@ fn parse_def_from_bcd(data: &[u8],
ires
},
Err(e) => return Err(e)
};
});
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 2 + operand.len + target.len
})
}
@@ -823,7 +833,6 @@ fn parse_def_mid(data: &[u8],
fn parse_def_mod(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
// TODO: Fatal exception on rhs == 0
parser_opcode!(data, 0x85);
@@ -831,17 +840,18 @@ fn parse_def_mod(data: &[u8],
let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
let result = lhs.val.get_as_integer()? % rhs.val.get_as_integer()?;
let result = AmlValue::Integer(lhs.val.get_as_integer()? % rhs.val.get_as_integer()?);
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 1 + lhs.len + rhs.len + target.len
})
}
fn parse_def_multiply(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
// TODO: Handle overflow
parser_opcode!(data, 0x77);
@@ -849,60 +859,65 @@ fn parse_def_multiply(data: &[u8],
let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
let result = lhs.val.get_as_integer()? * rhs.val.get_as_integer()?;
let result = AmlValue::Integer(lhs.val.get_as_integer()? * rhs.val.get_as_integer()?);
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 1 + lhs.len + rhs.len + target.len
})
}
fn parse_def_nand(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
parser_opcode!(data, 0x7C);
let lhs = parse_term_arg(&data[1..], ctx)?;
let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
let result = !(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?);
let result = AmlValue::Integer(!(lhs.val.get_as_integer()? & rhs.val.get_as_integer()?));
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 1 + lhs.len + rhs.len + target.len
})
}
fn parse_def_nor(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
parser_opcode!(data, 0x7E);
let lhs = parse_term_arg(&data[1..], ctx)?;
let rhs = parse_term_arg(&data[1 + lhs.len..], ctx)?;
let target = parse_target(&data[1 + lhs.len + rhs.len..], ctx)?;
let result = !(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?);
let result = AmlValue::Integer(!(lhs.val.get_as_integer()? | rhs.val.get_as_integer()?));
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 1 + lhs.len + rhs.len + target.len
})
}
fn parse_def_not(data: &[u8],
ctx: &mut AmlExecutionContext) -> ParseResult {
// TODO: Store the result, if appropriate
parser_opcode!(data, 0x80);
let operand = parse_term_arg(&data[1..], ctx)?;
let target = parse_target(&data[1 + operand.len..], ctx)?;
let result = !operand.val.get_as_integer()?;
let result = AmlValue::Integer(!operand.val.get_as_integer()?);
ctx.modify(target.val, result.clone());
Ok(AmlParseType {
val: AmlValue::IntegerConstant(result),
val: result,
len: 1 + operand.len + target.len
})
}