Skip to content

Commit 0723f0f

Browse files
committed
Added TypeDef support. Added support for many arthmetic operations.
1 parent 4c0ab9e commit 0723f0f

16 files changed

+412
-38
lines changed

src/assembly.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ impl Assembly {
2323
}
2424
}
2525
pub fn join(self, other: Self) -> Self {
26-
let mut types = self.types.union(&other.types).cloned().collect();
27-
let mut functions = self.functions.union(&other.functions).cloned().collect();
26+
let types = self.types.union(&other.types).cloned().collect();
27+
let functions = self.functions.union(&other.functions).cloned().collect();
2828
let entrypoint = self.entrypoint.or(other.entrypoint);
2929
Self { types, functions,entrypoint }
3030
}
@@ -67,6 +67,9 @@ impl Assembly {
6767
}
6868
}
6969
method.set_ops(ops);
70+
for local in &mir.local_decls {
71+
self.add_type(local.ty, tcx);
72+
}
7073
self.functions.insert(method);
7174
Ok(())
7275
//todo!("Can't add function")
@@ -80,6 +83,14 @@ impl Assembly {
8083
pub fn types(&self) -> impl Iterator<Item = &TypeDef> {
8184
(&self.types).iter()
8285
}
86+
pub fn add_type<'ctx>(&mut self,ty:rustc_middle::ty::Ty<'ctx>,tyctx: TyCtxt<'ctx>){
87+
for type_def in TypeDef::from_ty(ty,tyctx){
88+
self.types.insert(type_def);
89+
}
90+
}
91+
pub fn add_typedef<'ctx>(&mut self,type_def:TypeDef){
92+
self.types.insert(type_def);
93+
}
8394
pub fn add_item<'tcx>(
8495
&mut self,
8596
item: MonoItem<'tcx>,

src/assembly_exporter/ilasm_exporter.rs

+111-17
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl AssemblyExporter for ILASMExporter {
2828
Self { encoded_asm }
2929
}
3030
fn add_type(&mut self, tpe: &TypeDef) {
31-
todo!("Can't add type definitions yet");
31+
type_def_cli(&mut self.encoded_asm,tpe).expect("Error");
3232
//let _ = self.types.push(tpe.clone());
3333
}
3434
fn add_method(&mut self, method: &Method) {
@@ -84,8 +84,30 @@ impl AssemblyExporter for ILASMExporter {
8484
}
8585
}
8686

