Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge changes to the method reference repr #57

Merged
merged 10 commits into from
Oct 5, 2024
83 changes: 43 additions & 40 deletions cilly/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ use serde::{Deserialize, Serialize};
use crate::{
access_modifier::AccessModifer,
basic_block::BasicBlock,
call_site::CallSite,
cil_root::CILRoot,
method::{Method, MethodType},
v2::{ClassDef, FnSig, Int},
v2::{cilnode::MethodKind, ClassDef, FnSig, Int, MethodRef, MethodRefIdx},
IString, Type,
};

Expand All @@ -36,9 +35,9 @@ pub type ExternFnDef = (IString, FnSig, bool);
/// Representation of a .NET assembly.
pub struct Assembly {
/// List of functions defined within this assembly.
functions: FxHashMap<CallSite, Method>,
/// Callsite representing the entrypoint of this assebmly if any present.
entrypoint: Option<CallSite>,
functions: FxHashMap<MethodRefIdx, Method>,
/// MethodRefIdx representing the entrypoint of this assebmly if any present.
entrypoint: Option<MethodRefIdx>,
/// List of references to external assemblies
extern_refs: FxHashMap<IString, AssemblyExternRef>,
extern_fns: FxHashMap<ExternFnDef, IString>,
Expand Down Expand Up @@ -100,33 +99,34 @@ impl Assembly {

/// Addds a per-thread static initailzer
pub fn add_tcctor(&mut self) -> &mut Method {
self.functions
.entry(CallSite::new(
None,
".tcctor".into(),
let mref = MethodRef::new(
*self.main_module(),
self.alloc_string(".tcctor"),
self.alloc_sig(FnSig::new(Box::new([]), Type::Void)),
MethodKind::Static,
vec![].into(),
);
let mref = self.alloc_methodref(mref);
self.functions.entry(mref).or_insert_with(|| {
Method::new(
AccessModifer::Extern,
MethodType::Static,
FnSig::new(Box::new([]), Type::Void),
true,
))
.or_insert_with(|| {
Method::new(
AccessModifer::Extern,
MethodType::Static,
FnSig::new(Box::new([]), Type::Void),
".tcctor",
vec![
(None, self.inner.nptr(Type::Int(Int::U8))),
(None, self.inner.nptr(Type::Int(Int::U8))),
],
vec![BasicBlock::new(vec![CILRoot::VoidRet.into()], 0, None)],
vec![],
)
})
".tcctor",
vec![
(None, self.inner.nptr(Type::Int(Int::U8))),
(None, self.inner.nptr(Type::Int(Int::U8))),
],
vec![BasicBlock::new(vec![CILRoot::VoidRet.into()], 0, None)],
vec![],
)
})
}

/// Returns true if assembly contains function named `name`
#[must_use]
pub fn contains_fn(&self, site: &CallSite) -> bool {
self.functions.contains_key(site)
pub fn contains_fn(&self, site: MethodRefIdx) -> bool {
self.functions.contains_key(&site)
}
/// Adds a method to the assebmly.
pub fn add_method(&mut self, method: Method) {
Expand All @@ -144,11 +144,11 @@ impl Assembly {
}
}

/// Sets the entrypoint of the assembly to the method behind `CallSite`.
pub fn set_entrypoint(&mut self, entrypoint: &CallSite) {
/// Sets the entrypoint of the assembly to the method behind `MethodRefIdx`.
pub fn set_entrypoint(&mut self, entrypoint: MethodRefIdx) {
assert!(self.entrypoint.is_none(), "ERROR: Multiple entrypoints");
let wrapper = crate::entrypoint::wrapper(entrypoint, self.inner_mut());
self.entrypoint = Some(wrapper.call_site());
let wrapper = crate::entrypoint::wrapper(self[entrypoint].clone(), self.inner_mut());
self.entrypoint = Some(wrapper.call_site(self));
self.add_method(wrapper);
}

Expand All @@ -161,15 +161,18 @@ impl Assembly {
self.initializers.push(root);
}
pub fn cctor_mut(&mut self) -> Option<&mut Method> {
self.functions.get_mut(&CallSite::new(
None,
".cctor".into(),
FnSig::new(Box::new([]), Type::Void),
true,
))
}

pub(crate) fn functions(&self) -> &FxHashMap<CallSite, Method> {
let mref = MethodRef::new(
*self.main_module(),
self.alloc_string(".cctor"),
self.sig([], Type::Void),
MethodKind::Static,
vec![].into(),
);
let mref = self.alloc_methodref(mref);
self.functions.get_mut(&mref)
}

pub(crate) fn functions(&self) -> &FxHashMap<MethodRefIdx, Method> {
&self.functions
}

Expand Down
22 changes: 11 additions & 11 deletions cilly/src/bin/interpreter/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ fn main() {}
use std::io::Write;
use cilly::{
asm::Assembly,
call_site::CallSite,
call_site::MethodRefIdx,
cil_node::CILNode,
cil_root::{CILRoot, SFI},
method::Method,
Expand All @@ -17,21 +17,21 @@ use fxhash::{FxBuildHasher, FxHashMap};
use value::Value;
#[derive(Debug)]
enum Exception {
MethodNotFound(CallSite),
MethodNotFound(MethodRefIdx),
LocalOutOfRange { loc: usize, lcount: usize },
ArgOutOfRange { arg: usize, lcount: usize },
AllocOffsetOutOfRange,
}
type AllocID = u32;
struct InterpreterState<'asm> {
asm: &'asm Assembly,
call_stack: Vec<(&'asm CallSite, usize, usize, cilly::cil_root::SFI)>,
call_stack: Vec<(&'asm MethodRefIdx, usize, usize, cilly::cil_root::SFI)>,
locals: Vec<Box<[Value]>>,
mem: FxHashMap<AllocID, Box<[u8]>>,
last_alloc: AllocID,
fields: FxHashMap<StaticFieldDesc, Value>,
methods: FxHashMap<AllocID, CallSite>,
inv_methods: FxHashMap<CallSite, AllocID>,
methods: FxHashMap<AllocID, MethodRefIdx>,
inv_methods: FxHashMap<MethodRefIdx, AllocID>,
last_alloc_method: AllocID,
}

Expand Down Expand Up @@ -341,7 +341,7 @@ fn eval_node<'asm>(
}
}
impl<'asm> InterpreterState<'asm> {
pub fn get_fn_ptr_alloc(&mut self, site: &CallSite) -> AllocID {
pub fn get_fn_ptr_alloc(&mut self, site: &MethodRefIdx) -> AllocID {
*self.inv_methods.entry(site.clone()).or_insert_with(|| {
let new_method = self.last_alloc_method;
self.methods.insert(new_method, site.clone());
Expand All @@ -357,7 +357,7 @@ impl<'asm> InterpreterState<'asm> {
}
pub fn try_call_extern(
&mut self,
call: &'asm CallSite,
call: &'asm MethodRefIdx,
args: &mut Box<[Value]>,
string_map: &AsmStringContainer,
) -> Result<Value, Exception> {
Expand Down Expand Up @@ -412,7 +412,7 @@ impl<'asm> InterpreterState<'asm> {
pub fn run_cctor(&mut self) -> Result<Value, Exception> {
match self.asm.cctor() {
Some(_) => self.run(
Box::<CallSite>::leak(Box::new(CallSite::builtin(
Box::<MethodRefIdx>::leak(Box::new(MethodRefIdx::builtin(
".cctor".into(),
FnSig::new(&[], Type::Void),
true,
Expand All @@ -426,7 +426,7 @@ impl<'asm> InterpreterState<'asm> {
let entry = self.asm.methods().find(|method| method.is_entrypoint());
match entry {
Some(entry) => self.run(
Box::<CallSite>::leak(Box::new(entry.call_site())),
Box::<MethodRefIdx>::leak(Box::new(entry.call_site())),
&mut vec![Value::StringArray(
std::env::args().map(|arg| arg.into()).collect(),
)]
Expand All @@ -435,15 +435,15 @@ impl<'asm> InterpreterState<'asm> {
None => Ok(Value::Undef),
}
}
pub fn method(&self, site: &'asm CallSite) -> Result<&'asm Method, Exception> {
pub fn method(&self, site: &'asm MethodRefIdx) -> Result<&'asm Method, Exception> {
self.asm
.functions()
.get(site)
.ok_or(Exception::MethodNotFound(site.clone()))
}
pub fn run(
&mut self,
call: &'asm CallSite,
call: &'asm MethodRefIdx,
args: &mut Box<[Value]>,
) -> Result<Value, Exception> {
assert_eq!(self.locals.len(), self.call_stack.len());
Expand Down
41 changes: 15 additions & 26 deletions cilly/src/bin/linker/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#![allow(clippy::module_name_repetitions)]
use cilly::{
asm::DEAD_CODE_ELIMINATION,
call_site::CallSite,
conv_usize,
libc_fns::{self, LIBC_FNS, LIBC_MODIFIES_ERRNO},
v2::{
Expand All @@ -11,6 +10,7 @@ use cilly::{
Assembly, BasicBlock, CILNode, CILRoot, ClassDef, ClassRef, Const, FnSig, IlasmFlavour,
Int, MethodImpl, Type,
},
MethodRef,
};
//use assembly::Assembly;
use lazy_static::lazy_static;
Expand Down Expand Up @@ -258,6 +258,18 @@ fn main() {
final_assembly.alloc_string("_Unwind_RaiseException"),
Box::new(|_, asm| {
let rust_exception = asm.alloc_string("RustException");
let exception_class =
asm.alloc_class_ref(ClassRef::new(rust_exception, None, false, [].into()));
let exception_ctor = MethodRef::new(
(asm.alloc_class_ref(ClassRef::new(rust_exception, None, false, [].into()))),
asm.alloc_string(".ctor"),
asm.sig(
([Type::ClassRef(exception_class), Type::Int(Int::USize)]),
Type::Void,
),
MethodKind::Constructor,
vec![].into(),
);
MethodImpl::MethodBody {
blocks: vec![cilly::v2::BasicBlock::from_v1(
&cilly::basic_block::BasicBlock::new(
Expand All @@ -267,30 +279,7 @@ fn main() {
args: Box::new([conv_usize!(
cilly::cil_node::CILNode::LDArg(0)
)]),
site: Box::new(CallSite::new(
Some(asm.alloc_class_ref(ClassRef::new(
rust_exception,
None,
false,
[].into(),
))),
".ctor".into(),
FnSig::new(
Box::new([
Type::ClassRef(asm.alloc_class_ref(
ClassRef::new(
rust_exception,
None,
false,
[].into(),
),
)),
Type::Int(Int::USize),
]),
Type::Void,
),
false,
)),
site: asm.alloc_methodref(exception_ctor),
},
)),
)
Expand Down Expand Up @@ -608,7 +597,7 @@ fn override_errno(asm: &mut Assembly) {
vec![BasicBlock::new(
vec![CILRoot::Ret {
tree: cilly::call!(
CallSite::new(
MethodRefIdx::new(
Some(ClassRef::marshal()),
"GetLastWin32Error".into(),
FnSig::new(&[], Type::Int(Int::I32)),
Expand Down
Loading
Loading