Skip to content

Commit 71f409c

Browse files
committed
Indexing related bugfixes
1 parent 5465461 commit 71f409c

File tree

7 files changed

+191
-48
lines changed

7 files changed

+191
-48
lines changed

src/compile_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ run_test! {types,vec}
587587
run_test! {types,string_slice}
588588
run_test! {types,ref_deref}
589589
run_test! {types,slice_ptr_cast}
590-
590+
run_test! {types,slice_index_ref}
591591
run_test! {types,slice}
592592
run_test! {types,statics}
593593
run_test! {std,main}

src/ffi/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,15 @@ pub fn insert_ffi_functions(asm: &mut Assembly, tyctx: TyCtxt) {
178178
);
179179
volatile_load.set_ops(vec![CILOp::LDArg(0), CILOp::LDIndI8, CILOp::Ret]);
180180
asm.add_method(volatile_load);
181+
let mut volatile_load = Method::new(
182+
AccessModifer::Private,
183+
true,
184+
FnSig::new(&[Type::Ptr(Type::USize.into())], &Type::USize),
185+
"volatile_load",
186+
vec![],
187+
);
188+
volatile_load.set_ops(vec![CILOp::LDArg(0), CILOp::LDIndISize, CILOp::Ret]);
189+
asm.add_method(volatile_load);
181190
abort(asm);
182191
}
183192

src/place/adress.rs

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,74 @@ pub fn place_elem_adress<'ctx>(
183183
}
184184
}
185185
}
186+
PlaceElem::ConstantIndex {
187+
offset,
188+
min_length,
189+
from_end,
190+
} => {
191+
let curr_ty = curr_type
192+
.as_ty()
193+
.expect("INVALID PLACE: Indexing into enum variant???");
194+
let index = CILOp::LdcI64(*offset as i64);
195+
assert!(!from_end, "Indexing slice form end");
196+
eprintln!("WARNING: ConstantIndex has required min_length of {min_length}, but bounds checking on const access not supported yet!");
197+
match curr_ty.kind() {
198+
TyKind::Slice(inner) => {
199+
let inner = crate::utilis::monomorphize(&method_instance, *inner, tyctx);
200+
let inner_type =
201+
type_cache.type_from_cache(inner, tyctx, Some(method_instance));
202+
let slice = type_cache
203+
.slice_ty(inner, tyctx, Some(method_instance))
204+
.as_dotnet()
205+
.unwrap();
206+
let desc = FieldDescriptor::new(
207+
slice,
208+
Type::Ptr(Type::Void.into()),
209+
"data_address".into(),
210+
);
211+
let derf_op = super::deref_op(
212+
super::PlaceTy::Ty(inner),
213+
tyctx,
214+
&method_instance,
215+
type_cache,
216+
);
217+
let mut ops = vec![
218+
CILOp::LDField(desc.into()),
219+
index,
220+
CILOp::SizeOf(inner_type.into()),
221+
CILOp::Mul,
222+
CILOp::Add,
223+
];
224+
225+
ops.extend(derf_op);
226+
ops
227+
}
228+
TyKind::Array(element, _length) => {
229+
let element_ty = crate::utilis::monomorphize(&method_instance, *element, tyctx);
230+
let element = type_cache.type_from_cache(element_ty, tyctx, Some(method_instance));
231+
let array_type =
232+
type_cache.type_from_cache(curr_ty, tyctx, Some(method_instance));
233+
let array_dotnet = array_type.as_dotnet().expect("Non array type");
234+
vec![
235+
index,
236+
CILOp::Call(
237+
crate::cil::CallSite::new(
238+
Some(array_dotnet),
239+
"get_Adress".into(),
240+
FnSig::new(&[array_type, Type::USize], &element),
241+
false,
242+
)
243+
.into(),
244+
),
245+
]
246+
}
247+
_ => {
248+
rustc_middle::ty::print::with_no_trimmed_paths! { todo!("Can't index into {curr_ty}!")}
249+
}
250+
}
251+
}
186252
_ => {
187-
rustc_middle::ty::print::with_no_trimmed_paths! {todo!("Can't handle porojection {place_elem:?} in body")}
253+
rustc_middle::ty::print::with_no_trimmed_paths! {todo!("Can't handle porojection {place_elem:?} in adress")}
188254
}
189255
}
190256
}

src/place/body.rs

