Skip to content

Commit

Permalink
Fixed drops + 2 more intirniscs
Browse files Browse the repository at this point in the history
  • Loading branch information
FractalFir committed Jan 24, 2024
1 parent 7553d76 commit 03093df
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 32 deletions.
3 changes: 2 additions & 1 deletion cargo_tests/build_std/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::io::Write;
use std::hint::black_box;
extern "C" {
fn puts(msg: *const u8);
}
Expand Down Expand Up @@ -111,7 +112,7 @@ fn main() {

//std::hint::black_box(f);
//std::io::stdout().write_all(b"hello world\n").unwrap();
let s = format!("Hello {}\0",8);
let s = format!("Hello??? WTF is going on???{}\0",black_box(65));
unsafe{puts(s.as_ptr())};


Expand Down
16 changes: 1 addition & 15 deletions src/rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ pub fn handle_rvalue<'tcx>(
NullOp::AlignOf => {
let ty = crate::utilis::monomorphize(&method_instance, *ty, tyctx);
vec![
CILOp::LdcI64(align_of(ty, tyctx) as i64),
CILOp::LdcI64(crate::utilis::align_of(ty, tyctx) as i64),
CILOp::ConvUSize(false),
]
}
Expand Down Expand Up @@ -493,17 +493,3 @@ pub fn handle_rvalue<'tcx>(
};
res
}
fn align_of<'tcx>(ty: rustc_middle::ty::Ty<'tcx>, tyctx: TyCtxt<'tcx>) -> u64 {
let layout = tyctx
.layout_of(rustc_middle::ty::ParamEnvAnd {
param_env: ParamEnv::reveal_all(),
value: ty,
})
.expect("Can't get layout of a type.")
.layout;

let align = layout.align.abi;
// FIXME: this field is likely private for a reason. I should not do this get its value. Find a better way to get aligement.
let pow2 = u64::from(unsafe { std::mem::transmute::<_, u8>(align) });
1 << pow2
}
20 changes: 10 additions & 10 deletions src/terminator/call.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
use crate::call_info::CallInfo;
use crate::cil::FieldDescriptor;
use crate::interop::AssemblyRef;
use crate::r#type::Type;
use crate::utilis::garg_to_string;
use crate::{
cil::{CILOp, CallSite},
function_sig::FnSig,
operand::handle_operand,
r#type::DotnetTypeRef,
utilis::monomorphize,
utilis::CTOR_FN_NAME,
utilis::MANAGED_CALL_FN_NAME,
utilis::MANAGED_CALL_VIRT_FN_NAME,
cil::FieldDescriptor,call_info::CallInfo,interop::AssemblyRef,
utilis::garg_to_string,
};
use rustc_middle::ty::InstanceDef;
use rustc_middle::{
mir::{Body, Operand, Place, SwitchTargets, Terminator, TerminatorKind},
ty::{GenericArg, Instance, ParamEnv, Ty, TyCtxt, TyKind},
ty::{GenericArg, Instance, ParamEnv, Ty, TyCtxt, TyKind,InstanceDef},
};
use rustc_span::source_map::Spanned;
fn decode_interop_call<'tyctx>(
Expand Down Expand Up @@ -376,12 +370,13 @@ pub fn call<'tyctx>(
else {
// I assume most functions wihc can't be resolved are empty drops.
// There propably exists a better way to check if it REALLY is just an empty drop, but this is good enough for now.
/*
if rustc_middle::ty::print::with_no_trimmed_paths! {format!("{fn_type:?}")}
.contains("drop")
{
rustc_middle::ty::print::with_no_trimmed_paths! {eprintln!("Empty drop {fn_type:?}")};
return vec![];
}
}*/
panic!("ERROR: Could not get function instance. fn type:{fn_type:?}")
};

