Skip to content

Commit

Permalink
Added support for statics/constants requiring reallocation
Browse files Browse the repository at this point in the history
  • Loading branch information
FractalFir committed Jan 21, 2024
1 parent de94229 commit 6931f0d
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 12 deletions.
58 changes: 51 additions & 7 deletions src/assembly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::{
r#type::TypeDef,
IString,
};
use rustc_middle::mir::interpret::Allocation;
use rustc_middle::mir::{
interpret::{AllocId, GlobalAlloc},
mono::MonoItem,
Expand Down Expand Up @@ -350,13 +351,34 @@ impl Assembly {
//tcx.reserve_and_set_memory_alloc(alloc)
alloc
}
GlobalAlloc::Function(_) | GlobalAlloc::VTable(..) => {
unreachable!()
GlobalAlloc::VTable(..)=>{
//TODO: handle VTables
let alloc_fld: IString = format!("alloc_{alloc_id:x}").into();
let field_desc = crate::cil::StaticFieldDescriptor::new(
None,
Type::Ptr(Type::U8.into()),
alloc_fld.clone(),
);
self.static_fields.insert(alloc_fld, Type::Ptr(Type::U8.into()));
return field_desc;
}
GlobalAlloc::Function(_) => {
//TODO: handle constant functions
let alloc_fld: IString = format!("alloc_{alloc_id:x}").into();
let field_desc = crate::cil::StaticFieldDescriptor::new(
None,
Type::Ptr(Type::U8.into()),
alloc_fld.clone(),
);
self.static_fields.insert(alloc_fld, Type::Ptr(Type::U8.into()));
return field_desc;
//todo!("Function/Vtable allocation.");
}
};
let const_allocation = const_allocation.inner();
let bytes: &[u8] = const_allocation
.inspect_with_uninit_and_ptr_outside_interpreter(0..const_allocation.len());



//let byte_hash = calculate_hash(&bytes);

let alloc_fld: IString = format!("alloc_{alloc_id:x}").into();
Expand All @@ -366,6 +388,7 @@ impl Assembly {
alloc_fld.clone(),
);
if self.static_fields.get(&alloc_fld).is_none() {
let init_method = allocation_initializer_method(const_allocation, &alloc_fld, tcx,self);
let cctor = self
.functions
.entry(CallSite::new(
Expand All @@ -391,7 +414,8 @@ impl Assembly {
if !ops.is_empty() && ops[ops.len() - 1] == CILOp::Ret {
ops.pop();
}
let init_method = allocation_initializer_method(bytes, &alloc_fld, tcx);


ops.extend([
CILOp::Call(CallSite::boxed(
None,
Expand All @@ -402,6 +426,7 @@ impl Assembly {
CILOp::STStaticField(field_desc.clone().into()),
CILOp::Ret,
]);
//eprintln!("Adding intiailzer named {}. \n Method:{init_method:?}",init_method.name());
self.add_method(init_method);
self.add_static(Type::Ptr(Type::U8.into()), &alloc_fld);
}
Expand Down Expand Up @@ -566,7 +591,11 @@ fn locals_from_mir<'tyctx>(
}
local_types
}
fn allocation_initializer_method(bytes: &[u8], name: &str, tyctx: TyCtxt) -> Method {
fn allocation_initializer_method(const_allocation:&Allocation, name: &str, tyctx: TyCtxt,asm:&mut Assembly) -> Method {
let bytes: &[u8] = const_allocation
.inspect_with_uninit_and_ptr_outside_interpreter(0..const_allocation.len());
let ptrs = const_allocation.provenance().ptrs();

let mut ops = Vec::new();
ops.extend([
CILOp::LdcI64(bytes.len() as u64 as i64),
Expand All @@ -585,9 +614,24 @@ fn allocation_initializer_method(bytes: &[u8], name: &str, tyctx: TyCtxt) -> Met
CILOp::LdcI32(1),
CILOp::Add,
CILOp::STLoc(0),
CILOp::Comment(name.clone().into()),

]);
}
if !ptrs.is_empty(){
for ptr in ptrs.iter(){
let ptr_alloc = asm.add_allocation(ptr.1.alloc_id().0.into(), tyctx);
let offset = ptr.0.bytes_usize() as u32;
ops.extend([
CILOp::LDLoc(1),
CILOp::LdcI32(offset as i32),
CILOp::ConvISize(false),
CILOp::Add,
CILOp::LDStaticField(ptr_alloc.into()),
CILOp::STIndISize,
]);
}
//eprintln!("Constant requires rellocation support!");
}
ops.extend([CILOp::LDLoc(1), CILOp::Ret]);
let mut method = Method::new(
AccessModifer::Private,
Expand Down
1 change: 1 addition & 0 deletions src/compile_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ run_test! {types,slice_ptr_cast,stable}
run_test! {types,slice_index_ref,unstable}
run_test! {types,slice,unstable}
run_test! {types,statics,stable}
run_test! {types,self_referential_statics,stable}
run_test! {std,main,unstable}

run_test! {control_flow,cf_for,stable}
Expand Down
14 changes: 12 additions & 2 deletions src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,18 @@ fn create_const_from_data<'ctx>(
size: Size::from_bytes((len as u64) - offset_bytes),
};
let bytes = memory.0.get_bytes_unchecked(range);
//eprintln!("Creating const {ty:?} from data of length {len}.");
create_const_from_slice(ty, tyctx, bytes, method_instance, tycache)
if memory.0.provenance().ptrs().is_empty(){
//eprintln!("Creating const {ty:?} from data of length {len}.");
create_const_from_slice(ty, tyctx, bytes, method_instance, tycache)
}
else{
let mut ops = vec![CILOp::LoadGlobalAllocPtr { alloc_id:alloc_id.0.into() }];
let ty =crate::utilis::monomorphize(&method_instance, ty, tyctx);
ops.extend(crate::place::deref_op(ty.into(), tyctx, &method_instance, tycache));
ops
//panic!("Constant requires rellocation support!");
}

}

fn load_const_value<'ctx>(
Expand Down
12 changes: 9 additions & 3 deletions src/type/type_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,10 @@ pub fn get_array_type(element_count: usize, element: Type) -> TypeDef {
element.clone(),
"f_0".to_string().into(),
)),
CILOp::Call(as_pointer.clone().into()),
//CILOp::Call(as_pointer.clone().into()),
CILOp::LDArg(1),
CILOp::SizeOf(element.clone().into()),
CILOp::Mul,
CILOp::Add,
CILOp::LDArg(2),
CILOp::STObj(element.clone().into()),
Expand All @@ -295,8 +297,10 @@ pub fn get_array_type(element_count: usize, element: Type) -> TypeDef {
element.clone(),
"f_0".to_string().into(),
)),
CILOp::Call(as_pointer.clone().into()),
//CILOp::Call(as_pointer.clone().into()),
CILOp::LDArg(1),
CILOp::SizeOf(element.clone().into()),
CILOp::Mul,
CILOp::Add,
CILOp::Ret,
];
Expand All @@ -317,8 +321,10 @@ pub fn get_array_type(element_count: usize, element: Type) -> TypeDef {
element.clone(),
"f_0".to_string().into(),
)),
CILOp::Call(as_pointer.into()),
//CILOp::Call(as_pointer.into()),
CILOp::LDArg(1),
CILOp::SizeOf(element.clone().into()),
CILOp::Mul,
CILOp::Add,
CILOp::LdObj(element.into()),
CILOp::Ret,
Expand Down
12 changes: 12 additions & 0 deletions test/types/self_referential_statics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![feature(lang_items,adt_const_params,associated_type_defaults,core_intrinsics,start)]
#![allow(internal_features,incomplete_features,unused_variables,dead_code,improper_ctypes_definitions)]
#![no_std]
include!("../common.rs");
#[allow(dead_code)]
static A:u8 = 10;
static B:u8 = 11;
static NUMBER_LISTS:[&u8;2] = [&A,&B];
fn main(){
test_eq!(*black_box(NUMBER_LISTS[black_box(0)]),10);
test_eq!(*black_box(NUMBER_LISTS[black_box(1)]),11);
}

0 comments on commit 6931f0d

Please sign in to comment.