87-
fn type_def_cli(tpe: &TypeDef) -> Result<IString, super::AssemblyExportError> {
88-
todo!();
87+
fn type_def_cli(mut w: impl Write,tpe: &TypeDef) -> Result<(), super::AssemblyExportError> {
88+
let name = tpe.name();
89+
let mut generics = String::new();
90+
if tpe.gargc() != 0{
91+
generics.push('<');
92+
}
93+
for i in 0..tpe.gargc(){
94+
if i != 0{
95+
generics.push(',');
96+
}
97+
generics.push_str(&format!("G{i}"));
98+
}
99+
if tpe.gargc() != 0{
100+
generics.push('>');
101+
}
102+
let extended = if let Some(extended) = tpe.extends(){
103+
todo!("Can't handle inheretence yet!");
104+
}
105+
else{
106+
"[System.Runtime]System.ValueType"
107+
};
108+
writeln!(w,"\n.class {name}{generics} extends {extended}{{");
109+
writeln!(w,"}}");
110+
Ok(())
89111
}
90112
fn absolute_path(path: &std::path::Path) -> std::io::Result<std::path::PathBuf> {
91113
if path.has_root() {
@@ -164,9 +186,24 @@ fn op_cli(op: &crate::cil_op::CILOp) -> Cow<'static, str> {
164186
.into()
165187
}
166188
}
167-
//Arthmetic
189+
//Arthmetics
168190
CILOp::Add => "add".into(),
191+
CILOp::Sub => "sub".into(),
192+
CILOp::Mul => "mul".into(),
193+
CILOp::Div => "div".into(),
194+
CILOp::Rem => "rem".into(),
195+
//Bitwise
196+
CILOp::And => "and".into(),
197+
CILOp::Or => "or".into(),
198+
CILOp::XOr => "xor".into(),
199+
//CILOp::Not => "not".into(),
200+
//Bitshifts
201+
CILOp::Shl => "shl".into(),
202+
CILOp::Shr => "shr".into(),
203+
//Comparisons
204+
CILOp::Gt => "cgt".into(),
169205
CILOp::Eq => "ceq".into(),
206+
CILOp::Lt => "clt".into(),
170207
//Arguments
171208
CILOp::LDArg(argnum) => {
172209
if *argnum < 8 {
@@ -282,21 +319,78 @@ fn op_cli(op: &crate::cil_op::CILOp) -> Cow<'static, str> {
282319
else{
283320
"conv.i8".into()
284321
}
285-
/*
286-
CILOp::ConvU => "conv.u".into(),
287-
CILOp::ConvI8 => "conv.i1".into(),
288-
CILOp::ConvU8 => "conv.u1".into(),
289-
CILOp::ConvI16 => "conv.i2".into(),
290-
CILOp::ConvU16 => "conv.u2".into(),
291-
CILOp::ConvI32 => "conv.i4".into(),
292-
CILOp::ConvU32 => "conv.u4".into(),
293-
CILOp::ConvF32 => "conv.r4".into(),
294-
CILOp::ConvI64 => "conv.i8".into(),
295-
CILOp::ConvU64 => "conv.u8".into(),
296-
CILOp::ConvF64 => "conv.r8".into(),*/
322+
CILOp::ConvUSize(checked) =>
323+
if *checked{
324+
"conv.ovf.u".into()
325+
}
326+
else{
327+
"conv.u".into()
328+
}
329+
CILOp::ConvU8(checked) =>
330+
if *checked{
331+
"conv.ovf.u1".into()
332+
}
333+
else{
334+
"conv.u1".into()
335+
}
336+
CILOp::ConvU16(checked) =>
337+
if *checked{
338+
"conv.ovf.u2".into()
339+
}
340+
else{
341+
"conv.u2".into()
342+
}
343+
CILOp::ConvU32(checked) =>
344+
if *checked{
345+
"conv.ovf.u4".into()
346+
}
347+
else{
348+
"conv.u4".into()
349+
}
350+
CILOp::ConvU64(checked) =>
351+
if *checked{
352+
"conv.ovf.u8".into()
353+
}
354+
else{
355+
"conv.u8".into()
356+
}
297357
// Pointer stuff
298358
CILOp::LDIndI8 => "ldind.i1".into(),
299359
CILOp::Pop=>"pop".into(),
360+
CILOp::Throw=>"throw".into(),
361+
CILOp::LdStr(str)=>format!("ldstr {str:?}").into(),
362+
CILOp::NewObj(call_site) => {
363+
if call_site.is_nop() {
364+
"".into()
365+
} else {
366+
//assert!(sig.inputs.is_empty());
367+
let mut inputs_iter = call_site.signature().inputs().iter();
368+
let mut input_string = String::new();
369+
if let Some(firts_arg) = inputs_iter.next() {
370+
input_string.push_str(&arg_type_cli(firts_arg));
371+
}
372+
for arg in inputs_iter {
373+
input_string.push(',');
374+
input_string.push_str(&arg_type_cli(arg));
375+
}
376+
let prefix = if call_site.is_static() {
377+
""
378+
} else {
379+
"instance"
380+
};
381+
let owner_name = match &call_site.class() {
382+
Some(owner) => format!("{}::", dotnet_type_ref_cli(&owner)),
383+
None => "".into(),
384+
};
385+
//println!("inputs:{inputs:?} input_string: {input_string}",inputs = call_site.signature.inputs);
386+
format!(
387+
"newobj {prefix} {output} {owner_name}{function_name}({input_string})\n",
388+
function_name = call_site.name(),
389+
output = output_type_cli(&call_site.signature().output())
390+
)
391+
.into()
392+
}
393+
}
300394
_ => todo!("Unsuported op {op:?}"),
301395
}
302396
}
@@ -344,7 +438,7 @@ fn type_cli(tpe: &Type) -> Cow<'static, str> {
344438
Type::Ptr(inner) => format!("{inner}*", inner = type_cli(inner)).into(),
345439
Type::DotnetType(dotnet_type) => dotnet_type_ref_cli(dotnet_type).into(),
346440
//Special type
347-
Type::Unresolved => "unresolved".into(),
441+
Type::Unresolved => "Unresolved".into(),
348442
Type::Bool => "bool".into(),
349443
Type::DotnetChar => "char".into(),
350444
//_ => todo!("Unsuported type {tpe:?}"),

src/binop.rs

+99-1
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,56 @@ pub(crate) fn binop_unchecked<'ctx>(
1818
.into_iter()
1919
.flatten()
2020
.collect(),
21+
BinOp::Sub | BinOp::SubUnchecked => [ops_a, ops_b, sub_unchecked(ty_a, ty_b)]
22+
.into_iter()
23+
.flatten()
24+
.collect(),
2125
BinOp::Ne => [ops_a, ops_b, ne_unchecked(ty_a, ty_b)]
2226
.into_iter()
2327
.flatten()
2428
.collect(),
25-
_ => todo!("Unsupported bionp {binop:?}"),
29+
BinOp::Eq => [ops_a, ops_b, eq_unchecked(ty_a, ty_b)]
30+
.into_iter()
31+
.flatten()
32+
.collect(),
33+
BinOp::Lt => [ops_a, ops_b, lt_unchecked(ty_a, ty_b)]
34+
.into_iter()
35+
.flatten()
36+
.collect(),
37+
BinOp::Gt => [ops_a, ops_b, gt_unchecked(ty_a, ty_b)]
38+
.into_iter()
39+
.flatten()
40+
.collect(),
41+
BinOp::BitAnd=>[ops_a, ops_b, bit_and_unchecked(ty_a, ty_b)].into_iter()
42+
.flatten()
43+
.collect(),
44+
BinOp::BitOr=>[ops_a, ops_b, bit_or_unchecked(ty_a, ty_b)].into_iter()
45+
.flatten()
46+
.collect(),
47+
BinOp::BitXor=>[ops_a, ops_b, bit_xor_unchecked(ty_a, ty_b)].into_iter()
48+
.flatten()
49+
.collect(),
50+
BinOp::Rem =>[ops_a, ops_b, rem_unchecked(ty_a, ty_b)].into_iter()
51+
.flatten()
52+
.collect(),
53+
BinOp::Shl| BinOp::ShlUnchecked =>[ops_a, ops_b, shl_unchecked(ty_a, ty_b)].into_iter()
54+
.flatten()
55+
.collect(),
56+
BinOp::Shr | BinOp::ShrUnchecked =>[ops_a, ops_b, shr_unchecked(ty_a, ty_b)].into_iter()
57+
.flatten()
58+
.collect(),
59+
BinOp::Mul | BinOp::MulUnchecked =>[ops_a, ops_b, mul_unchecked(ty_a, ty_b)].into_iter()
60+
.flatten()
61+
.collect(),
62+
BinOp::Div =>[ops_a, ops_b, div_unchecked(ty_a, ty_b)].into_iter()
63+
.flatten()
64+
.collect(),
65+
BinOp::Ge=>[ops_a, ops_b, lt_unchecked(ty_a, ty_b),vec![CILOp::LdcI32(0), CILOp::Eq]].into_iter().flatten()
66+
.collect(),
67+
BinOp::Le=>[ops_a, ops_b, gt_unchecked(ty_a, ty_b),vec![CILOp::LdcI32(0), CILOp::Eq]].into_iter().flatten()
68+
.collect(),
69+
BinOp::Offset=>todo!("Offset of operator unsuported!"),
70+
//_ => todo!("Unsupported bionp {binop:?}"),
2671
}
2772
}
2873
fn add_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
@@ -45,6 +90,59 @@ fn add_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
4590
_ => todo!("can't add numbers of types {ty_a} and {ty_b}"),
4691
}
4792
}
93+
fn sub_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
94+
match ty_a.kind() {
95+
TyKind::Int(int_ty) => {
96+
if let IntTy::I128 = int_ty {
97+
todo!("Can't add 128 bit intigers yet!");
98+
} else {
99+
vec![CILOp::Sub]
100+
}
101+
}
102+
TyKind::Uint(uint_ty) => {
103+
if let UintTy::U128 = uint_ty {
104+
todo!("Can't add 128 bit intigers yet!");
105+
} else {
106+
vec![CILOp::Sub]
107+
}
108+
}
109+
TyKind::Float(_) => vec![CILOp::Sub],
110+
_ => todo!("can't add numbers of types {ty_a} and {ty_b}"),
111+
}
112+
}
48113
fn ne_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
49114
vec![CILOp::Eq, CILOp::LdcI32(0), CILOp::Eq]
50115
}
116+
fn eq_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
117+
vec![CILOp::Eq]
118+
}
119+
fn lt_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
120+
vec![CILOp::Lt]
121+
}
122+
fn gt_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
123+
vec![CILOp::Lt]
124+
}
125+
fn bit_and_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
126+
vec![CILOp::And]
127+
}
128+
fn bit_or_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
129+
vec![CILOp::Or]
130+
}
131+
fn bit_xor_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
132+
vec![CILOp::XOr]
133+
}
134+
fn rem_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
135+
vec![CILOp::Rem]
136+
}
137+
fn shr_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
138+
vec![CILOp::Shr]
139+
}
140+
fn shl_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
141+
vec![CILOp::Shl]
142+
}
143+
fn mul_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
144+
vec![CILOp::Mul]
145+
}
146+
fn div_unchecked<'ctx>(ty_a: Ty<'ctx>, ty_b: Ty<'ctx>) -> Vec<CILOp> {
147+
vec![CILOp::Div]
148+
}

