Skip to content

Commit 9e3845d

Browse files
committed
Fixed setting the references. Dereferencing still does not work.
1 parent e9e8d05 commit 9e3845d

10 files changed

+74
-126
lines changed

makefile

+7-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ TEST_DIR = "test"
22
CODEGEN_BACKEND = ../target/debug/librustc_codegen_clr.so
33
RUSTC = rustc
44
RUST_FLAGS = --crate-type lib
5-
test: build_backend identy binops casts types calls
5+
test: build_backend identy binops casts types calls references
66
calls:
77
cd test && rustc $(RUST_FLAGS) -O -Z codegen-backend=$(CODEGEN_BACKEND) calls.rs && \
88
ilasm /dll libcalls.rlib
@@ -11,7 +11,12 @@ identy:
1111
ilasm /dll libidentity.rlib
1212
binops:
1313
cd test && rustc $(RUST_FLAGS) -O -Z codegen-backend=$(CODEGEN_BACKEND) binops.rs && \
14-
ilasm /dll libbinops.rlib
14+
ilasm /dll libbinops.rlib && \
15+
rustc -O --emit=mir --crate-type=lib binops.rs
16+
references:
17+
cd test && rustc $(RUST_FLAGS) -O -Z codegen-backend=$(CODEGEN_BACKEND) references.rs && \
18+
ilasm /dll libreferences.rlib && \
19+
rustc -O --emit=mir --crate-type=lib references.rs
1520
casts:
1621
cd test && rustc $(RUST_FLAGS) -O -Z codegen-backend=$(CODEGEN_BACKEND) casts.rs && \
1722
ilasm /dll libcasts.rlib

src/assembly.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ impl Assembly {
4444
.expect("Could not resolve the function signature"),
4545
name,
4646
);
47+
clr_method.add_locals(&mir.local_decls);
4748
for block_data in blocks {
4849
clr_method.begin_bb();
4950
for statement in &block_data.statements {
@@ -54,9 +55,7 @@ impl Assembly {
5455
None => (),
5556
}
5657
}
57-
// Optimization is currently broken, and may produce invalid IR.
5858
clr_method.opt();
59-
clr_method.add_locals(&mir.local_decls);
6059
println!("clr_method:{clr_method:?}");
6160
println!("instance:{instance:?}\n");
6261
self.methods.push(clr_method);

src/assigment_target.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_middle::{
55
mir::{Body, Place,AggregateKind,CastKind,BinOp,Operand,ConstantKind},
66
ty::TyCtxt,
77
};
8+
use rustc_middle::mir::ProjectionElem;
89
macro_rules! sign_cast {
910
($var:ident,$src:ty,$dest:ty) => {
1011
(<$dest>::from_ne_bytes(($var as $src).to_ne_bytes()))
@@ -34,7 +35,24 @@ impl AsigmentTarget {
3435
LocalPlacement::Var(var_id) => BaseIR::STLoc(var_id),
3536
});
3637
} else {
37-
panic!("Can't handle non-trivial assignments!");
38+
let local: u32 = place.local.into();
39+
new.adress_calc
40+
.push(match clr_method.local_id_placement(local) {
41+
LocalPlacement::Arg(arg_id) => BaseIR::LDArg(arg_id),
42+
LocalPlacement::Var(var_id) => BaseIR::LDLoc(var_id),
43+
});
44+
for modifier in &place.projection[..(place.projection.len() - 1)]{
45+
todo!("Can't handle assignments with more than one level of indirection")
46+
}
47+
let last = place.projection[(place.projection.len() - 1)];
48+
match last{
49+
ProjectionElem::Deref => {
50+
//TODO: handle the type
51+
new.value_pos = AsigmentValuePosition::AfterAdress;
52+
new.set_ops.push(BaseIR::STIInd(4));
53+
}
54+
_=> todo!("Can't handle ProjectionElements of type {last:?}!"),
55+
}
3856
}
3957
new
4058
}
@@ -90,6 +108,13 @@ impl RValue {
90108
_ => todo!("Unknown binop:{binop:?}"),
91109
});
92110
}
111+
fn read_pointer_of_type(&mut self, element_type:&VariableType){
112+
match element_type{
113+
VariableType::I32 => self.ops.push(BaseIR::LDIndIn(std::mem::size_of::<i32>() as u8)),
114+
VariableType::Ref(_) | VariableType::RefMut(_) =>self.ops.push(BaseIR::LDIndI),
115+
_=>todo!("Can't derference pointer of type {element_type:?}"),
116+
}
117+
}
93118
fn process_rvalue<'ctx>(
94119
&mut self,
95120
rvalue: &CompilerRValue<'ctx>,
@@ -128,6 +153,16 @@ impl RValue {
128153
),
129154
}
130155
}
156+
CompilerRValue::Repeat(_, _) => todo!("Can't yet initialize arrays!"),
157+
CompilerRValue::CopyForDeref(place) =>{
158+
if place.projection.len() == 1{
159+
self.load(place.local.into(),clr_method);
160+
self.read_pointer_of_type(&clr_method.get_type_of_local(place.local.into()).get_pointed_type().expect("Tried to deference a value that was neither a pointer nor a reference"));
161+
}
162+
else {
163+
panic!("Can't handle non-trivial deference's yet, projection:{projection:?}!",projection = place.projection);
164+
}
165+
}
131166
_ => todo!("Can't yet handle a rvalue of type {rvalue:?}"),
132167
}
133168
}

