Skip to content

Commit b387ba5

Browse files
committed
AML: implement support for native methods in the AML namespace
1 parent 17a86ae commit b387ba5

File tree

3 files changed

+38
-13
lines changed

3 files changed

+38
-13
lines changed

src/aml/mod.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,13 @@ where
136136
trace!("Invoking AML method: {}", path);
137137

138138
let object = self.namespace.lock().get(path.clone())?.clone();
139-
match object.typ() {
140-
ObjectType::Method => {
139+
match &*object {
140+
Object::Method { .. } => {
141141
self.namespace.lock().add_level(path.clone(), NamespaceLevelKind::MethodLocals)?;
142142
let context = MethodContext::new_from_method(object, args, path)?;
143143
self.do_execute_method(context)
144144
}
145+
Object::NativeMethod(f) => f(&args),
145146
_ => Ok(object),
146147
}
147148
}
@@ -644,13 +645,22 @@ where
644645
})
645646
.collect();
646647

647-
self.namespace.lock().add_level(method_scope.clone(), NamespaceLevelKind::MethodLocals)?;
648+
if let Object::Method { .. } = **method {
649+
self.namespace
650+
.lock()
651+
.add_level(method_scope.clone(), NamespaceLevelKind::MethodLocals)?;
648652

649-
let new_context =
650-
MethodContext::new_from_method(method.clone(), args, method_scope.clone())?;
651-
let old_context = mem::replace(&mut context, new_context);
652-
self.context_stack.lock().push(old_context);
653-
context.retire_op(op);
653+
let new_context =
654+
MethodContext::new_from_method(method.clone(), args, method_scope.clone())?;
655+
let old_context = mem::replace(&mut context, new_context);
656+
self.context_stack.lock().push(old_context);
657+
context.retire_op(op);
658+
} else if let Object::NativeMethod { ref f, .. } = **method {
659+
let result = f(&args)?;
660+
context.contribute_arg(Argument::Object(result));
661+
} else {
662+
panic!();
663+
}
654664
}
655665
Opcode::Return => {
656666
let [Argument::Object(object)] = &op.arguments[..] else { panic!() };
@@ -1207,7 +1217,8 @@ where
12071217
let object = self.namespace.lock().search(&name, &context.current_scope);
12081218
match object {
12091219
Ok((resolved_name, object)) => {
1210-
if let Object::Method { flags, .. } = *object {
1220+
if let Object::Method { flags, .. } | Object::NativeMethod { flags, .. } = *object
1221+
{
12111222
context.start_in_flight_op(OpInFlight::new_with(
12121223
Opcode::InternalMethodCall,
12131224
vec![Argument::Object(object), Argument::Namestring(resolved_name)],
@@ -1762,7 +1773,7 @@ where
17621773
Object::Event => "[Event]".to_string(),
17631774
Object::FieldUnit(_) => "[Field]".to_string(),
17641775
Object::Integer(value) => value.to_string(),
1765-
Object::Method { .. } => "[Control Method]".to_string(),
1776+
Object::Method { .. } | Object::NativeMethod(_) => "[Control Method]".to_string(),
17661777
Object::Mutex { .. } => "[Mutex]".to_string(),
17671778
Object::Reference { inner, .. } => resolve_as_string(&*(inner.clone().unwrap_reference())),
17681779
Object::OpRegion(_) => "[Operation Region]".to_string(),

src/aml/namespace.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
use super::object::WrappedObject;
2-
use crate::aml::AmlError;
1+
use super::{
2+
AmlError,
3+
object::{MethodFlags, Object, WrappedObject},
4+
};
35
use alloc::{
46
collections::btree_map::BTreeMap,
57
string::{String, ToString},
8+
sync::Arc,
69
vec,
710
vec::Vec,
811
};
@@ -26,6 +29,12 @@ impl Namespace {
2629
namespace.add_level(AmlName::from_str("\\_PR").unwrap(), NamespaceLevelKind::Scope).unwrap();
2730
namespace.add_level(AmlName::from_str("\\_TZ").unwrap(), NamespaceLevelKind::Scope).unwrap();
2831

32+
// TODO: this is just testing the native methods atm - actually implement it
33+
namespace.insert(
34+
AmlName::from_str("\\_OSI").unwrap(),
35+
Object::NativeMethod { f: Arc::new(|args| todo!()), flags: MethodFlags(0) }.wrap(),
36+
);
37+
2938
// TODO: add pre-defined objects as well - \GL, \OSI, etc.
3039

3140
namespace

src/aml/object.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use alloc::{borrow::Cow, string::String, sync::Arc, vec::Vec};
33
use bit_field::BitField;
44
use core::{cell::UnsafeCell, fmt, ops};
55

6-
#[derive(Clone, Debug)]
6+
type NativeMethod = dyn Fn(&[WrappedObject]) -> Result<WrappedObject, AmlError>;
7+
8+
#[derive(Clone)]
79
pub enum Object {
810
Uninitialized,
911
Buffer(Vec<u8>),
@@ -13,6 +15,7 @@ pub enum Object {
1315
FieldUnit(FieldUnit),
1416
Integer(u64),
1517
Method { code: Vec<u8>, flags: MethodFlags },
18+
NativeMethod { f: Arc<NativeMethod>, flags: MethodFlags },
1619
Mutex { mutex: Handle, sync_level: u8 },
1720
Reference { kind: ReferenceKind, inner: WrappedObject },
1821
OpRegion(OpRegion),
@@ -39,6 +42,7 @@ impl fmt::Display for Object {
3942
Object::Integer(value) => write!(f, "Integer({})", value),
4043
// TODO: decode flags here
4144
Object::Method { code, flags } => write!(f, "Method"),
45+
Object::NativeMethod { .. } => write!(f, "NativeMethod"),
4246
Object::Mutex { mutex, sync_level } => write!(f, "Mutex"),
4347
Object::Reference { kind, inner } => write!(f, "Reference({:?} -> {})", kind, **inner),
4448
Object::OpRegion(region) => write!(f, "{:?}", region),
@@ -248,6 +252,7 @@ impl Object {
248252
Object::FieldUnit(_) => ObjectType::FieldUnit,
249253
Object::Integer(_) => ObjectType::Integer,
250254
Object::Method { .. } => ObjectType::Method,
255+
Object::NativeMethod { .. } => ObjectType::Method,
251256
Object::Mutex { .. } => ObjectType::Mutex,
252257
Object::Reference { inner, .. } => inner.typ(),
253258
Object::OpRegion(_) => ObjectType::OpRegion,

0 commit comments

Comments
 (0)