Lines changed: 78 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -105,46 +105,6 @@ pub fn place_elem_body<'ctx>(
105105
let variant_type = PlaceTy::EnumVariant(curr_type, variant.as_u32());
106106
(variant_type, vec![CILOp::LDFieldAdress(field_desc)])
107107
}
108-
PlaceElem::ConstantIndex {
109-
offset,
110-
min_length,
111-
from_end,
112-
} => {
113-
let curr_ty = curr_type
114-
.as_ty()
115-
.expect("INVALID PLACE: Indexing into enum variant???");
116-
let index = CILOp::LdcI64(*offset as i64);
117-
assert!(!from_end, "Indexing slice form end");
118-
eprintln!("WARNING: ConstantIndex has required min_length of {min_length}, but bounds checking on const access not supported yet!");
119-
match curr_ty.kind() {
120-
TyKind::Slice(inner) => {
121-
let inner = crate::utilis::monomorphize(&method_instance, *inner, tyctx);
122-
let inner_type =
123-
type_cache.type_from_cache(inner, tyctx, Some(method_instance));
124-
let slice = type_cache
125-
.slice_ty(inner, tyctx, Some(method_instance))
126-
.as_dotnet()
127-
.unwrap();
128-
let desc = FieldDescriptor::new(
129-
slice,
130-
Type::Ptr(Type::Void.into()),
131-
"data_address".into(),
132-
);
133-
let ops = vec![
134-
CILOp::LDField(desc.into()),
135-
index,
136-
CILOp::SizeOf(inner_type.into()),
137-
CILOp::Mul,
138-
CILOp::Add,
139-
];
140-
(inner.into(), ops)
141-
}
142-
143-
_ => {
144-
rustc_middle::ty::print::with_no_trimmed_paths! { todo!("Can't index into {curr_ty}!")}
145-
}
146-
}
147-
}
148108
PlaceElem::Index(index) => {
149109
let curr_ty = curr_type
150110
.as_ty()
@@ -230,6 +190,84 @@ pub fn place_elem_body<'ctx>(
230190
}
231191
}
232192
}
193+
PlaceElem::ConstantIndex {
194+
offset,
195+
min_length,
196+
from_end,
197+
} => {
198+
let curr_ty = curr_type
199+
.as_ty()
200+
.expect("INVALID PLACE: Indexing into enum variant???");
201+
let index = CILOp::LdcI64(*offset as i64);
202+
assert!(!from_end, "Indexing slice form end");
203+
eprintln!("WARNING: ConstantIndex has required min_length of {min_length}, but bounds checking on const access not supported yet!");
204+
match curr_ty.kind() {
205+
TyKind::Slice(inner) => {
206+
let inner = crate::utilis::monomorphize(&method_instance, *inner, tyctx);
207+
let inner_type =
208+
type_cache.type_from_cache(inner, tyctx, Some(method_instance));
209+
let slice = type_cache
210+
.slice_ty(inner, tyctx, Some(method_instance))
211+
.as_dotnet()
212+
.unwrap();
213+
let desc = FieldDescriptor::new(
214+
slice,
215+
Type::Ptr(Type::Void.into()),
216+
"data_address".into(),
217+
);
218+
let derf_op = super::deref_op(
219+
super::PlaceTy::Ty(inner),
220+
tyctx,
221+
&method_instance,
222+
type_cache,
223+
);
224+
let mut ops = vec![
225+
CILOp::LDField(desc.into()),
226+
index,
227+
CILOp::SizeOf(inner_type.into()),
228+
CILOp::Mul,
229+
CILOp::Add,
230+
];
231+
if !body_ty_is_by_adress(inner) {
232+
ops.extend(super::deref_op(
233+
super::PlaceTy::Ty(inner),
234+
tyctx,
235+
&method_instance,
236+
type_cache,
237+
));
238+
}
239+
ops.extend(derf_op);
240+
(inner.into(), ops)
241+
}
242+
TyKind::Array(element, _length) => {
243+
let element_ty = crate::utilis::monomorphize(&method_instance, *element, tyctx);
244+
let element = type_cache.type_from_cache(element_ty, tyctx, Some(method_instance));
245+
let array_type =
246+
type_cache.type_from_cache(curr_ty, tyctx, Some(method_instance));
247+
let array_dotnet = array_type.as_dotnet().expect("Non array type");
248+
if !body_ty_is_by_adress(element_ty) {
249+
((element_ty).into(),vec![
250+
index,
251+
CILOp::Call(
252+
crate::cil::CallSite::new(
253+
Some(array_dotnet),
254+
"get_Item".into(),
255+
FnSig::new(&[array_type, Type::USize], &element),
256+
false,
257+
)
258+
.into(),
259+
),
260+
])
261+
}else{
262+
todo!()
263+
}
264+
265+
}
266+
_ => {
267+
rustc_middle::ty::print::with_no_trimmed_paths! { todo!("Can't index into {curr_ty}!")}
268+
}
269+
}
270+
}
233271
_ => todo!("Can't handle porojection {place_elem:?} in body"),
234272
}
235273
}

