Skip to content

Commit

Permalink
Merge pull request #57 from FractalFir/methodref
Browse files Browse the repository at this point in the history
Merge changes to the method reference repr
  • Loading branch information
FractalFir authored Oct 5, 2024
2 parents ac20e7f + c0ed0a4 commit 9c6545d
Show file tree
Hide file tree
Showing 47 changed files with 3,742 additions and 4,524 deletions.
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

0 comments on commit 9c6545d

Please sign in to comment.