From 5ded87241617abdfc0a5153e9308b40a7f141dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Kostrubiec?= Date: Tue, 20 Feb 2024 23:50:13 +0100 Subject: [PATCH] Moved unops to use CILTrees --- src/aggregate.rs | 96 ++++++----- src/assembly_exporter/ilasm_op.rs | 4 +- src/binop.rs | 6 +- src/checked_binop.rs | 6 +- src/cil_tree/cil_node.rs | 29 +++- src/constant.rs | 265 ++++++++++++++++-------------- src/operand.rs | 2 +- src/place/body.rs | 8 +- src/place/get.rs | 4 +- src/rvalue.rs | 58 ++++--- src/statement.rs | 9 +- src/terminator/call.rs | 90 +++++----- src/terminator/intrinsics/mod.rs | 228 +++++++++++-------------- src/terminator/mod.rs | 77 ++++----- src/unop.rs | 83 ++++++---- 15 files changed, 493 insertions(+), 472 deletions(-) diff --git a/src/aggregate.rs b/src/aggregate.rs index 5df97f3c..e4b0d57b 100644 --- a/src/aggregate.rs +++ b/src/aggregate.rs @@ -27,7 +27,8 @@ pub fn handle_aggregate<'tyctx>( .map(|operand| { ( operand.0 as u32, - crate::operand::handle_operand(operand.1, tyctx, method, method_instance, tycache).flatten(), + crate::operand::handle_operand(operand.1, tyctx, method, method_instance, tycache) + .flatten(), ) }) .collect(); @@ -90,13 +91,10 @@ pub fn handle_aggregate<'tyctx>( ops.extend(value.1); ops.push(CILOp::Call(call_site.clone())); } - ops.extend(super::place::place_get( - target_location, - tyctx, - method, - method_instance, - tycache, - ).flatten()); + ops.extend( + super::place::place_get(target_location, tyctx, method, method_instance, tycache) + .flatten(), + ); ops } AggregateKind::Tuple => { @@ -130,13 +128,10 @@ pub fn handle_aggregate<'tyctx>( name.into(), ))); } - ops.extend(super::place::place_get( - target_location, - tyctx, - method, - method_instance, - tycache, - ).flatten()); + ops.extend( + super::place::place_get(target_location, tyctx, method, method_instance, tycache) + .flatten(), + ); ops } AggregateKind::Closure(_def_id, _args) => { @@ -155,13 +150,9 @@ pub fn handle_aggregate<'tyctx>( let field_ty = crate::utilis::monomorphize(&method_instance, value.ty(method, tyctx), tyctx); let field_ty = tycache.type_from_cache(field_ty, tyctx, Some(method_instance)); - closure_constructor.extend(handle_operand( - value, - tyctx, - method, - method_instance, - tycache, - ).flatten()); + closure_constructor.extend( + handle_operand(value, tyctx, method, method_instance, tycache).flatten(), + ); closure_constructor.push(CILOp::STField( FieldDescriptor::new( closure_dotnet.clone(), @@ -180,13 +171,9 @@ pub fn handle_aggregate<'tyctx>( method_instance, tycache, ); - ops.extend(place_get( - target_location, - tyctx, - method, - method_instance, - tycache, - ).flatten()); + ops.extend( + place_get(target_location, tyctx, method, method_instance, tycache).flatten(), + ); ops } _ => todo!("Unsuported aggregate kind {aggregate_kind:?}"), @@ -247,13 +234,16 @@ fn aggregate_adt<'tyctx>( ); ops.push(CILOp::STField(field_desc.into())); } - ops.extend(crate::place::place_get( - target_location, - tyctx, - method, - method_instance, - type_cache, - ).flatten()); + ops.extend( + crate::place::place_get( + target_location, + tyctx, + method, + method_instance, + type_cache, + ) + .flatten(), + ); ops } AdtKind::Enum => { @@ -323,13 +313,16 @@ fn aggregate_adt<'tyctx>( field_name, )))); } - ops.extend(crate::place::place_get( - target_location, - tyctx, - method, - method_instance, - type_cache, - ).flatten()); + ops.extend( + crate::place::place_get( + target_location, + tyctx, + method, + method_instance, + type_cache, + ) + .flatten(), + ); ops } AdtKind::Union => { @@ -363,13 +356,16 @@ fn aggregate_adt<'tyctx>( ops.push(CILOp::STField(field_desc)); } - ops.extend(crate::place::place_get( - target_location, - tyctx, - method, - method_instance, - type_cache, - ).flatten()); + ops.extend( + crate::place::place_get( + target_location, + tyctx, + method, + method_instance, + type_cache, + ) + .flatten(), + ); ops } } diff --git a/src/assembly_exporter/ilasm_op.rs b/src/assembly_exporter/ilasm_op.rs index 8ec6319d..e2ad2134 100644 --- a/src/assembly_exporter/ilasm_op.rs +++ b/src/assembly_exporter/ilasm_op.rs @@ -383,9 +383,9 @@ pub fn op_cli(op: &crate::cil::CILOp) -> Cow<'static, str> { } } CILOp::ConvF32=> "conv.r4".into(), - CILOp::ConvF64 => + CILOp::ConvF64 => "conv.r8".into(), - CILOp::ConvF64Un => + CILOp::ConvF64Un => "conv.r.un".into(), // Pointer stuff CILOp::LDIndI8 => "ldind.i1".into(), diff --git a/src/binop.rs b/src/binop.rs index 72e55eaf..e35f6cca 100644 --- a/src/binop.rs +++ b/src/binop.rs @@ -15,8 +15,10 @@ pub(crate) fn binop_unchecked<'tyctx>( method_instance: Instance<'tyctx>, tycache: &mut TyCache, ) -> Vec { - let ops_a = crate::operand::handle_operand(operand_a, tyctx, method, method_instance, tycache).flatten(); - let ops_b = crate::operand::handle_operand(operand_b, tyctx, method, method_instance, tycache).flatten(); + let ops_a = crate::operand::handle_operand(operand_a, tyctx, method, method_instance, tycache) + .flatten(); + let ops_b = crate::operand::handle_operand(operand_b, tyctx, method, method_instance, tycache) + .flatten(); let ty_a = operand_a.ty(&method.local_decls, tyctx); let ty_b = operand_b.ty(&method.local_decls, tyctx); match binop { diff --git a/src/checked_binop.rs b/src/checked_binop.rs index cdb6c2fe..270e456e 100644 --- a/src/checked_binop.rs +++ b/src/checked_binop.rs @@ -17,8 +17,10 @@ pub(crate) fn binop_checked<'tyctx>( method_instance: Instance<'tyctx>, cache: &mut TyCache, ) -> Vec { - let ops_a = crate::operand::handle_operand(operand_a, tyctx, method, method_instance, cache).flatten(); - let ops_b = crate::operand::handle_operand(operand_b, tyctx, method, method_instance, cache).flatten(); + let ops_a = + crate::operand::handle_operand(operand_a, tyctx, method, method_instance, cache).flatten(); + let ops_b = + crate::operand::handle_operand(operand_b, tyctx, method, method_instance, cache).flatten(); let ty_a = operand_a.ty(&method.local_decls, tyctx); let ty_a = crate::utilis::monomorphize(&method_instance, ty_a, tyctx); let ty_b = operand_b.ty(&method.local_decls, tyctx); diff --git a/src/cil_tree/cil_node.rs b/src/cil_tree/cil_node.rs index a57ef5e2..5c70a169 100644 --- a/src/cil_tree/cil_node.rs +++ b/src/cil_tree/cil_node.rs @@ -12,7 +12,7 @@ pub enum CILNode { LDLocA(u32), LDArgA(u32), BlackBox(Box), - + ConvF32(Box), ConvF64(Box), SizeOf(Box), @@ -69,7 +69,9 @@ pub enum CILNode { LdcU32(u32), LdcF64(f64), LdcF32(f32), - LoadGlobalAllocPtr { alloc_id: u64 }, + LoadGlobalAllocPtr { + alloc_id: u64, + }, ConvU8(Box), ConvU16(Box), ConvU32(Box), @@ -81,6 +83,9 @@ pub enum CILNode { ConvI64(Box), ConvISize(Box), Volatile(Box), + Neg(Box), + Not(Box), + Eq(Box, Box), } impl CILNode { pub fn flatten(&self) -> Vec { @@ -96,7 +101,7 @@ impl CILNode { let mut res = vec![CILOp::Volatile]; res.extend(inner.flatten()); res - }, + } Self::ConvUSize(inner) => append_vec(inner.flatten(), CILOp::ConvUSize(false)), Self::ConvU8(inner) => append_vec(inner.flatten(), CILOp::ConvU8(false)), @@ -118,6 +123,10 @@ impl CILNode { Self::LDIndI64 { ptr } => append_vec(ptr.flatten(), CILOp::LDIndI64), Self::LDIndISize { ptr } => append_vec(ptr.flatten(), CILOp::LDIndISize), Self::LdObj { ptr, obj } => append_vec(ptr.flatten(), CILOp::LdObj(obj.clone())), + + Self::Neg(inner) => append_vec(inner.flatten(), CILOp::Neg), + Self::Not(inner) => append_vec(inner.flatten(), CILOp::Not), + Self::LDFieldAdress { addr, field } => { append_vec(addr.flatten(), CILOp::LDFieldAdress(field.clone().into())) } @@ -132,6 +141,12 @@ impl CILNode { res.push(CILOp::Add); res } + Self::Eq(a, b) => { + let mut res = a.flatten(); + res.extend(b.flatten()); + res.push(CILOp::Eq); + res + } Self::Mul(a, b) => { let mut res = a.flatten(); res.extend(b.flatten()); @@ -143,9 +158,7 @@ impl CILNode { parrent.extend(ops.iter().cloned()); parrent } - Self::RawOpsParrentless { ops } => { - ops.clone().into() - } + Self::RawOpsParrentless { ops } => ops.clone().into(), Self::Call { args, site } => { let mut res: Vec = args.iter().map(|arg| arg.flatten()).flatten().collect(); res.push(CILOp::Call(site.clone())); @@ -157,7 +170,9 @@ impl CILNode { Self::LdcU32(val) => vec![CILOp::LdcU32(*val)], Self::LdcF64(val) => vec![CILOp::LdcF64(*val)], Self::LdcF32(val) => vec![CILOp::LdcF32(*val)], - Self::LoadGlobalAllocPtr{alloc_id} => vec![CILOp::LoadGlobalAllocPtr { alloc_id: *alloc_id }] + Self::LoadGlobalAllocPtr { alloc_id } => vec![CILOp::LoadGlobalAllocPtr { + alloc_id: *alloc_id, + }], } } } diff --git a/src/constant.rs b/src/constant.rs index d23c219f..789e1ea3 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -1,5 +1,7 @@ use crate::{ - cil::{CILOp, CallSite, FieldDescriptor, StaticFieldDescriptor}, cil_tree::cil_node::CILNode, r#type::{DotnetTypeRef, TyCache, Type} + cil::{CILOp, CallSite, FieldDescriptor, StaticFieldDescriptor}, + cil_tree::cil_node::CILNode, + r#type::{DotnetTypeRef, TyCache, Type}, }; use rustc_abi::Size; use rustc_middle::mir::{ @@ -15,7 +17,7 @@ pub fn handle_constant<'ctx>( method: &rustc_middle::mir::Body<'ctx>, method_instance: Instance<'ctx>, tycache: &mut TyCache, -) -> CILNode{ +) -> CILNode { let constant = constant_op.const_; let constant = crate::utilis::monomorphize(&method_instance, constant, tyctx); let evaluated = constant @@ -604,14 +606,14 @@ fn create_const_from_data<'ctx>( //eprintln!("Creating const {ty:?} from data of length {len}."); //create_const_from_slice(ty, tyctx, bytes, method_instance, tycache) } else { - + //panic!("Constant requires rellocation support!"); } let ptr = CILNode::LoadGlobalAllocPtr { alloc_id: alloc_id.0.into(), }; let ty = crate::utilis::monomorphize(&method_instance, ty, tyctx); - crate::place::deref_op(ty.into(), tyctx, &method_instance, tycache,ptr) + crate::place::deref_op(ty.into(), tyctx, &method_instance, tycache, ptr) } fn load_const_value<'ctx>( @@ -629,11 +631,14 @@ fn load_const_value<'ctx>( ConstValue::ZeroSized => { let tpe = crate::utilis::monomorphize(&method_instance, const_ty, tyctx); let tpe = tycache.type_from_cache(tpe, tyctx, Some(method_instance)); - CILNode::RawOpsParrentless{ops:[ - CILOp::NewTMPLocal(tpe.into()), - CILOp::LoadTMPLocal, - CILOp::FreeTMPLocal, - ].into()} + CILNode::RawOpsParrentless { + ops: [ + CILOp::NewTMPLocal(tpe.into()), + CILOp::LoadTMPLocal, + CILOp::FreeTMPLocal, + ] + .into(), + } } ConstValue::Slice { data, meta } => { let slice_type = tycache.type_from_cache(const_ty, tyctx, Some(method_instance)); @@ -649,19 +654,21 @@ fn load_const_value<'ctx>( let alloc_id = tyctx.reserve_and_set_memory_alloc(data); let alloc_id: u64 = crate::utilis::alloc_id_to_u64(alloc_id); - CILNode::RawOpsParrentless{ops:[ - CILOp::NewTMPLocal(slice_type.into()), - CILOp::LoadAddresOfTMPLocal, - CILOp::LdcI64(meta as i64), - CILOp::ConvUSize(false), - CILOp::STField(metadata_field.into()), - CILOp::LoadAddresOfTMPLocal, - CILOp::LoadGlobalAllocPtr { alloc_id }, - CILOp::STField(ptr_field.into()), - CILOp::LoadTMPLocal, - CILOp::FreeTMPLocal, - ].into() - } + CILNode::RawOpsParrentless { + ops: [ + CILOp::NewTMPLocal(slice_type.into()), + CILOp::LoadAddresOfTMPLocal, + CILOp::LdcI64(meta as i64), + CILOp::ConvUSize(false), + CILOp::STField(metadata_field.into()), + CILOp::LoadAddresOfTMPLocal, + CILOp::LoadGlobalAllocPtr { alloc_id }, + CILOp::STField(ptr_field.into()), + CILOp::LoadTMPLocal, + CILOp::FreeTMPLocal, + ] + .into(), + } } ConstValue::Indirect { alloc_id, offset } => { create_const_from_data( @@ -703,34 +710,40 @@ fn load_const_scalar<'ctx>( if name == "__rust_alloc_error_handler_should_panic" || name == "__rust_no_alloc_shim_is_unstable" { - return CILNode::RawOpsParrentless{ops:[ - CILOp::LDStaticField( - StaticFieldDescriptor::new(None, Type::U8, name.clone().into()) - .into(), - ), - CILOp::NewTMPLocal(Type::U8.into()), - CILOp::SetTMPLocal, - CILOp::LoadAddresOfTMPLocal, - CILOp::ConvUSize(false), - CILOp::FreeTMPLocal, - ].into()}; + return CILNode::RawOpsParrentless { + ops: [ + CILOp::LDStaticField( + StaticFieldDescriptor::new(None, Type::U8, name.clone().into()) + .into(), + ), + CILOp::NewTMPLocal(Type::U8.into()), + CILOp::SetTMPLocal, + CILOp::LoadAddresOfTMPLocal, + CILOp::ConvUSize(false), + CILOp::FreeTMPLocal, + ] + .into(), + }; } if name == "environ" { - return CILNode::RawOpsParrentless{ops:[ - CILOp::LDStaticField( - StaticFieldDescriptor::new( - None, - Type::Ptr(Type::Ptr(Type::U8.into()).into()), - name.clone().into(), - ) - .into(), - ), - CILOp::NewTMPLocal(Type::U8.into()), - CILOp::SetTMPLocal, - CILOp::LoadAddresOfTMPLocal, - CILOp::ConvUSize(false), - CILOp::FreeTMPLocal, - ].into()}; + return CILNode::RawOpsParrentless { + ops: [ + CILOp::LDStaticField( + StaticFieldDescriptor::new( + None, + Type::Ptr(Type::Ptr(Type::U8.into()).into()), + name.clone().into(), + ) + .into(), + ), + CILOp::NewTMPLocal(Type::U8.into()), + CILOp::SetTMPLocal, + CILOp::LoadAddresOfTMPLocal, + CILOp::ConvUSize(false), + CILOp::FreeTMPLocal, + ] + .into(), + }; } let attrs = tyctx.codegen_fn_attrs(def_id); @@ -752,10 +765,13 @@ fn load_const_scalar<'ctx>( return CILNode::LoadGlobalAllocPtr { alloc_id }; } GlobalAlloc::Memory(_const_allocation) => { - - return CILNode::Add(CILNode::LoadGlobalAllocPtr { - alloc_id: alloc_id.alloc_id().0.into(), - }.into(), CILNode::ConvUSize(CILNode::LdcU64(offset.bytes() as u64).into()).into()); + return CILNode::Add( + CILNode::LoadGlobalAllocPtr { + alloc_id: alloc_id.alloc_id().0.into(), + } + .into(), + CILNode::ConvUSize(CILNode::LdcU64(offset.bytes() as u64).into()).into(), + ); } _ => todo!("Unhandled global alloc {global_alloc:?}"), } @@ -774,11 +790,14 @@ fn load_const_scalar<'ctx>( TyKind::RawPtr(_) => CILNode::ConvUSize(CILNode::LdcU64(scalar_u128 as u64).into()), TyKind::Tuple(elements) => { if elements.is_empty() { - CILNode::RawOpsParrentless { ops: [CILOp::NewTMPLocal(Type::Void.into()), - CILOp::LoadTMPLocal, - CILOp::FreeTMPLocal, - ].into() } - + CILNode::RawOpsParrentless { + ops: [ + CILOp::NewTMPLocal(Type::Void.into()), + CILOp::LoadTMPLocal, + CILOp::FreeTMPLocal, + ] + .into(), + } } else { //asssert!(elements.len() == 1, "Mulit element const tuples not supported yet!"); let tuple_dotnet = tpe.clone().as_dotnet().unwrap(); @@ -851,24 +870,27 @@ fn load_const_scalar<'ctx>( ], &Type::Void, ); - CILNode::RawOpsParrentless { ops: [CILOp::NewTMPLocal(Type::U128.into()), - CILOp::LoadAddresOfTMPLocal, - CILOp::LdcI64(high), - CILOp::ConvU64(false), - CILOp::LdcI64(low), - CILOp::ConvU64(false), - CILOp::Call(CallSite::boxed( - Some(DotnetTypeRef::uint_128()), - ".ctor".into(), - ctor_sig, - false, - )), - CILOp::LoadAddresOfTMPLocal, - CILOp::ConvUSize(false), - CILOp::LdObj(tpe.into()), - CILOp::FreeTMPLocal, - ].into() } - + CILNode::RawOpsParrentless { + ops: [ + CILOp::NewTMPLocal(Type::U128.into()), + CILOp::LoadAddresOfTMPLocal, + CILOp::LdcI64(high), + CILOp::ConvU64(false), + CILOp::LdcI64(low), + CILOp::ConvU64(false), + CILOp::Call(CallSite::boxed( + Some(DotnetTypeRef::uint_128()), + ".ctor".into(), + ctor_sig, + false, + )), + CILOp::LoadAddresOfTMPLocal, + CILOp::ConvUSize(false), + CILOp::LdObj(tpe.into()), + CILOp::FreeTMPLocal, + ] + .into(), + } } _ => todo!("Can't load const ADT scalars of type {scalar_type:?}"), }, @@ -876,7 +898,7 @@ fn load_const_scalar<'ctx>( _ => todo!("Can't load scalar constants of type {scalar_type:?}!"), } } -fn load_const_float(value: u128, int_type: &FloatTy, _tyctx: TyCtxt) ->CILNode{ +fn load_const_float(value: u128, int_type: &FloatTy, _tyctx: TyCtxt) -> CILNode { match int_type { FloatTy::F32 => { let value = f32::from_ne_bytes((value as u32).to_ne_bytes()); @@ -898,12 +920,11 @@ pub fn load_const_int(value: u128, int_type: &IntTy) -> CILNode { let value = i16::from_ne_bytes((value as u16).to_ne_bytes()); CILNode::ConvI16(CILNode::LdcI32(value as i32).into()) } - IntTy::I32 => - CILNode::LdcI32(i32::from_ne_bytes((value as u32).to_ne_bytes())), - IntTy::I64 => { - CILNode::LdcI64(i64::from_ne_bytes((value as u64).to_ne_bytes())) - } - IntTy::Isize => CILNode::ConvISize(CILNode::LdcI64(i64::from_ne_bytes((value as u64).to_ne_bytes())).into()), + IntTy::I32 => CILNode::LdcI32(i32::from_ne_bytes((value as u32).to_ne_bytes())), + IntTy::I64 => CILNode::LdcI64(i64::from_ne_bytes((value as u64).to_ne_bytes())), + IntTy::Isize => CILNode::ConvISize( + CILNode::LdcI64(i64::from_ne_bytes((value as u64).to_ne_bytes())).into(), + ), IntTy::I128 => { let low = (value & u128::from(u64::MAX)) as u64; let high = (value >> 64) as u64; @@ -918,24 +939,27 @@ pub fn load_const_int(value: u128, int_type: &IntTy) -> CILNode { ], &Type::Void, ); - CILNode::RawOpsParrentless { ops: [ - CILOp::NewTMPLocal(Type::I128.into()), - CILOp::LoadAddresOfTMPLocal, - CILOp::LdcI64(high), - CILOp::ConvI64(false), - CILOp::ConvU64(false), - CILOp::LdcI64(low), - CILOp::ConvI64(false), - CILOp::ConvU64(false), - CILOp::Call(CallSite::boxed( - Some(DotnetTypeRef::int_128()), - ".ctor".into(), - ctor_sig, - false, - )), - CILOp::LoadTMPLocal, - CILOp::FreeTMPLocal, - ].into() } + CILNode::RawOpsParrentless { + ops: [ + CILOp::NewTMPLocal(Type::I128.into()), + CILOp::LoadAddresOfTMPLocal, + CILOp::LdcI64(high), + CILOp::ConvI64(false), + CILOp::ConvU64(false), + CILOp::LdcI64(low), + CILOp::ConvI64(false), + CILOp::ConvU64(false), + CILOp::Call(CallSite::boxed( + Some(DotnetTypeRef::int_128()), + ".ctor".into(), + ctor_sig, + false, + )), + CILOp::LoadTMPLocal, + CILOp::FreeTMPLocal, + ] + .into(), + } } } } @@ -950,7 +974,7 @@ pub fn load_const_uint(value: u128, int_type: &UintTy) -> CILNode { CILNode::ConvU16(CILNode::LdcU32(value as u32).into()) } UintTy::U32 => CILNode::ConvU32(CILNode::LdcU32(value as u32).into()), - UintTy::U64 => CILNode::ConvU64(CILNode::LdcU64(value as u64).into()), + UintTy::U64 => CILNode::ConvU64(CILNode::LdcU64(value as u64).into()), UintTy::Usize => CILNode::ConvUSize(CILNode::LdcU64(value as u64).into()), UintTy::U128 => { let low = (value & u128::from(u64::MAX)) as u64; @@ -965,24 +989,27 @@ pub fn load_const_uint(value: u128, int_type: &UintTy) -> CILNode { ], &Type::Void, ); - CILNode::RawOpsParrentless { ops:vec![ - CILOp::NewTMPLocal(Type::U128.into()), - CILOp::LoadAddresOfTMPLocal, - CILOp::LdcI64(high), - CILOp::ConvI64(false), - CILOp::ConvU64(false), - CILOp::LdcI64(low), - CILOp::ConvI64(false), - CILOp::ConvU64(false), - CILOp::Call(CallSite::boxed( - Some(DotnetTypeRef::uint_128()), - ".ctor".into(), - ctor_sig, - false, - )), - CILOp::LoadTMPLocal, - CILOp::FreeTMPLocal, - ].into() } + CILNode::RawOpsParrentless { + ops: vec![ + CILOp::NewTMPLocal(Type::U128.into()), + CILOp::LoadAddresOfTMPLocal, + CILOp::LdcI64(high), + CILOp::ConvI64(false), + CILOp::ConvU64(false), + CILOp::LdcI64(low), + CILOp::ConvI64(false), + CILOp::ConvU64(false), + CILOp::Call(CallSite::boxed( + Some(DotnetTypeRef::uint_128()), + ".ctor".into(), + ctor_sig, + false, + )), + CILOp::LoadTMPLocal, + CILOp::FreeTMPLocal, + ] + .into(), + } } } } diff --git a/src/operand.rs b/src/operand.rs index e5ad1582..cf664e62 100644 --- a/src/operand.rs +++ b/src/operand.rs @@ -11,7 +11,7 @@ pub(crate) fn handle_operand<'ctx>( tycache: &mut crate::r#type::TyCache, ) -> CILNode { match operand { - Operand::Copy(place) | Operand::Move(place)=> { + Operand::Copy(place) | Operand::Move(place) => { crate::place::place_get(place, tyctx, method, method_instance, tycache) } Operand::Constant(const_val) => { diff --git a/src/place/body.rs b/src/place/body.rs index 4061f663..4c81859a 100644 --- a/src/place/body.rs +++ b/src/place/body.rs @@ -265,7 +265,7 @@ pub fn place_elem_body<'ctx>( false, ) .into(), - args: [parrent_node,CILNode::ConvUSize(index.into())].into(), + args: [parrent_node, CILNode::ConvUSize(index.into())].into(), }; ((element).into(), ops) } else { @@ -280,7 +280,7 @@ pub fn place_elem_body<'ctx>( false, ) .into(), - args: [parrent_node,CILNode::ConvUSize(index.into())].into(), + args: [parrent_node, CILNode::ConvUSize(index.into())].into(), }; ((element).into(), ops) } @@ -360,7 +360,7 @@ pub fn place_elem_body<'ctx>( false, ) .into(), - args: [parrent_node,CILNode::ConvUSize(index.into())].into(), + args: [parrent_node, CILNode::ConvUSize(index.into())].into(), }; ((element_ty).into(), ops) } else { @@ -375,7 +375,7 @@ pub fn place_elem_body<'ctx>( false, ) .into(), - args: [parrent_node,CILNode::ConvUSize(index.into())].into(), + args: [parrent_node, CILNode::ConvUSize(index.into())].into(), }; ((element_ty).into(), ops) } diff --git a/src/place/get.rs b/src/place/get.rs index 6c145958..a08f076e 100644 --- a/src/place/get.rs +++ b/src/place/get.rs @@ -154,7 +154,7 @@ fn place_elem_get<'a>( false, ) .into(), - args: [addr_calc,CILNode::ConvUSize(index.into())].into(), + args: [addr_calc, CILNode::ConvUSize(index.into())].into(), } } _ => { @@ -224,7 +224,7 @@ fn place_elem_get<'a>( false, ) .into(), - args: [addr_calc,CILNode::ConvUSize(index.into())].into(), + args: [addr_calc, CILNode::ConvUSize(index.into())].into(), } } _ => { diff --git a/src/rvalue.rs b/src/rvalue.rs index d398d685..23d456dc 100644 --- a/src/rvalue.rs +++ b/src/rvalue.rs @@ -17,7 +17,9 @@ pub fn handle_rvalue<'tcx>( tycache: &mut TyCache, ) -> Vec { let res = match rvalue { - Rvalue::Use(operand) => handle_operand(operand, tyctx, method, method_instance, tycache).flatten(), + Rvalue::Use(operand) => { + handle_operand(operand, tyctx, method, method_instance, tycache).flatten() + } Rvalue::CopyForDeref(place) => { crate::place::place_get(place, tyctx, method, method_instance, tycache).flatten() } @@ -52,23 +54,28 @@ pub fn handle_rvalue<'tcx>( let ops = match (src_fat, target_fat) { (true, true) => { let mut res = Vec::new(); - + res.push(CILOp::NewTMPLocal(source_type.into())); res.push(CILOp::SetTMPLocal); res.push(CILOp::LoadAddresOfTMPLocal); res.push(CILOp::FreeTMPLocal); - let parrent = handle_operand(operand, tyctx, method, method_instance, tycache).into(); - crate::place::deref_op( + let parrent = + handle_operand(operand, tyctx, method, method_instance, tycache).into(); + crate::place::deref_op( crate::place::PlaceTy::Ty(target), tyctx, &method_instance, tycache, - CILNode::RawOps { parrent, ops: res.into() } - ).flatten() - + CILNode::RawOps { + parrent, + ops: res.into(), + }, + ) + .flatten() } (true, false) => { - let mut res = handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); + let mut res = + handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); if source_type.as_dotnet().is_none() { eprintln!("source:{source:?}"); } @@ -95,7 +102,8 @@ pub fn handle_rvalue<'tcx>( let source_type = tycache.type_from_cache(source, tyctx, Some(method_instance)); let target_type = tycache.type_from_cache(target, tyctx, Some(method_instance)); let target_dotnet = target_type.as_dotnet().unwrap(); - let mut res = handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); + let mut res = + handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); let derefed_source = match source.kind() { TyKind::RawPtr(tpe) => tpe.ty, TyKind::Ref(_, inner, _) => *inner, @@ -177,7 +185,7 @@ pub fn handle_rvalue<'tcx>( tycache, ), Rvalue::UnaryOp(binop, operand) => { - crate::unop::unop(*binop, operand, tyctx, method, method_instance, tycache) + crate::unop::unop(*binop, operand, tyctx, method, method_instance, tycache).flatten() } Rvalue::Cast(CastKind::IntToInt, operand, target) => { let target = crate::utilis::monomorphize(&method_instance, *target, tyctx); @@ -268,7 +276,8 @@ pub fn handle_rvalue<'tcx>( handle_operand(operand, tyctx, method, method_instance, tycache).flatten() } (Type::F64, Type::U64) => { - let mut res = handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); + let mut res = + handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); res.extend([ CILOp::NewTMPLocal(Type::Ptr(src.into()).into()), CILOp::SetTMPLocal, @@ -279,7 +288,8 @@ pub fn handle_rvalue<'tcx>( res } (Type::F32, Type::U32) => { - let mut res = handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); + let mut res = + handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); res.extend([ CILOp::NewTMPLocal(Type::Ptr(src.into()).into()), CILOp::SetTMPLocal, @@ -290,7 +300,8 @@ pub fn handle_rvalue<'tcx>( res } (Type::U32, Type::F32) => { - let mut res = handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); + let mut res = + handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); res.extend([ CILOp::NewTMPLocal(Type::Ptr(src.into()).into()), CILOp::SetTMPLocal, @@ -301,7 +312,8 @@ pub fn handle_rvalue<'tcx>( res } (Type::U64, Type::F64) => { - let mut res = handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); + let mut res = + handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); res.extend([ CILOp::NewTMPLocal(Type::Ptr(src.into()).into()), CILOp::SetTMPLocal, @@ -313,7 +325,7 @@ pub fn handle_rvalue<'tcx>( } (_, _) => { let mut res = Vec::new(); - let operand = handle_operand(operand, tyctx, method, method_instance, tycache); + let operand = handle_operand(operand, tyctx, method, method_instance, tycache); res.push(CILOp::NewTMPLocal(src.into())); res.push(CILOp::SetTMPLocal); res.push(CILOp::LoadAddresOfTMPLocal); @@ -323,8 +335,12 @@ pub fn handle_rvalue<'tcx>( tyctx, &method_instance, tycache, - CILNode::RawOps { parrent: operand.into(), ops: res.into() } - ).flatten() + CILNode::RawOps { + parrent: operand.into(), + ops: res.into(), + }, + ) + .flatten() } } } @@ -335,7 +351,7 @@ pub fn handle_rvalue<'tcx>( let src = operand.ty(&method.local_decls, tyctx); let src = crate::utilis::monomorphize(&method_instance, src, tyctx); let src = tycache.type_from_cache(src, tyctx, Some(method_instance)); - /* + /* let mut res = handle_operand(operand, tyctx, method, method_instance, tycache); res.push(CILOp::NewTMPLocal( crate::r#type::Type::Ptr(src.into()).into(), @@ -344,7 +360,8 @@ pub fn handle_rvalue<'tcx>( res.push(CILOp::LoadAddresOfTMPLocal); res.push(CILOp::FreeTMPLocal); res.extend(deref_op(boxed_dst.into(), tyctx, &method_instance, tycache)); - res*/ todo!("FIX NOW") + res*/ + todo!("FIX NOW") } Rvalue::Cast(CastKind::PointerFromExposedAddress, operand, _) => { //FIXME: the documentation of this cast(https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html) is a bit confusing, @@ -478,7 +495,8 @@ pub fn handle_rvalue<'tcx>( tyctx, Some(method_instance), ); - let operand = handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); + let operand = + handle_operand(operand, tyctx, method, method_instance, tycache).flatten(); let mut ops = Vec::new(); ops.push(CILOp::NewTMPLocal(array.clone().into())); for idx in 0..times { diff --git a/src/statement.rs b/src/statement.rs index ee7c7d1b..25bd1a58 100644 --- a/src/statement.rs +++ b/src/statement.rs @@ -159,21 +159,24 @@ pub fn handle_statement<'tcx>( method, method_instance, type_cache, - ).flatten(); + ) + .flatten(); let src_op = crate::operand::handle_operand( src, tyctx, method, method_instance, type_cache, - ).flatten(); + ) + .flatten(); let count_op = crate::operand::handle_operand( count, tyctx, method, method_instance, type_cache, - ).flatten(); + ) + .flatten(); let src_ty = src.ty(method, tyctx); let src_ty = crate::utilis::monomorphize(&method_instance, src_ty, tyctx); let ptr_type = type_cache.type_from_cache(src_ty, tyctx, Some(method_instance)); diff --git a/src/terminator/call.rs b/src/terminator/call.rs index 8b26547e..f41ff875 100644 --- a/src/terminator/call.rs +++ b/src/terminator/call.rs @@ -86,13 +86,16 @@ fn call_managed<'tyctx>( let mut call = Vec::new(); for arg in args { - call.extend(crate::operand::handle_operand( - &arg.node, - tyctx, - method, - method_instance, - type_cache, - ).flatten()); + call.extend( + crate::operand::handle_operand( + &arg.node, + tyctx, + method, + method_instance, + type_cache, + ) + .flatten(), + ); } call.push(CILOp::Call(CallSite::boxed( Some(tpe.clone()), @@ -169,13 +172,16 @@ fn callvirt_managed<'tyctx>( let mut call = Vec::new(); for arg in args { - call.extend(crate::operand::handle_operand( - &arg.node, - tyctx, - method, - method_instance, - type_cache, - ).flatten()); + call.extend( + crate::operand::handle_operand( + &arg.node, + tyctx, + method, + method_instance, + type_cache, + ) + .flatten(), + ); } call.push(CILOp::CallVirt(CallSite::boxed( Some(tpe.clone()), @@ -254,13 +260,16 @@ fn call_ctor<'tyctx>( let sig = FnSig::new(&inputs, &crate::r#type::Type::Void); let mut call = Vec::new(); for arg in args { - call.extend(crate::operand::handle_operand( - &arg.node, - tyctx, - method, - method_instance, - type_cache, - ).flatten()); + call.extend( + crate::operand::handle_operand( + &arg.node, + tyctx, + method, + method_instance, + type_cache, + ) + .flatten(), + ); } call.push(CILOp::NewObj(CallSite::boxed( Some(tpe.clone()), @@ -294,13 +303,10 @@ pub fn call_closure<'tyctx>( .expect("Closure must be called with at least 2 arguments(closure + arg tuple)"); let other_args = &args[..args.len() - 1]; for arg in other_args { - call.extend(crate::operand::handle_operand( - &arg.node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + call.extend( + crate::operand::handle_operand(&arg.node, tyctx, body, method_instance, type_cache) + .flatten(), + ); } let last_arg_type = crate::utilis::monomorphize(&method_instance, last_arg.node.ty(body, tyctx), tyctx); @@ -308,13 +314,16 @@ pub fn call_closure<'tyctx>( TyKind::Tuple(elements) => { if elements.is_empty() { } else { - call.extend(crate::operand::handle_operand( - &last_arg.node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + call.extend( + crate::operand::handle_operand( + &last_arg.node, + tyctx, + body, + method_instance, + type_cache, + ) + .flatten(), + ); let tuple_type = type_cache.type_from_cache(last_arg_type, tyctx, Some(method_instance)); call.push(CILOp::NewTMPLocal(tuple_type.clone().into())); @@ -485,13 +494,10 @@ pub fn call<'tyctx>( let mut call = Vec::new(); for arg in args { - call.extend(crate::operand::handle_operand( - &arg.node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + call.extend( + crate::operand::handle_operand(&arg.node, tyctx, body, method_instance, type_cache) + .flatten(), + ); } if crate::function_sig::is_fn_variadic(fn_type, tyctx) { signature.set_inputs( diff --git a/src/terminator/intrinsics/mod.rs b/src/terminator/intrinsics/mod.rs index 01eee884..8b56b97b 100644 --- a/src/terminator/intrinsics/mod.rs +++ b/src/terminator/intrinsics/mod.rs @@ -1,5 +1,10 @@ use crate::{ - cil::{CILOp, CallSite}, cil_tree::cil_node::CILNode, function_sig::FnSig, operand::handle_operand, place::place_set, r#type::{tycache, DotnetTypeRef, Type} + cil::{CILOp, CallSite}, + cil_tree::cil_node::CILNode, + function_sig::FnSig, + operand::handle_operand, + place::place_set, + r#type::{tycache, DotnetTypeRef, Type}, }; use rustc_middle::{ mir::{Body, Operand, Place}, @@ -21,13 +26,10 @@ pub fn handle_intrinsic<'tyctx>( ) -> Vec { let mut call = Vec::new(); for arg in args { - call.extend(crate::operand::handle_operand( - &arg.node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + call.extend( + crate::operand::handle_operand(&arg.node, tyctx, body, method_instance, type_cache) + .flatten(), + ); } match fn_name { "breakpoint" => { @@ -55,7 +57,8 @@ pub fn handle_intrinsic<'tyctx>( ) } "arith_offset" => { - let mut ops = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + let mut ops = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); let tpe = crate::utilis::monomorphize( &method_instance, call_instance.args[0] @@ -64,13 +67,9 @@ pub fn handle_intrinsic<'tyctx>( tyctx, ); let tpe = type_cache.type_from_cache(tpe, tyctx, Some(method_instance)); - ops.extend(handle_operand( - &args[0].node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + ops.extend( + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(), + ); ops.extend([ CILOp::SizeOf(tpe.into()), CILOp::ConvUSize(false), @@ -144,21 +143,14 @@ pub fn handle_intrinsic<'tyctx>( 3, "The intrinsic `fmaf64` MUST take in exactly 1 argument!" ); - let mut res = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); - res.extend(handle_operand( - &args[1].node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); - res.extend(handle_operand( - &args[2].node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + let mut res = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + res.extend( + handle_operand(&args[1].node, tyctx, body, method_instance, type_cache).flatten(), + ); + res.extend( + handle_operand(&args[2].node, tyctx, body, method_instance, type_cache).flatten(), + ); res.extend([CILOp::Mul, CILOp::Add]); place_set(destination, tyctx, res, body, method_instance, type_cache) } @@ -184,13 +176,9 @@ pub fn handle_intrinsic<'tyctx>( .with_valuetype(false); let bit_operations = Some(bit_operations); let mut res = Vec::new(); - res.extend(handle_operand( - &args[0].node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + res.extend( + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(), + ); res.extend([ CILOp::ConvU64(false), CILOp::Call(CallSite::boxed( @@ -215,13 +203,9 @@ pub fn handle_intrinsic<'tyctx>( let bit_operations = Some(bit_operations); let mut res = Vec::new(); - res.extend(handle_operand( - &args[0].node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + res.extend( + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(), + ); let tpe = crate::utilis::monomorphize( &method_instance, call_instance.args[0] @@ -272,13 +256,9 @@ pub fn handle_intrinsic<'tyctx>( let tpe = type_cache.type_from_cache(tpe, tyctx, Some(method_instance)); let bit_operations = Some(bit_operations); let mut res = Vec::new(); - res.extend(handle_operand( - &args[0].node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + res.extend( + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(), + ); res.extend([CILOp::Call(CallSite::boxed( bit_operations.clone(), "TrailingZeroCount".into(), @@ -299,20 +279,12 @@ pub fn handle_intrinsic<'tyctx>( .with_valuetype(false); let bit_operations = Some(bit_operations); let mut res = Vec::new(); - res.extend(handle_operand( - &args[0].node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); - res.extend(handle_operand( - &args[1].node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + res.extend( + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(), + ); + res.extend( + handle_operand(&args[1].node, tyctx, body, method_instance, type_cache).flatten(), + ); res.extend([ CILOp::ConvU64(false), CILOp::Call(CallSite::boxed( @@ -331,9 +303,12 @@ pub fn handle_intrinsic<'tyctx>( 3, "The intrinsic `write_bytes` MUST take in exactly 3 argument!" ); - let dst = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); - let val = handle_operand(&args[1].node, tyctx, body, method_instance, type_cache).flatten(); - let count = handle_operand(&args[2].node, tyctx, body, method_instance, type_cache).flatten(); + let dst = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + let val = + handle_operand(&args[1].node, tyctx, body, method_instance, type_cache).flatten(); + let count = + handle_operand(&args[2].node, tyctx, body, method_instance, type_cache).flatten(); let mut ops = dst; ops.extend(val); ops.extend(count); @@ -346,9 +321,12 @@ pub fn handle_intrinsic<'tyctx>( 3, "The intrinsic `copy` MUST take in exactly 3 argument!" ); - let dst = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); - let val = handle_operand(&args[1].node, tyctx, body, method_instance, type_cache).flatten(); - let count = handle_operand(&args[2].node, tyctx, body, method_instance, type_cache).flatten(); + let dst = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + let val = + handle_operand(&args[1].node, tyctx, body, method_instance, type_cache).flatten(); + let count = + handle_operand(&args[2].node, tyctx, body, method_instance, type_cache).flatten(); let mut ops = dst; ops.extend(val); ops.extend(count); @@ -361,8 +339,10 @@ pub fn handle_intrinsic<'tyctx>( 2, "The intrinsic `exact_div` MUST take in exactly 2 argument!" ); - let lhs = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); - let rhs = handle_operand(&args[1].node, tyctx, body, method_instance, type_cache).flatten(); + let lhs = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + let rhs = + handle_operand(&args[1].node, tyctx, body, method_instance, type_cache).flatten(); let mut ops = lhs; ops.extend(rhs); ops.push(CILOp::Div); @@ -422,18 +402,14 @@ pub fn handle_intrinsic<'tyctx>( crate::utilis::monomorphize(&method_instance, args[0].node.ty(body, tyctx), tyctx); let arg_ty = arg.builtin_deref(true).unwrap().ty; let arg = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache); - let ops = crate::place::deref_op( - arg_ty.into(), - tyctx, - &method_instance, - type_cache, - arg, - ).flatten(); + let ops = + crate::place::deref_op(arg_ty.into(), tyctx, &method_instance, type_cache, arg) + .flatten(); place_set(destination, tyctx, ops, body, method_instance, type_cache) } "atomic_load_unordered" => { // This is already implemented by default in .NET when volatile is used. TODO: ensure this is 100% right. - //TODO:fix volitale prefix! + //TODO:fix volitale prefix! debug_assert_eq!( args.len(), 1, @@ -443,13 +419,9 @@ pub fn handle_intrinsic<'tyctx>( crate::utilis::monomorphize(&method_instance, args[0].node.ty(body, tyctx), tyctx); let arg_ty = arg.builtin_deref(true).unwrap().ty; let arg = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache); - let ops = crate::place::deref_op( - arg_ty.into(), - tyctx, - &method_instance, - type_cache, - arg, - ).flatten(); + let ops = + crate::place::deref_op(arg_ty.into(), tyctx, &method_instance, type_cache, arg) + .flatten(); place_set(destination, tyctx, ops, body, method_instance, type_cache) } "atomic_load_acquire" => { @@ -459,18 +431,14 @@ pub fn handle_intrinsic<'tyctx>( 1, "The intrinsic `atomic_load_acquire` MUST take in exactly 1 argument!" ); - let ops = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache); + let ops = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache); let arg = crate::utilis::monomorphize(&method_instance, args[0].node.ty(body, tyctx), tyctx); let arg_ty = arg.builtin_deref(true).unwrap().ty; - - let ops = crate::place::deref_op( - arg_ty.into(), - tyctx, - &method_instance, - type_cache, - ops, - ).flatten(); + + let ops = + crate::place::deref_op(arg_ty.into(), tyctx, &method_instance, type_cache, ops) + .flatten(); place_set(destination, tyctx, ops, body, method_instance, type_cache) } //"bswap" @@ -481,7 +449,8 @@ pub fn handle_intrinsic<'tyctx>( 2, "The intrinsic `min_align_of_val` MUST take in exactly 1 argument!" ); - let mut ops = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + let mut ops = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); let tpe = crate::utilis::monomorphize( &method_instance, call_instance.args[0] @@ -490,13 +459,9 @@ pub fn handle_intrinsic<'tyctx>( tyctx, ); let tpe = type_cache.type_from_cache(tpe, tyctx, Some(method_instance)); - ops.extend(handle_operand( - &args[1].node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + ops.extend( + handle_operand(&args[1].node, tyctx, body, method_instance, type_cache).flatten(), + ); ops.extend([ CILOp::Sub, CILOp::SizeOf(tpe.into()), @@ -536,7 +501,8 @@ pub fn handle_intrinsic<'tyctx>( 1, "The intrinsic `sqrtf32` MUST take in exactly 1 argument!" ); - let mut ops = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + let mut ops = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); ops.push(CILOp::Call(CallSite::boxed( Some(DotnetTypeRef::new("System.Runtime".into(), "System.MathF")), "Sqrt".into(), @@ -551,7 +517,8 @@ pub fn handle_intrinsic<'tyctx>( 1, "The intrinsic `floorf32` MUST take in exactly 1 argument!" ); - let mut ops = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + let mut ops = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); ops.push(CILOp::Call(CallSite::boxed( Some(DotnetTypeRef::new("System.Runtime".into(), "System.MathF")), "Floor".into(), @@ -566,7 +533,8 @@ pub fn handle_intrinsic<'tyctx>( 1, "The intrinsic `ceilf32` MUST take in exactly 1 argument!" ); - let mut ops = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + let mut ops = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); ops.push(CILOp::Call(CallSite::boxed( Some(DotnetTypeRef::new("System.Runtime".into(), "System.MathF")), "Ceiling".into(), @@ -581,14 +549,11 @@ pub fn handle_intrinsic<'tyctx>( 2, "The intrinsic `maxnumf32` MUST take in exactly 2 arguments!" ); - let mut ops = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); - ops.extend(handle_operand( - &args[1].node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + let mut ops = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + ops.extend( + handle_operand(&args[1].node, tyctx, body, method_instance, type_cache).flatten(), + ); ops.push(CILOp::Call(CallSite::boxed( Some(DotnetTypeRef::new("System.Runtime".into(), "System.MathF")), "Max".into(), @@ -603,14 +568,11 @@ pub fn handle_intrinsic<'tyctx>( 2, "The intrinsic `minnumf32` MUST take in exactly 2 arguments!" ); - let mut ops = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); - ops.extend(handle_operand( - &args[1].node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + let mut ops = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + ops.extend( + handle_operand(&args[1].node, tyctx, body, method_instance, type_cache).flatten(), + ); ops.push(CILOp::Call(CallSite::boxed( Some(DotnetTypeRef::new("System.Runtime".into(), "System.MathF")), "Min".into(), @@ -625,15 +587,12 @@ pub fn handle_intrinsic<'tyctx>( 2, "The intrinsic `powif32` MUST take in exactly 2 arguments!" ); - let mut ops = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + let mut ops = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); ops.push(CILOp::ConvF64); - ops.extend(handle_operand( - &args[1].node, - tyctx, - body, - method_instance, - type_cache, - ).flatten()); + ops.extend( + handle_operand(&args[1].node, tyctx, body, method_instance, type_cache).flatten(), + ); ops.push(CILOp::ConvF64); ops.push(CILOp::Call(CallSite::boxed( Some(DotnetTypeRef::new("System.Runtime".into(), "System.Math")), @@ -668,7 +627,8 @@ pub fn handle_intrinsic<'tyctx>( 1, "The intrinsic `sqrtf64` MUST take in exactly 1 argument!" ); - let mut ops = handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); + let mut ops = + handle_operand(&args[0].node, tyctx, body, method_instance, type_cache).flatten(); ops.push(CILOp::Call(CallSite::boxed( Some(DotnetTypeRef::new("System.Runtime".into(), "System.Math")), "Sqrt".into(), diff --git a/src/terminator/mod.rs b/src/terminator/mod.rs index 8005123b..f9835fd1 100644 --- a/src/terminator/mod.rs +++ b/src/terminator/mod.rs @@ -61,21 +61,27 @@ pub fn handle_terminator<'ctx>( FnSig::from_poly_sig(Some(method_instance), tyctx, type_cache, sig); let mut call_ops = Vec::new(); for arg in args { - call_ops.extend(crate::operand::handle_operand( - &arg.node, + call_ops.extend( + crate::operand::handle_operand( + &arg.node, + tyctx, + body, + method_instance, + type_cache, + ) + .flatten(), + ); + } + call_ops.extend( + crate::place::place_get( + operand, tyctx, - body, + method, method_instance, type_cache, - ).flatten()); - } - call_ops.extend(crate::place::place_get( - operand, - tyctx, - method, - method_instance, - type_cache, - ).flatten()); + ) + .flatten(), + ); call_ops.push(CILOp::CallI(sig.clone().into())); if *sig.output() == crate::r#type::Type::Void { ops.extend(call_ops); @@ -127,7 +133,8 @@ pub fn handle_terminator<'ctx>( TerminatorKind::SwitchInt { discr, targets } => { let ty = crate::utilis::monomorphize(&method_instance, discr.ty(method, tyctx), tyctx); let discr = - crate::operand::handle_operand(discr, tyctx, method, method_instance, type_cache).flatten(); + crate::operand::handle_operand(discr, tyctx, method, method_instance, type_cache) + .flatten(); handle_switch(ty, &discr, targets) } TerminatorKind::Assert { @@ -215,13 +222,7 @@ fn throw_assert_msg<'ctx>( AssertKind::BoundsCheck { len, index } => { let mut ops = Vec::with_capacity(8); ops.push(CILOp::LdStr("index out of bounds: the len is ".into())); - ops.extend(handle_operand( - len, - tyctx, - method, - method_instance, - type_cache, - ).flatten()); + ops.extend(handle_operand(len, tyctx, method, method_instance, type_cache).flatten()); let usize_class = crate::utilis::usize_class(); let string_class = crate::utilis::string_class(); let string_type = crate::r#type::Type::DotnetType(Box::new(string_class.clone())); @@ -229,13 +230,7 @@ fn throw_assert_msg<'ctx>( let usize_to_string = CallSite::boxed(Some(usize_class), "ToString".into(), sig, false); ops.push(CILOp::Call(usize_to_string.clone())); ops.push(CILOp::LdStr(" but the index is".into())); - ops.extend(handle_operand( - index, - tyctx, - method, - method_instance, - type_cache, - ).flatten()); + ops.extend(handle_operand(index, tyctx, method, method_instance, type_cache).flatten()); ops.push(CILOp::Call(usize_to_string.clone())); let sig = FnSig::new( @@ -301,26 +296,14 @@ fn throw_assert_msg<'ctx>( ops.push(CILOp::LdStr( format!("attempt to {binop:?} with overflow lhs:").into(), )); - ops.extend(handle_operand( - a, - tyctx, - method, - method_instance, - type_cache, - ).flatten()); + ops.extend(handle_operand(a, tyctx, method, method_instance, type_cache).flatten()); let usize_class = crate::utilis::usize_class(); let string_type = crate::r#type::Type::DotnetType(Box::new(string_class.clone())); let sig = FnSig::new(&[], &string_type); let usize_to_string = CallSite::boxed(Some(usize_class), "ToString".into(), sig, false); ops.push(CILOp::Call(usize_to_string.clone())); ops.push(CILOp::LdStr("rhs:".into())); - ops.extend(handle_operand( - b, - tyctx, - method, - method_instance, - type_cache, - ).flatten()); + ops.extend(handle_operand(b, tyctx, method, method_instance, type_cache).flatten()); ops.push(CILOp::Call(usize_to_string.clone())); let sig = FnSig::new( @@ -417,13 +400,7 @@ fn throw_assert_msg<'ctx>( ops.push(CILOp::LdStr( "attempt to neg with overflow value:".to_string().into(), )); - ops.extend(handle_operand( - value, - tyctx, - method, - method_instance, - type_cache, - ).flatten()); + ops.extend(handle_operand(value, tyctx, method, method_instance, type_cache).flatten()); let usize_class = crate::utilis::usize_class(); let string_type = crate::r#type::Type::DotnetType(Box::new(string_class.clone())); let sig = FnSig::new(&[], &string_type); @@ -474,7 +451,9 @@ fn handle_switch(ty: Ty, discr: &[CILOp], switch: &SwitchTargets) -> Vec .expect("Bool value outside of range 0-255. Should be either 0 OR 1.") as i32, )], - TyKind::Char => crate::constant::load_const_uint(value, &rustc_middle::ty::UintTy::U64).flatten(), + TyKind::Char => { + crate::constant::load_const_uint(value, &rustc_middle::ty::UintTy::U64).flatten() + } _ => todo!("Unsuported switch discriminant type {ty:?}"), }); //ops.push(CILOp::LdcI64(value as i64)); diff --git a/src/unop.rs b/src/unop.rs index 5e2ee4d1..3827cb41 100644 --- a/src/unop.rs +++ b/src/unop.rs @@ -1,3 +1,4 @@ +use crate::cil_tree::cil_node::CILNode; use crate::function_sig::FnSig; use crate::r#type::tycache::TyCache; use crate::r#type::{DotnetTypeRef, Type}; @@ -12,46 +13,58 @@ pub fn unop<'ctx>( method: &rustc_middle::mir::Body<'ctx>, method_instance: Instance<'ctx>, tycache: &mut TyCache, -) -> Vec { - let mut ops = crate::operand::handle_operand(operand, tcx, method, method_instance, tycache).flatten(); +) -> CILNode { + let parrent_node = + crate::operand::handle_operand(operand, tcx, method, method_instance, tycache); let ty = operand.ty(&method.local_decls, tcx); match unnop { UnOp::Neg => match ty.kind() { - TyKind::Int(IntTy::I128) => ops.push(CILOp::Call(CallSite::boxed( - DotnetTypeRef::int_128().into(), - "op_UnaryNegation".into(), - FnSig::new(&[Type::I128], &Type::I128), - true, - ))), - TyKind::Int(IntTy::I8) => ops.extend([CILOp::Neg, CILOp::ConvI8(false)]), - TyKind::Int(IntTy::I16) => ops.extend([CILOp::Neg, CILOp::ConvI16(false)]), - TyKind::Uint(UintTy::U128) => ops.push(CILOp::Call(CallSite::boxed( - DotnetTypeRef::uint_128().into(), - "op_UnaryNegation".into(), - FnSig::new(&[Type::U128], &Type::U128), - true, - ))), - TyKind::Uint(UintTy::U8) => ops.extend([CILOp::Neg, CILOp::ConvU8(false)]), - TyKind::Uint(UintTy::U16) => ops.extend([CILOp::Neg, CILOp::ConvU16(false)]), - _ => ops.push(CILOp::Neg), + TyKind::Int(IntTy::I128) => CILNode::Call { + site: CallSite::boxed( + DotnetTypeRef::int_128().into(), + "op_UnaryNegation".into(), + FnSig::new(&[Type::I128], &Type::I128), + true, + ), + args: [parrent_node].into(), + }, + TyKind::Int(IntTy::I8) => CILNode::Neg(CILNode::ConvI8(parrent_node.into()).into()), + TyKind::Int(IntTy::I16) => CILNode::Neg(CILNode::ConvI16(parrent_node.into()).into()), + TyKind::Uint(UintTy::U128) => CILNode::Call { + site: CallSite::boxed( + DotnetTypeRef::uint_128().into(), + "op_UnaryNegation".into(), + FnSig::new(&[Type::U128], &Type::U128), + true, + ), + args: [parrent_node].into(), + }, + _ => CILNode::Neg(parrent_node.into()), }, UnOp::Not => match ty.kind() { - TyKind::Bool => ops.extend([CILOp::LdcI32(0), CILOp::Eq]), - TyKind::Uint(UintTy::U128) => ops.push(CILOp::Call(CallSite::boxed( - DotnetTypeRef::uint_128().into(), - "op_OnesComplement".into(), - FnSig::new(&[Type::U128], &Type::U128), - true, - ))), - TyKind::Int(IntTy::I128) => ops.push(CILOp::Call(CallSite::boxed( - DotnetTypeRef::int_128().into(), - "op_OnesComplement".into(), - FnSig::new(&[Type::I128], &Type::I128), - true, - ))), + TyKind::Bool => CILNode::Eq(CILNode::LdcI32(0).into(),parrent_node.into()), + TyKind::Uint(UintTy::U128) => CILNode::Call { + site: CallSite::boxed( + DotnetTypeRef::uint_128().into(), + "op_OnesComplement".into(), + FnSig::new(&[Type::U128], &Type::U128), + true, + ), + args: [parrent_node].into(), + }, + TyKind::Int(IntTy::I128) => CILNode::Call { + site: CallSite::boxed( + DotnetTypeRef::int_128().into(), + "op_OnesComplement".into(), + FnSig::new(&[Type::I128], &Type::I128), + true, + ), + args: [parrent_node].into(), + }, + //TyKind::U128 => ops.extend([CILOp::LdcI32(0), CILOp::Eq]), - _ => ops.push(CILOp::Not), + _ => CILNode::Not(parrent_node.into()), }, - }; - ops + } + }