src/rvalue.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use crate::cil::{CILOp, FieldDescriptor};
1+
use crate::cil::{CILOp, FieldDescriptor, CallSite};
2+
use crate::function_sig::FnSig;
23
use crate::operand::handle_operand;
34
use crate::place::deref_op;
45
use crate::r#type::{TyCache, Type};
@@ -387,6 +388,26 @@ pub fn handle_rvalue<'tcx>(
387388
}
388389
ops
389390
}
391+
Rvalue::Repeat(operand,times)=>{
392+
let times = times. try_eval_target_usize(tyctx,ParamEnv::reveal_all()).expect("Could not evalute array size as usize.");
393+
let array = crate::utilis::monomorphize(&method_instance, rvalue.ty(method,tyctx), tyctx);
394+
let array = tycache.type_from_cache(array, tyctx, Some(method_instance));
395+
let array_dotnet = array.clone().as_dotnet().expect("Invalid array type.");
396+
397+
let operand_type = tycache.type_from_cache(crate::utilis::monomorphize(&method_instance, operand.ty(method,tyctx), tyctx), tyctx, Some(method_instance));
398+
let operand = handle_operand(operand, tyctx, method, method_instance, tycache);
399+
let mut ops = Vec::new();
400+
ops.push(CILOp::NewTMPLocal(array.clone().into()));
401+
for idx in 0..times{
402+
ops.push(CILOp::LoadAddresOfTMPLocal);
403+
ops.extend(operand.clone());
404+
ops.extend([CILOp::LdcI64(idx as u64 as i64),CILOp::ConvUSize(false)]);
405+
ops.push(CILOp::Call(CallSite::new(Some(array_dotnet.clone()),"set_Item".into(),FnSig::new(&[array.clone(),Type::USize,operand_type.clone()],&Type::Void),false).into()));
406+
}
407+
ops.push(CILOp::LoadTMPLocal);
408+
ops.push(CILOp::FreeTMPLocal);
409+
ops
410+
}
390411
_ => rustc_middle::ty::print::with_no_trimmed_paths! {todo!("Unhandled RValue {rvalue:?}")},
391412
};
392413
res

src/type/type_def.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,8 @@ pub fn escape_field_name(name: &str) -> IString {
172172
}
173173
}
174174
pub fn closure_name(def_id: DefId, fields: &[Type], sig: &crate::function_sig::FnSig) -> String {
175-
let krate = def_id.krate.as_u32();
176-
let index = def_id.index.as_u32();
177-
// Fields and sig would describe the closure better and COULD be used to reduce ammount of types needed.
178-
let _ = (fields, sig);
179-
format!("Closure{index:x}_{krate:x}")
175+
let mangled_fields:String = fields.iter().map(|f|crate::r#type::mangle(f)).collect();
176+
format!("Closure{field_count}{mangled_fields}",field_count = fields.len())
180177
}
181178
pub fn closure_typedef(def_id: DefId, fields: &[Type], sig: crate::function_sig::FnSig) -> TypeDef {
182179
let name = closure_name(def_id, fields, &sig);

test/types/slice_index_ref.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(lang_items,adt_const_params,associated_type_defaults,core_intrinsics,start)]
2+
#![allow(internal_features,incomplete_features,unused_variables,dead_code)]
3+
#![no_std]
4+
include!("../common.rs");
5+
pub fn main(){
6+
let a = [0;8];
7+
let b = black_box(&a[..]);
8+
let c = black_box(&((*b)[8]));
9+
let a = [b;8];
10+
let b = black_box(&a[..]);
11+
let c = black_box(&((*b)[8]));
12+
}

0 commit comments

Comments
 (0)