Expand Down Expand Up @@ -511,6 +506,11 @@ pub fn call<'tyctx>(
}
//assert_eq!(args.len(),signature.inputs().len(),"CALL SIGNATURE ARG COUNT MISMATCH!");
let is_void = matches!(signature.output(), crate::r#type::Type::Void);
rustc_middle::ty::print::with_no_trimmed_paths! {call.push(CILOp::Comment(format!("Calling {instance:?}").into()))};
match instance.def{
InstanceDef::DropGlue(def,None)=>return vec![],
_=>(),
}
call.push(CILOp::Call(CallSite::boxed(
None,
function_name,
Expand Down
48 changes: 48 additions & 0 deletions src/terminator/intrinsics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,54 @@ pub fn handle_intrinsic<'tyctx>(
}
//"bswap"
"assert_inhabited" => vec![],
"ptr_offset_from_unsigned"=>{
debug_assert_eq!(
args.len(),
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);
let tpe = crate::utilis::monomorphize(
&method_instance,
call_instance.args[0]
.as_type()
.expect("needs_drop works only on types!"),
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));
ops.extend([
CILOp::Sub,
CILOp::SizeOf(tpe.into()),
CILOp::Div,
]);
place_set(destination, tyctx, ops, body, method_instance, type_cache)
}
"min_align_of_val"=>{
debug_assert_eq!(
args.len(),
1,
"The intrinsic `min_align_of_val` MUST take in exactly 1 argument!"
);
let tpe = crate::utilis::monomorphize(
&method_instance,
call_instance.args[0]
.as_type()
.expect("needs_drop works only on types!"),
tyctx,
);
place_set(
destination,
tyctx,
vec![
CILOp::LdcI64(crate::utilis::align_of(tpe, tyctx) as i64),
CILOp::ConvUSize(false),
],
body,
method_instance,
type_cache,
)
}
"sqrtf32" => {
debug_assert_eq!(
args.len(),
Expand Down
2 changes: 1 addition & 1 deletion src/terminator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ pub fn handle_terminator<'ctx>(
crate::place::place_adress(place, tyctx, method, method_instance, type_cache);

call.push(CILOp::Call(CallSite::boxed(None, function_name, sig, true)));
eprintln!("drop call:{call:?}");
//dprintln!("drop call:{call:?}");
call.push(CILOp::GoTo(target.as_u32()));
call
}
Expand Down
14 changes: 14 additions & 0 deletions src/utilis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,3 +458,17 @@ pub fn is_fn_intrinsic<'tyctx>(fn_ty: Ty<'tyctx>, tyctx: TyCtxt<'tyctx>) -> bool
_ => false,
}
}
pub fn align_of<'tcx>(ty: rustc_middle::ty::Ty<'tcx>, tyctx: TyCtxt<'tcx>) -> u64 {
let layout = tyctx
.layout_of(rustc_middle::ty::ParamEnvAnd {
param_env: ParamEnv::reveal_all(),
value: ty,
})
.expect("Can't get layout of a type.")
.layout;

let align = layout.align.abi;
// FIXME: this field is likely private for a reason. I should not do this get its value. Find a better way to get aligement.
let pow2 = u64::from(unsafe { std::mem::transmute::<_, u8>(align) });
1 << pow2
}
10 changes: 5 additions & 5 deletions test/control_flow/drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ include!("../common.rs");
struct DecrementOnDrop<'a>(&'a mut u32);
impl Drop for DecrementOnDrop<'_>{
fn drop(&mut self){
//Put::putnl(*self.0);
Put::putnl(*self.0);
*self.0 -= 1;
}
}
fn main(){
let mut i = 1;
//Put::putnl(i);
//test_eq!(black_box(i),1);
Put::putnl(i);
test_eq!(black_box(i),1);
let d = DecrementOnDrop(&mut i);
black_box(d);
//Put::putnl(i);
//test_eq!(black_box(i),0);
Put::putnl(i);
test_eq!(black_box(i),0);
}

0 comments on commit 03093df

Please sign in to comment.