Implmented method execution and method invocations
This commit is contained in:
@@ -7,20 +7,12 @@ use collections::btree_map::BTreeMap;
|
||||
|
||||
use super::AmlError;
|
||||
use super::parser::{ AmlParseType, ParseResult, AmlParseTypeGeneric, AmlExecutionContext, ExecutionState };
|
||||
use super::namespace::{ AmlValue, ObjectReference, FieldSelector, get_namespace_string };
|
||||
use super::namespace::{ AmlValue, ObjectReference, FieldSelector, Method, get_namespace_string };
|
||||
use super::namestring::{parse_name_string, parse_name_seg};
|
||||
use super::termlist::{parse_term_arg, parse_term_list, parse_object_list};
|
||||
use super::pkglength::parse_pkg_length;
|
||||
use super::type2opcode::parse_def_buffer;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Method {
|
||||
arg_count: u8,
|
||||
serialized: bool,
|
||||
sync_level: u8,
|
||||
term_list: Vec<u8>
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum RegionSpace {
|
||||
SystemMemory,
|
||||
|
||||
@@ -5,7 +5,8 @@ use collections::btree_map::BTreeMap;
|
||||
|
||||
use core::str::FromStr;
|
||||
|
||||
use super::namedobj::{ RegionSpace, FieldFlags, Method };
|
||||
use super::termlist::parse_term_list;
|
||||
use super::namedobj::{ RegionSpace, FieldFlags };
|
||||
use super::parser::AmlExecutionContext;
|
||||
use super::AmlError;
|
||||
|
||||
@@ -30,6 +31,14 @@ pub enum ObjectReference {
|
||||
Object(Box<AmlValue>)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Method {
|
||||
pub arg_count: u8,
|
||||
pub serialized: bool,
|
||||
pub sync_level: u8,
|
||||
pub term_list: Vec<u8>
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AmlValue {
|
||||
None,
|
||||
@@ -105,6 +114,24 @@ impl AmlValue {
|
||||
_ => Err(AmlError::AmlValueError)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_as_method(&self) -> Result<Method, AmlError> {
|
||||
match *self {
|
||||
AmlValue::Method(ref m) => Ok(m.clone()),
|
||||
_ => Err(AmlError::AmlValueError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Method {
|
||||
pub fn execute(&self, scope: String, parameters: Vec<AmlValue>) -> AmlValue {
|
||||
let mut ctx = AmlExecutionContext::new(scope);
|
||||
ctx.init_arg_vars(parameters);
|
||||
|
||||
parse_term_list(&self.term_list[..], &mut ctx);
|
||||
|
||||
AmlValue::None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_namespace_string(current: String, modifier_v: AmlValue) -> String {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use collections::string::String;
|
||||
use collections::btree_map::BTreeMap;
|
||||
use collections::vec::Vec;
|
||||
|
||||
use super::namespace::{ AmlValue, ObjectReference };
|
||||
use super::AmlError;
|
||||
@@ -53,6 +54,18 @@ impl AmlExecutionContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_arg_vars(&mut self, parameters: Vec<AmlValue>) {
|
||||
if parameters.len() > 8 {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut cur = 0;
|
||||
while cur < parameters.len() {
|
||||
self.arg_vars[cur] = parameters[cur].clone();
|
||||
cur += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modify(&mut self, name: AmlValue, value: AmlValue) {
|
||||
// TODO: throw errors
|
||||
// TODO: return DRO
|
||||
|
||||
@@ -120,12 +120,32 @@ pub fn parse_method_invocation(data: &[u8],
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Check if method exists in namespace
|
||||
// TODO: If so, parse appropriate number of parameters
|
||||
// TODO: If not, add deferred load to ctx
|
||||
let name = parse_name_string(data, ctx)?;
|
||||
let method = ctx.get(name.val.clone());
|
||||
|
||||
let method = match method {
|
||||
AmlValue::None => return Err(AmlError::AmlDeferredLoad),
|
||||
_ => method.get_as_method()?
|
||||
};
|
||||
|
||||
Err(AmlError::AmlDeferredLoad)
|
||||
let mut cur = 0;
|
||||
let mut params: Vec<AmlValue> = vec!();
|
||||
|
||||
let mut current_offset = name.len;
|
||||
|
||||
while cur < method.arg_count {
|
||||
let res = parse_term_arg(&data[current_offset..], ctx)?;
|
||||
|
||||
current_offset += res.len;
|
||||
cur += 1;
|
||||
|
||||
params.push(res.val);
|
||||
}
|
||||
|
||||
Ok(AmlParseType {
|
||||
val: method.execute(get_namespace_string(ctx.scope.clone(), name.val), params),
|
||||
len: current_offset
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_term_obj(data: &[u8],
|
||||
|
||||
Reference in New Issue
Block a user