Skip to content

Commit

Permalink
Typedefs now converted to the new format on the fly
Browse files Browse the repository at this point in the history
  • Loading branch information
FractalFir committed Aug 5, 2024
1 parent 37a5eec commit 728788e
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 106 deletions.
100 changes: 14 additions & 86 deletions cilly/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,9 @@ impl AssemblyExternRef {
}
}
pub type ExternFnDef = (IString, FnSig, bool);
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize)]
/// Representation of a .NET assembly.
pub struct Assembly {
/// List of types desined within the assembly.
types: FxHashMap<IString, TypeDef>,
/// List of functions defined within this assembly.
functions: FxHashMap<CallSite, Method>,
/// Callsite representing the entrypoint of this assebmly if any present.
Expand All @@ -59,28 +57,10 @@ pub struct Assembly {
static_fields: FxHashMap<IString, (Type, bool)>,
/// Initializers. Call order not guarnateed(but should match the order they are added in), but should be called after most of `.cctor` runs.
initializers: Vec<CILRoot>,
// Inner v2 assembly
inner: super::v2::Assembly,
}
impl Assembly {
/// Returns the `.cctor` function used to initialize static data
#[must_use]
pub fn cctor(&self) -> Option<&Method> {
self.functions.get(&CallSite::new(
None,
".cctor".into(),
FnSig::new(&[], Type::Void),
true,
))
}
/// Returns the `.tcctor` function used to initialize thread-local static data
#[must_use]
pub fn tcctor(&self) -> Option<&Method> {
self.functions.get(&CallSite::new(
None,
".tcctor".into(),
FnSig::new(&[], Type::Void),
true,
))
}
/// Returns the external assembly reference
#[must_use]
pub fn extern_refs(&self) -> &FxHashMap<IString, AssemblyExternRef> {
Expand All @@ -90,13 +70,13 @@ impl Assembly {
#[must_use]
pub fn empty() -> Self {
let mut res = Self {
types: FxHashMap::with_hasher(FxBuildHasher::default()),
functions: FxHashMap::with_hasher(FxBuildHasher::default()),
entrypoint: None,
extern_refs: FxHashMap::with_hasher(FxBuildHasher::default()),
static_fields: FxHashMap::with_hasher(FxBuildHasher::default()),
extern_fns: FxHashMap::with_hasher(FxBuildHasher::default()),
initializers: vec![],
inner: Default::default(),
};
res.static_fields.insert(
"GlobalAtomicLock".into(),
Expand All @@ -117,41 +97,6 @@ impl Assembly {
res.add_tcctor();
res
}
/// Joins 2 assemblies together.
#[must_use]
pub fn join(self, other: Self) -> Self {
let static_initializer = link_static_initializers(self.cctor(), other.cctor());
let tcctor = link_static_initializers(self.tcctor(), other.tcctor());
let mut types = self.types;
types.extend(other.types);
let mut functions = self.functions;
functions.extend(other.functions);
if let Some(static_initializer) = static_initializer {
functions.insert(static_initializer.call_site(), static_initializer);
}
if let Some(tcctor) = tcctor {
functions.insert(tcctor.call_site(), tcctor);
}
let entrypoint = self.entrypoint.or(other.entrypoint);
let mut extern_refs = self.extern_refs;
let mut static_fields = self.static_fields;
let mut extern_fns = self.extern_fns;
static_fields.extend(other.static_fields);
extern_refs.extend(other.extern_refs);
extern_fns.extend(other.extern_fns);
let mut initializers = self.initializers;
initializers.extend(other.initializers);

Self {
types,
functions,
entrypoint,
extern_refs,
extern_fns,
static_fields,
initializers,
}
}

/// Adds a global static field named *name* of type *tpe*
pub fn add_static(&mut self, tpe: Type, name: &str, thread_local: bool) {
Expand Down Expand Up @@ -252,18 +197,6 @@ impl Assembly {
self.functions.insert(cs, method);
}

/// Returns an interator over all methods within the assembly.
pub fn methods(&self) -> impl Iterator<Item = &Method> {
self.functions.values()
}
/// Returns an interator over all methods within the assembly.
pub fn methods_mut(&mut self) -> impl Iterator<Item = &mut Method> {
self.functions.values_mut()
}
/// Returns an iterator over all types witin the assembly.
pub fn types(&self) -> impl Iterator<Item = (&IString, &TypeDef)> {
self.types.iter()
}
/// Optimizes all the methods witin the assembly.
pub fn opt(&mut self) {
self.functions.iter_mut().for_each(|method| {
Expand All @@ -274,8 +207,8 @@ impl Assembly {
});
}
/// Adds a definition of a type to the assembly.
pub fn add_typedef(&mut self, mut type_def: TypeDef) {
self.types.insert(type_def.name().into(), type_def);
pub fn add_typedef(&mut self, type_def: TypeDef) {
super::v2::ClassDef::from_v1(&type_def, &mut self.inner);
}

/// Sets the entrypoint of the assembly to the method behind `CallSite`.
Expand All @@ -287,14 +220,10 @@ impl Assembly {
}

#[must_use]
pub fn extern_fns(&self) -> &FxHashMap<ExternFnDef, IString> {
pub(crate) fn extern_fns(&self) -> &FxHashMap<ExternFnDef, IString> {
&self.extern_fns
}

pub fn add_extern_fn(&mut self, name: IString, sig: FnSig, lib: IString, preserve_errno: bool) {
self.extern_fns.insert((name, sig, preserve_errno), lib);
}

pub fn add_initialzer(&mut self, root: CILRoot) {
self.initializers.push(root);
}
Expand All @@ -307,21 +236,21 @@ impl Assembly {
))
}

pub fn static_fields_mut(&mut self) -> &mut FxHashMap<IString, (Type, bool)> {
&mut self.static_fields
}

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

pub fn initializers(&self) -> &[CILRoot] {
pub(crate) fn initializers(&self) -> &[CILRoot] {
&self.initializers
}

pub fn static_fields(&self) -> &FxHashMap<IString, (Type, bool)> {
&self.static_fields
}

pub(crate) fn inner(&self) -> &super::v2::Assembly {
&self.inner
}
}
use lazy_static::*;
lazy_static! {
Expand Down Expand Up @@ -355,8 +284,7 @@ impl MemoryUsage for Assembly {
fn memory_usage(&self, counter: &mut impl crate::utilis::MemoryUsageCounter) -> usize {
let self_size = std::mem::size_of::<Self>();
let tpe_name = std::any::type_name::<Self>();
let types = self.types.memory_usage(counter);
counter.add_field(tpe_name, "types", types);

let functions = self.functions.memory_usage(counter);
counter.add_field(tpe_name, "types", functions);
let extern_fns = self.extern_fns.memory_usage(counter);
Expand Down
6 changes: 0 additions & 6 deletions cilly/src/utilis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,9 +663,6 @@ fn argv() {
let mut asm = Assembly::empty();
argc_argv_init_method(&mut asm);
let mut out = String::new();
asm.methods()
.find(|method| method.name().contains("argc"))
.unwrap();
}
pub trait MemoryUsage {
fn memory_usage(&self, counter: &mut impl MemoryUsageCounter) -> usize;
Expand Down Expand Up @@ -832,9 +829,6 @@ fn environ() {
get_environ(&mut asm);

let mut out = String::new();
asm.methods()
.find(|method| method.name().contains("environ"))
.unwrap();
}
#[must_use]
pub fn escape_class_name(name: &str) -> String {
Expand Down
15 changes: 8 additions & 7 deletions cilly/src/v2/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ impl std::hash::Hash for IStringWrapper {
}
pub type MissingMethodPatcher =
FxHashMap<StringIdx, Box<dyn Fn(MethodRefIdx, &mut Assembly) -> MethodImpl>>;
#[derive(Default, Serialize, Deserialize)]
#[derive(Default, Serialize, Deserialize, Clone)]
pub struct Assembly {
strings: BiMap<StringIdx, IStringWrapper>,
types: BiMap<TypeIdx, Type>,
Expand Down Expand Up @@ -177,7 +177,11 @@ impl Assembly {
let cref = self.alloc_class_ref(cref);

if let Some(dup) = self.class_defs.insert(ClassDefIdx(cref), def.clone()) {
panic!("duplicate class def. {dup:?} {def:?}");
// TODO: this is costly, consider skipping in release.
// HACK: cvoid is doing *something* bizzare, but it seems harmless, so I ignore it I guess???
if !self.get_string(dup.name()).contains("core.ffi.c_void") {
assert_eq!(dup, def, "{}", self.get_string(dup.name()));
}
}

ClassDefIdx(cref)
Expand Down Expand Up @@ -282,7 +286,7 @@ impl Assembly {
}
/// Converts the old assembly repr to the new one.
pub fn from_v1(v1: &V1Asm) -> Self {
let mut empty = Self::default();
let mut empty: Assembly = v1.inner().clone();
// Add the user defined roots
let roots = v1
.initializers()
Expand Down Expand Up @@ -338,10 +342,6 @@ impl Assembly {
empty.new_method(def);
});

//todo!();
v1.types().for_each(|(_, tdef)| {
ClassDef::from_v1(tdef, &mut empty);
});
#[cfg(debug_assertions)]
empty.sanity_check();
empty
Expand Down Expand Up @@ -449,6 +449,7 @@ impl Assembly {
self.eliminate_dead_fns();
//self.eliminate_dead_types();
}
#[allow(dead_code)]
pub(crate) fn eliminate_dead_types(&mut self) {
let mut previosly_ressurected: FxHashSet<ClassDefIdx> = self
.method_defs()
Expand Down
2 changes: 1 addition & 1 deletion cilly/src/v2/bimap.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use fxhash::{FxHashMap, FxHasher};
use serde::{Deserialize, Serialize};
use std::{collections::hash_map::Entry, fmt::Debug, hash::Hash, num::NonZeroU32};
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Clone)]
pub struct BiMap<Key, Value: Eq + Hash>(pub Vec<Value>, pub FxHashMap<Value, Key>);
impl<Key: IntoBiMapIndex + Eq + Hash + Clone, Value: Eq + Hash + Clone> Default
for BiMap<Key, Value>
Expand Down
11 changes: 5 additions & 6 deletions src/assembly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -641,16 +641,15 @@ pub fn add_allocation(
//TODO: handle VTables
let alloc_fld: IString = format!("alloc_{alloc_id:x}").into();
let field_desc = StaticFieldDescriptor::new(None, ptr!(Type::U8), alloc_fld.clone());
asm.static_fields_mut()
.insert(alloc_fld, (ptr!(Type::U8), false));
asm.add_static(ptr!(Type::U8), &alloc_fld, false);
return CILNode::LDStaticField(Box::new(field_desc));
}
GlobalAlloc::Function { .. } => {
//TODO: handle constant functions
let alloc_fld: IString = format!("alloc_{alloc_id:x}").into();
let field_desc = StaticFieldDescriptor::new(None, ptr!(Type::U8), alloc_fld.clone());
asm.static_fields_mut()
.insert(alloc_fld, (ptr!(Type::U8), false));
asm.add_static(ptr!(Type::U8), &alloc_fld, false);

return CILNode::LDStaticField(Box::new(field_desc));
//todo!("Function/Vtable allocation.");
}
Expand All @@ -665,7 +664,7 @@ pub fn add_allocation(
let byte_hash = calculate_hash(&bytes);
let alloc_fld: IString = format!("a_{}{}", encode(alloc_id), encode(byte_hash)).into();
let field_desc = StaticFieldDescriptor::new(None, ptr!(Type::U8), alloc_fld.clone());
if !asm.static_fields_mut().contains_key(&alloc_fld) {
if !asm.static_fields().contains_key(&alloc_fld) {
let init_method =
allocation_initializer_method(const_allocation, &alloc_fld, tcx, asm, tycache);
let mut blocks = if thread_local {
Expand Down Expand Up @@ -727,7 +726,7 @@ pub fn add_const_value(asm: &mut Assembly, bytes: u128, tcx: TyCtxt) -> StaticFi
let alloc_fld: IString = format!("a_{bytes:x}").into();
let raw_bytes = bytes.to_le_bytes();
let field_desc = StaticFieldDescriptor::new(None, ptr!(Type::U8), alloc_fld.clone());
if !asm.static_fields_mut().contains_key(&alloc_fld) {
if !asm.static_fields().contains_key(&alloc_fld) {
let mut trees = vec![CILRoot::STLoc {
local: 0,
tree: call!(crate::cil::malloc(tcx), [conv_usize!(ldc_u32!(16))])
Expand Down

0 comments on commit 728788e

Please sign in to comment.