src/casts.rs

Whitespace-only changes.

src/cil_op.rs

+25
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ pub enum CILOp {
7070
GoTo(u32),
7171
BEq(u32),
7272
Call(Box<CallSite>),
73+
Throw,
7374
Ret,
7475
// Load/Store/AdressOf local
7576
LDLoc(u32),
@@ -84,20 +85,44 @@ pub enum CILOp {
8485
// Load constant float
8586
LdcF32(f32),
8687
LdcF64(f64),
88+
// Load string literal
89+
LdStr(IString),
8790
// Signed intieger convertions
8891
ConvI8(bool),
8992
ConvI16(bool),
9093
ConvI32(bool),
9194
ConvI64(bool),
9295
ConvISize(bool),
96+
// Unsigned intieger convertions
97+
ConvU8(bool),
98+
ConvU16(bool),
99+
ConvU32(bool),
100+
ConvU64(bool),
101+
ConvUSize(bool),
93102
// Pointer
94103
LDIndI8,
95104
//Debugging
96105
Comment(IString),
97106
// Arthmetic Operations
98107
Add,
108+
And,
109+
Div,
110+
Rem,
111+
Shr,
112+
Shl,
113+
Sub,
114+
Mul,
115+
Or,
116+
XOr,
117+
Not,
118+
Neg,
99119
// Comparisons
100120
Eq,
121+
Lt,
122+
Gt,
101123
//Special
102124
Pop,
125+
//OOP
126+
NewObj(Box<CallSite>),
127+
103128
}

0 commit comments

Comments
 (0)