src/base_ir.rs

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ pub(crate) enum BaseIR {
77
LDConstI32(i32),
88
LDConstI64(i64),
99
STIInd(u8),
10+
LDIndIn(u8),
11+
LDIndI,
1012
LDConstString(String),
1113
STArg(u32),
1214
LDArg(u32),
@@ -75,6 +77,8 @@ impl BaseIR {
7577
Self::NewObj { ctor_fn } => format!("\tnewobj instance {ctor_fn}\n"),
7678
Self::Throw => "\tthrow\n".into(),
7779
Self::STIInd(size) => format!("\tstind.i{size}\n"),
80+
Self::LDIndIn(size) => format!("\tldind.i{size}\n"),
81+
Self::LDIndI=>"\tldind.i\n".into(),
7882
}
7983
.into()
8084
}

src/clr_method.rs

+6-116
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ pub(crate) enum LocalPlacement {
3333
Var(u32),
3434
}
3535
impl CLRMethod {
36+
pub(crate) fn get_type_of_local(&self, local:u32)->&VariableType{
37+
match self.local_id_placement(local){
38+
LocalPlacement::Arg(index)=>&self.sig.inputs[index as usize],
39+
LocalPlacement::Var(index)=>&self.locals[index as usize],
40+
}
41+
}
3642
pub(crate) fn extend_ops(&mut self,ops:&[BaseIR]){
3743
self.ops.extend(ops.iter().map(|ref_op| ref_op.clone()))
3844
}
@@ -188,35 +194,6 @@ impl CLRMethod {
188194
LocalPlacement::Var(var_id) => BaseIR::LDLoc(var_id),
189195
})
190196
}
191-
fn store(&mut self, place: Place) {
192-
if place.projection.is_empty() {
193-
let local: u32 = place.local.into();
194-
self.ops.push(match self.local_id_placement(local) {
195-
LocalPlacement::Arg(arg_id) => BaseIR::STArg(arg_id),
196-
LocalPlacement::Var(var_id) => BaseIR::STLoc(var_id),
197-
})
198-
} else {
199-
// First, travel trough almost every element besides the last one!
200-
if place.projection.len() > 1 {
201-
panic!("Unhandled Non-trivial store!");
202-
for _projection_mod in &place.projection[..(place.projection.len() - 1)] {}
203-
}
204-
// The value or address of the last one should be on top of the stack.
205-
let last = place.projection[place.projection.len() - 1];
206-
match last {
207-
PlaceElem::Deref => {
208-
let local: u32 = place.local.into();
209-
self.ops.push(match self.local_id_placement(local) {
210-
LocalPlacement::Arg(arg_id) => BaseIR::LDArg(arg_id),
211-
LocalPlacement::Var(var_id) => BaseIR::LDLoc(var_id),
212-
});
213-
//TODO: use type info!
214-
self.ops.push(BaseIR::STIInd(4));
215-
}
216-
_ => todo!("Unhandled placement!"),
217-
}
218-
}
219-
}
220197
fn process_constant(&mut self, constant: ConstantKind) {
221198
match constant {
222199
ConstantKind::Val(value, r#type) => match value {
@@ -246,89 +223,6 @@ impl CLRMethod {
246223
}
247224
}
248225
}
249-
fn convert(&mut self, src: &VariableType, dest: &VariableType) {
250-
match (src, dest) {
251-
(
252-
VariableType::F32
253-
| VariableType::I8
254-
| VariableType::I16
255-
| VariableType::I32
256-
| VariableType::U8
257-
| VariableType::U16
258-
| VariableType::U32,
259-
VariableType::I32,
260-
) => self.ops.push(BaseIR::ConvI32),
261-
(
262-
VariableType::F64
263-
| VariableType::I64
264-
| VariableType::U64
265-
| VariableType::ISize
266-
| VariableType::USize,
267-
VariableType::I32,
268-
) => self.ops.push(BaseIR::ConvI32Checked),
269-
(VariableType::F32, VariableType::I8) => self.ops.push(BaseIR::ConvI8),
270-
(VariableType::I32, VariableType::F32) => self.ops.push(BaseIR::ConvF32),
271-
_ => todo!("Can't convert type {src:?} to {dest:?}"),
272-
}
273-
}
274-
// Makes so the top of the stack is the value of RValue
275-
fn process_rvalue<'ctx>(
276-
&mut self,
277-
rvalue: &Rvalue<'ctx>,
278-
body: &Body<'ctx>,
279-
tyctx: &TyCtxt<'ctx>,
280-
) {
281-
match rvalue {
282-
Rvalue::Use(operand) => self.process_operand(operand),
283-
Rvalue::BinaryOp(binop, operands) => {
284-
let (a, b): (_, _) = (&operands.0, &operands.1);
285-
self.process_operand(a);
286-
self.process_operand(b);
287-
self.ops.push(match binop {
288-
BinOp::Add => BaseIR::Add,
289-
BinOp::Sub => BaseIR::Sub,
290-
BinOp::Mul => BaseIR::Mul,
291-
BinOp::Shl => BaseIR::Shl,
292-
BinOp::Shr => BaseIR::Shr,
293-
BinOp::Eq => BaseIR::Eq,
294-
BinOp::Ne => BaseIR::NEq,
295-
BinOp::Gt => BaseIR::Gt,
296-
BinOp::Rem => BaseIR::Rem,
297-
BinOp::BitXor => BaseIR::Xor,
298-
BinOp::BitOr => BaseIR::Or,
299-
BinOp::BitAnd => BaseIR::And,
300-
BinOp::Div => BaseIR::Div,
301-
_ => todo!("Unknown binop:{binop:?}"),
302-
});
303-
}
304-
Rvalue::Cast(
305-
CastKind::IntToInt
306-
| CastKind::FloatToFloat
307-
| CastKind::FloatToInt
308-
| CastKind::IntToFloat,
309-
operand,
310-
target,
311-
) => {
312-
self.process_operand(operand);
313-
self.convert(
314-
&VariableType::from_ty(operand.ty(body, *tyctx)),
315-
&VariableType::from_ty(*target),
316-
);
317-
}
318-
Rvalue::Aggregate(kind, operands) => {
319-
match kind.as_ref() {
320-
AggregateKind::Adt(def_id, variant_idx, subst_ref, utai, fidx) => {
321-
//let (def_id,variant_idx,subst_ref,utai,fidx) = *adt;
322-
panic!("def_id:{def_id:?},variant_idx:{variant_idx:?},subst_ref:{subst_ref:?},utai:{utai:?},fidx:{fidx:?}");
323-
}
324-
_ => todo!(
325-
"Can't yet handle the aggregate of kind {kind:?} and operands:{operands:?}"
326-
),
327-
}
328-
}
329-
_ => todo!("Can't yet handle a rvalue of type {rvalue:?}"),
330-
}
331-
}
332226
pub(crate) fn add_statement<'ctx>(
333227
&mut self,
334228
statement: &Statement<'ctx>,
@@ -339,12 +233,8 @@ impl CLRMethod {
339233
match &statement.kind {
340234
StatementKind::Assign(asign_box) => {
341235
let (place, rvalue) = (asign_box.0, &asign_box.1);
342-
//self.process_rvalue(rvalue, body, tyctx);
343236
let rvalue = RValue::from_rvalue(rvalue, body, tyctx,self);
344-
//self.ops.extend(rvalue.get_ops().iter().map(|op|op.clone()));
345237
AsigmentTarget::from_placement(place,&self).finalize(rvalue,self);
346-
//self.store(place);
347-
//panic!("place:{place:?},rvalue:{rvalue:?}");
348238
}
349239
StatementKind::StorageLive(local) => {
350240
self.var_live((*local).into());

src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ impl FunctionSignature {
5454
pub(crate) fn from_poly_sig(sig: PolyFnSig) -> Option<Self> {
5555
let inputs = sig
5656
.inputs()
57-
// `skip_binder` is `a riskiy thing` TODO: Foigure out to which kind of issues it may lead!
57+
// `skip_binder` is `a riskiy thing` TODO: Figure out to which kind of issues it may lead!
5858
.skip_binder()
5959
//.no_bound_vars()?
6060
.iter()
6161
.map(|v| VariableType::from_ty(*v))
6262
.collect();
6363
let output = VariableType::from_ty(
6464
sig.output()
65-
// `skip_binder` is `a riskiy thing` TODO: Foigure out to which kind of issues it may lead!
65+
// `skip_binder` is `a riskiy thing` TODO: Figure out to which kind of issues it may lead!
6666
.skip_binder(), //.no_bound_vars()?
6767
);
6868
Some(Self { inputs, output })

src/variable.rs

+7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ pub(crate) enum VariableType {
2626
RefMut(Box<Self>),
2727
}
2828
impl VariableType {
29+
pub(crate) fn get_pointed_type(&self)->Option<Self>{
30+
match self{
31+
Self::Ref(inner) => Some((*inner.as_ref()).clone()),
32+
Self::RefMut(inner) => Some((*inner.as_ref()).clone()),
33+
_=>None,
34+
}
35+
}
2936
pub(crate) fn from_ty(ty: Ty) -> Self {
3037
match ty.kind() {
3138
TyKind::Int(IntTy::I8) => VariableType::I8,

test/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
*.rlib
22
*.dll
33
*.rcgu.o
4+
*.mir

test/binops.rs

-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,3 @@ pub extern fn neq(a:i32,b:i32)->bool{a != b}
2525
pub extern fn sqr_mag(ax:i32,ay:i32)->i32{ax*ax + ay*ay}
2626
#[no_mangle]
2727
pub extern fn pow2(power:i32)->i32{1<<power}
28-
/*
29-
#[no_mangle]
30-
pub extern fn set(reference:&mut i32, value:i32){*reference = value}*/

test/references.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#[no_mangle]
2+
pub extern fn set(reference:&mut i32, value:i32){*reference = value}
3+
#[no_mangle]
4+
pub extern fn set_i2(reference:&mut &mut i32, value:i32){**reference = value}
5+
#[no_mangle]
6+
pub extern fn set_i3(reference:&mut &mut &mut i32, value:i32){***reference = value}
7+
#[no_mangle]
8+
pub extern fn set_i4(reference:&mut &mut &mut &mut i32, value:i32){****reference = value}
9+
#[no_mangle]
10+
pub extern fn get(reference:&mut i32)->i32{*reference}

0 commit comments

Comments
 (0)