Skip to content

Commit

Permalink
Some work on typedefs + minor cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
FractalFir committed Aug 5, 2024
1 parent e17b6d7 commit 37a5eec
Show file tree
Hide file tree
Showing 17 changed files with 272 additions and 441 deletions.
346 changes: 6 additions & 340 deletions cilly/src/asm.rs

Large diffs are not rendered by default.

17 changes: 9 additions & 8 deletions cilly/src/bin/linker/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ impl LinkableFile {
&self.file
}
}
fn load_ar(r: &mut impl std::io::Read) -> std::io::Result<(Assembly, Vec<LinkableFile>)> {
let mut final_assembly = Assembly::empty();
fn load_ar(
r: &mut impl std::io::Read,
) -> std::io::Result<(cilly::v2::Assembly, Vec<LinkableFile>)> {
let mut final_assembly = cilly::v2::Assembly::default();
let mut archive = Archive::new(r);
let mut linkables = Vec::new();
// Iterate over all entries in the archive:
Expand All @@ -40,7 +42,7 @@ fn load_ar(r: &mut impl std::io::Read) -> std::io::Result<(Assembly, Vec<Linkabl
.expect("ERROR: Could not load the assembly file!");
let assembly = postcard::from_bytes(&asm_bytes)
.unwrap_or_else(|_| panic!("ERROR:Could not decode the assembly file {name}!"));
final_assembly = final_assembly.join(assembly);
final_assembly = final_assembly.link(assembly);
} else if ext.contains("o") {
let mut file_bytes = Vec::with_capacity(0x100);
entry
Expand All @@ -67,18 +69,17 @@ pub fn load_assemblies(
asm_file
.read_to_end(&mut asm_bytes)
.expect("ERROR: Could not load the assembly file!");
let assembly: cilly::asm::Assembly =
let asm: cilly::v2::Assembly =
postcard::from_bytes(&asm_bytes).expect("ERROR:Could not decode the assembly file!");
let asm = cilly::v2::Assembly::from_v1(&assembly);

final_assembly = final_assembly.link(asm);
}
for asm_path in archives {
let mut asm_file =
std::fs::File::open(asm_path).expect("ERROR: Could not open the assembly file!");
let assembly = load_ar(&mut asm_file).expect("Could not open archive");
let asm = cilly::v2::Assembly::from_v1(&assembly.0);
let (asm, linkable) = load_ar(&mut asm_file).expect("Could not open archive");
final_assembly = final_assembly.link(asm);
linkables.extend(assembly.1);
linkables.extend(linkable);
}
println!("Loaded assmeblies");
(final_assembly, linkables)
Expand Down
36 changes: 3 additions & 33 deletions cilly/src/bin/linker/main.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
#![deny(unused_must_use)]
#![allow(clippy::module_name_repetitions)]
use aot::aot_compile_mode;
use cilly::{
access_modifier,
asm::Assembly,
call,
call_site::CallSite,
conv_usize, ldc_i32,
conv_usize,
libc_fns::{LIBC_FNS, LIBC_MODIFIES_ERRNO},
method::{Method, MethodType},
v2::{
asm::{MissingMethodPatcher, ILASM_FLAVOUR},
cilnode::MethodKind,
BasicBlock, CILNode, CILRoot, ClassRef, IlasmFlavour, Int, MethodDef, MethodImpl, Type,
BasicBlock, CILNode, CILRoot, ClassRef, IlasmFlavour, Int, MethodImpl, Type,
},
DotnetTypeRef, FnSig,
};
Expand All @@ -21,39 +16,14 @@ use lazy_static::lazy_static;

mod cmd;
mod export;
use cilly::libc_fns;
mod load;
mod native_passtrough;
mod patch;
use fxhash::{FxBuildHasher, FxHashMap};
use native_passtrough::{add_shared, handle_native_passtrough, NativePastroughInfo};
use fxhash::FxHashMap;
use patch::{builtin_call, call_alias};
use std::{env, io::Write, path::Path};
mod aot;

/// Replaces `_UnwindBacktrace` with a nop.
/*fn override_backtrace(patched: &mut FxHashMap<CallSite, Method>, call: &CallSite) {
patched.insert(
call.clone(),
Method::new(
access_modifier::AccessModifer::Private,
MethodType::Static,
call.signature().clone(),
"_Unwind_Backtrace",
vec![],
vec![BasicBlock::new(
vec![
CILRoot::debug("called _Unwind_Backtrace").into(),
CILRoot::Ret { tree: ldc_i32!(4) }.into(),
],
0,
None,
)],
vec![Some("trace".into()), Some("trace_arg".into())],
),
);
}*/

fn add_mandatory_statics(asm: &mut cilly::v2::Assembly) {
let main_module = asm.main_module();
asm.add_static(
Expand Down
17 changes: 2 additions & 15 deletions cilly/src/cil_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1634,20 +1634,11 @@ impl std::ops::Neg for CILNode {
pub struct ValidationContext<'a> {
sig: &'a FnSig,
locals: &'a [(Option<IString>, Type)],
strings: &'a AsmStringContainer,
}

impl<'a> ValidationContext<'a> {
pub fn new(
sig: &'a FnSig,
locals: &'a [(Option<IString>, Type)],
strings: &'a AsmStringContainer,
) -> Self {
Self {
sig,
locals,
strings,
}
pub fn new(sig: &'a FnSig, locals: &'a [(Option<IString>, Type)]) -> Self {
Self { sig, locals }
}

pub fn sig(&self) -> &FnSig {
Expand All @@ -1657,8 +1648,4 @@ impl<'a> ValidationContext<'a> {
pub fn locals(&self) -> &[(Option<IString>, Type)] {
self.locals
}

pub fn strings(&self) -> &AsmStringContainer {
self.strings
}
}
8 changes: 2 additions & 6 deletions cilly/src/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,11 @@ impl Method {
});
self.locals = locals;
}
pub fn validate(&self, asm: &AsmStringContainer) -> Result<(), String> {
pub fn validate(&self) -> Result<(), String> {
let errs: Vec<String> = self
.blocks()
.iter()
.map(|tree| tree.validate(ValidationContext::new(&self.sig, &self.locals, asm)))
.map(|tree| tree.validate(ValidationContext::new(&self.sig, &self.locals)))
.filter_map(|err| match err {
Ok(()) => None,
Err(err) => Some(err),
Expand Down Expand Up @@ -551,10 +551,6 @@ impl Method {
&self.attributes
}

pub(crate) fn vctx<'a, 'b: 'a>(&'a self, strings: &'b AsmStringContainer) -> ValidationContext {
ValidationContext::new(&self.sig, &self.locals, strings)
}

pub(crate) fn set_blocks(&mut self, blocks: impl Into<Vec<BasicBlock>>) {
self.blocks = blocks.into();
}
Expand Down
50 changes: 49 additions & 1 deletion cilly/src/v2/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ impl Assembly {
pub fn class_mut(&mut self, id: ClassDefIdx) -> &mut ClassDef {
self.class_defs.get_mut(&id).unwrap()
}
pub fn get_class_def(&self, id: ClassDefIdx) -> &ClassDef {
self.class_defs.get(&id).unwrap()
}
pub fn class_ref(&self, cref: ClassRefIdx) -> &ClassRef {
self.class_refs.get(cref)
}
Expand Down Expand Up @@ -382,7 +385,7 @@ impl Assembly {
pub(crate) fn method_def_from_ref(&self, mref: MethodRefIdx) -> Option<&MethodDef> {
self.method_defs.get(&MethodDefIdx(mref))
}
pub fn eliminate_dead_code(&mut self) {
pub(crate) fn eliminate_dead_fns(&mut self) {
// 1st. Collect all "extern" method definitons, since those are always alive.
let mut previosly_ressurected: FxHashSet<MethodDefIdx> = self
.method_defs
Expand Down Expand Up @@ -442,6 +445,51 @@ impl Assembly {
.retain(|def| self.method_defs.contains_key(def));
});
}
pub fn eliminate_dead_code(&mut self) {
self.eliminate_dead_fns();
//self.eliminate_dead_types();
}
pub(crate) fn eliminate_dead_types(&mut self) {
let mut previosly_ressurected: FxHashSet<ClassDefIdx> = self
.method_defs()
.values()
.flat_map(|method| method.iter_types(self))
.flat_map(|tpe| tpe.iter_class_refs(self).collect::<Vec<_>>())
.flat_map(|cref| self.class_ref_to_def(cref))
.collect();
let rust_void = self.alloc_string("RustVoid");
let rust_void = self.alloc_class_ref(ClassRef::new(rust_void, None, true, vec![].into()));
if let Some(cref) = self.class_ref_to_def(rust_void) {
previosly_ressurected.insert(cref);
}

let mut to_resurrect: FxHashSet<ClassDefIdx> = FxHashSet::default();
let mut alive: FxHashSet<ClassDefIdx> = FxHashSet::default();
while !previosly_ressurected.is_empty() {
for def in previosly_ressurected.iter() {
let defids: FxHashSet<ClassDefIdx> = self
.get_class_def(*def)
.iter_types()
.flat_map(|tpe| tpe.iter_class_refs(self).collect::<Vec<_>>())
.flat_map(|cref| self.class_ref_to_def(cref))
.filter(|refid| alive.contains(refid))
.collect();

to_resurrect.extend(defids);
}
alive.extend(previosly_ressurected);
previosly_ressurected = to_resurrect;
to_resurrect = FxHashSet::default();
}
// Some cheap sanity checks
assert!(previosly_ressurected.is_empty());
assert!(to_resurrect.is_empty());
// Set the class_defs to only include alive classes
self.class_defs = alive
.iter()
.map(|id| (*id, self.class_defs.remove(id).unwrap()))
.collect();
}
/*pub fn realloc_nodes(&mut self){
}*/
Expand Down
5 changes: 1 addition & 4 deletions cilly/src/v2/asm_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@ impl Assembly {
.iter()
.map(|tpe| self.translate_type(source, *tpe))
.collect();

let cref = self.alloc_class_ref(ClassRef::new(name, asm, cref.is_valuetype(), generics));

cref
self.alloc_class_ref(ClassRef::new(name, asm, cref.is_valuetype(), generics))
}
pub(crate) fn translate_sig(&mut self, source: &Assembly, sig: FnSig) -> FnSig {
FnSig::new(
Expand Down
7 changes: 0 additions & 7 deletions cilly/src/v2/bimap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,6 @@ impl<Key: IntoBiMapIndex + Eq + Hash + Clone + Debug, Value: Eq + Hash + Clone +
pub fn get(&self, key: Key) -> &Value {
self.0.get(key.as_bimap_index().get() as usize - 1).unwrap()
}

pub fn translate(&mut self, destination: &mut Self) -> FxHashMap<Key, Key> {
let mut res = FxHashMap::default();
for (val, key) in self.1.iter_mut() {}
todo!();
res
}
}
pub type BiMapIndex = NonZeroU32;
pub trait IntoBiMapIndex {
Expand Down
13 changes: 10 additions & 3 deletions cilly/src/v2/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ impl ClassRef {
V1ClassRef::OptimizedRustStruct { name: _ } => panic!(),
}
}

/// Returns the assembly containing this typedef
pub fn asm(&self) -> Option<StringIdx> {
self.asm
}

/// The name of this class definition
pub fn name(&self) -> StringIdx {
self.name
}
Expand All @@ -105,8 +105,15 @@ pub struct ClassDef {
access: Access,
explict_size: Option<NonZeroU32>,
}

impl ClassDef {
pub(crate) fn iter_types(&self) -> impl Iterator<Item = Type> + '_ {
self.fields()
.iter()
.map(|(tpe, _, _)| tpe)
.chain(self.static_fields().iter().map(|(tpe, _, _)| tpe))
.copied()
.chain(self.extends.iter().map(|cref| Type::ClassRef(*cref)))
}
#[allow(clippy::too_many_arguments)]
pub fn new(
name: StringIdx,
Expand Down
16 changes: 13 additions & 3 deletions cilly/src/v2/fnsig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@ impl IntoBiMapIndex for SigIdx {
}
#[derive(Hash, PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct FnSig {
input: Box<[Type]>,
inputs: Box<[Type]>,
output: Type,
}

impl FnSig {
pub fn new(input: Box<[Type]>, output: Type) -> Self {
Self { input, output }
Self {
inputs: input,
output,
}
}

pub fn inputs(&self) -> &[Type] {
&self.input
&self.inputs
}

pub fn output(&self) -> &Type {
Expand All @@ -42,4 +45,11 @@ impl FnSig {
let output = Type::from_v1(signature.output(), asm);
Self::new(input, output)
}

pub fn iter_types(&self) -> impl Iterator<Item = Type> + '_ {
self.inputs()
.iter()
.copied()
.chain(std::iter::once(*self.output()))
}
}
Loading

0 comments on commit 37a5eec

Please sign in to comment.