Skip to content

Commit 5abfe06

Browse files
committed
Updated constants to use byte buffer literals.
1 parent 949c461 commit 5abfe06

File tree

8 files changed

+80
-86
lines changed

8 files changed

+80
-86
lines changed

bin/c_success_coretests.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,7 @@ slice::memchr::no_match
14561456
slice::memchr::no_match_empty
14571457
slice::memchr::no_match_empty_reversed
14581458
slice::memchr::no_match_reversed
1459+
slice::select_nth_unstable
14591460
slice::select_nth_unstable_past_length
14601461
slice::select_nth_unstable_zero_length
14611462
slice::slice_index::assert_range_eq_can_fail_by_inequality

cilly/src/v2/asm.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub struct Assembly {
3434
method_defs: FxHashMap<MethodDefIdx, MethodDef>,
3535
sections: FxHashMap<String, Vec<u8>>,
3636
/// A list of all buffers within this assembly.
37-
buffer: BiMap<Box<[u8]>>,
37+
pub(crate) const_data: BiMap<Box<[u8]>>,
3838
}
3939
impl Index<Interned<IString>> for Assembly {
4040
type Output = str;
@@ -114,6 +114,16 @@ impl Index<Interned<FieldDesc>> for Assembly {
114114
}
115115
}
116116
impl Assembly {
117+
/// Returns a pointer to an immutable(!) byte buffer of a given type.
118+
pub fn bytebuffer(
119+
&mut self,
120+
buffer: &[u8],
121+
tpe: impl IntoAsmIndex<Interned<Type>>,
122+
) -> Interned<CILNode> {
123+
let data = self.const_data.alloc(buffer.into());
124+
let tpe = tpe.into_idx(self);
125+
self.alloc_node(Const::ByteBuffer { data, tpe })
126+
}
117127
/// Offsets `addr` by `index` * sizeof(`tpe`)
118128
pub fn offset(
119129
&mut self,
@@ -1425,8 +1435,8 @@ impl Assembly {
14251435
self.add_static(Type::Void, "global_void", false, main)
14261436
}
14271437

1428-
pub(crate) fn translate_buffer(&self, data: Interned<Box<[u8]>>) -> Interned<Box<[u8]>> {
1429-
todo!()
1438+
pub(crate) fn alloc_const_data(&mut self, data: &[u8]) -> Interned<Box<[u8]>> {
1439+
self.const_data.alloc(data.into())
14301440
}
14311441
}
14321442
config!(GUARANTED_ALIGN, u8, 8);
@@ -1631,7 +1641,11 @@ fn export2() {
16311641
let main_module = asm.main_module();
16321642
let name = asm.alloc_string("entrypoint");
16331643
let sig = asm.sig([], Type::Void);
1634-
let body1 = vec![asm.alloc_root(CILRoot::VoidRet)];
1644+
let buff = asm.bytebuffer(b"Hewwo!", Int::U8);
1645+
let body1 = vec![
1646+
asm.alloc_root(CILRoot::VoidRet),
1647+
asm.alloc_root(CILRoot::Pop(buff)),
1648+
];
16351649
let hbody = vec![asm.alloc_root(CILRoot::ExitSpecialRegion {
16361650
target: 2,
16371651
source: 0,

cilly/src/v2/asm_link.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl Assembly {
114114
super::Const::ByteBuffer { data, tpe } => {
115115
let tpe = self.translate_type(source, source[*tpe]);
116116
CILNode::Const(Box::new(super::Const::ByteBuffer {
117-
data: self.translate_buffer(*data),
117+
data: self.alloc_const_data(&source.const_data[*data]),
118118
tpe: self.alloc_type(tpe),
119119
}))
120120
}

cilly/src/v2/c_exporter/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,11 @@ impl CExporter {
12361236
let mut defined_types: FxHashSet<ClassDefIdx> = FxHashSet::default();
12371237
let mut delayed_defs: FxHashSet<ClassDefIdx> = asm.iter_class_def_ids().cloned().collect();
12381238
let mut delayed_defs_copy: FxHashSet<ClassDefIdx> = FxHashSet::default();
1239+
for (const_data, idx) in asm.const_data.1.iter() {
1240+
let data: String = const_data.iter().map(|u| format!("{u}")).intersperse(",".into()).collect();
1241+
let encoded = encode(idx.inner() as u64);
1242+
writeln!(type_defs, "uint8_t c_{encoded}[] = {{{data}}};")?;
1243+
}
12391244
// Ensure RustVoid present
12401245
let rust_void = asm.rust_void();
12411246
self.export_class(
@@ -1310,6 +1315,7 @@ impl CExporter {
13101315
extrn: bool,
13111316
is_main: bool,
13121317
) -> Result<(), std::io::Error> {
1318+
13131319
let mut c_out = std::io::BufWriter::new(std::fs::File::create(c_path)?);
13141320
println!("Exporting {c_path:?}");
13151321

cilly/src/v2/il_exporter/mod.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::{utilis::assert_unique, MethodImpl};
1+
use crate::{
2+
utilis::{assert_unique, encode},
3+
MethodImpl,
4+
};
25

36
use std::{io::Write, path::Path};
47

@@ -27,6 +30,11 @@ impl ILExporter {
2730
fn export_to_write(&self, asm: &super::Assembly, out: &mut impl Write) -> std::io::Result<()> {
2831
let asm_mut = &mut asm.clone();
2932
writeln!(out, ".assembly _{{}}")?;
33+
for (const_data, idx) in asm.const_data.1.iter() {
34+
let encoded = encode(idx.inner() as u64);
35+
let data: String = const_data.iter().map(|u| format!("{u:x} ")).collect();
36+
writeln!(out, " .data cil I_{encoded} = bytearray ({data})\n.field assembly static uint8 c_{encoded} at I_{encoded}")?;
37+
}
3038
// Iterate trough all types
3139
for class_def in asm.iter_class_defs() {
3240
let vis = match class_def.access() {
@@ -251,8 +259,8 @@ impl ILExporter {
251259
let node = asm.get_node(node).clone();
252260
match node {
253261
CILNode::Const(cst) => match cst.as_ref() {
254-
super::Const::ByteBuffer { data, tpe }=>{
255-
todo!("ByteBuffers not supported in IL yet.")
262+
super::Const::ByteBuffer { data, tpe:_ }=>{
263+
writeln!(out,"ldsflda uint8 c_{}", encode(data.inner() as u64))
256264
}
257265
super::Const::Null(_) => writeln!(out, "ldnull"),
258266
super::Const::I8(val) => match val {

rustc_codgen_clr_operand/src/constant.rs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ fn create_const_from_data<'tcx>(
5858
Scalar::from_u128(u128::from_ne_bytes(bytes.as_slice().try_into().unwrap()));
5959
return load_const_scalar(scalar, ty, ctx);
6060
}
61+
let ptr = alloc_ptr(alloc_id, &alloc, ctx);
62+
let ty = ctx.monomorphize(ty);
63+
64+
let tpe = ctx.type_from_cache(ty);
65+
let tpe_ptr = ctx.nptr(tpe);
66+
return CILNode::LdObj {
67+
ptr: Box::new(ptr.cast_ptr(tpe_ptr)),
68+
obj: Box::new(tpe),
69+
};
6170
}
6271
let ptr = CILNode::LoadGlobalAllocPtr {
6372
alloc_id: alloc_id.0.into(),
@@ -93,9 +102,9 @@ pub fn load_const_value<'tcx>(
93102
let slice_dotnet = slice_type.as_class_ref().expect("Slice type invalid!");
94103

95104
let alloc_id = ctx.tcx().reserve_and_set_memory_alloc(data);
96-
let alloc_id: u64 = alloc_id.0.into();
105+
97106
let meta = CILNode::V2(ctx.alloc_node(Const::USize(meta)));
98-
let ptr = CILNode::LoadGlobalAllocPtr { alloc_id }.cast_ptr(ctx.nptr(Type::Void));
107+
let ptr = alloc_ptr(alloc_id, &data, ctx).cast_ptr(ctx.nptr(Type::Void));
99108
CILNode::create_slice(slice_dotnet, ctx, meta, ptr)
100109
}
101110
ConstValue::Indirect { alloc_id, offset } => {
@@ -172,21 +181,16 @@ fn load_scalar_ptr(
172181
let alloc_id = alloc_id.alloc_id().0.into();
173182
CILNode::LoadGlobalAllocPtr { alloc_id }
174183
}
175-
GlobalAlloc::Memory(_const_allocation) => {
184+
GlobalAlloc::Memory(const_allocation) => {
176185
if offset.bytes() != 0 {
177186
CILNode::Add(
178-
CILNode::LoadGlobalAllocPtr {
179-
alloc_id: alloc_id.alloc_id().0.into(),
180-
}
181-
.into(),
187+
alloc_ptr(alloc_id.alloc_id(), &const_allocation, ctx).into(),
182188
Box::new(CILNode::V2(
183189
ctx.alloc_node(cilly::Const::USize(offset.bytes())),
184190
)),
185191
)
186192
} else {
187-
CILNode::LoadGlobalAllocPtr {
188-
alloc_id: alloc_id.alloc_id().0.into(),
189-
}
193+
alloc_ptr(alloc_id.alloc_id(), &const_allocation, ctx)
190194
}
191195
}
192196
GlobalAlloc::Function {
@@ -217,6 +221,24 @@ fn load_scalar_ptr(
217221
}
218222
//panic!("alloc_id:{alloc_id:?}")
219223
}
224+
fn alloc_ptr<'tcx>(
225+
alloc_id: AllocId,
226+
const_alloc: &rustc_middle::mir::interpret::ConstAllocation,
227+
ctx: &mut MethodCompileCtx<'tcx, '_>,
228+
) -> CILNode {
229+
let const_alloc = const_alloc.inner();
230+
// If aligement is small enough to be *guaranteed*, and no pointers are present.
231+
if const_alloc.align.bytes() <= 1 && const_alloc.provenance().ptrs().is_empty() {
232+
CILNode::V2(ctx.bytebuffer(
233+
const_alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..const_alloc.len()),
234+
Int::U8,
235+
))
236+
} else {
237+
CILNode::LoadGlobalAllocPtr {
238+
alloc_id: alloc_id.0.into(),
239+
}
240+
}
241+
}
220242
fn load_const_scalar<'tcx>(
221243
scalar: Scalar,
222244
scalar_type: Ty<'tcx>,

src/assembly.rs

Lines changed: 10 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -132,74 +132,17 @@ fn allocation_initializer_method(
132132
);
133133
}
134134

135-
if !bytes.iter().all(|byte| *byte != 0) {
136-
trees.push(
137-
CILRoot::InitBlk {
138-
dst: Box::new(CILNode::LDLoc(0)),
139-
val: Box::new(CILNode::V2(asm.alloc_node(0_u8))),
140-
count: Box::new(CILNode::V2(
141-
asm.alloc_node(Const::USize(bytes.len() as u64)),
142-
)),
143-
}
144-
.into(),
145-
);
146-
}
147-
let mut offset = 0;
148-
while offset < bytes.len() {
149-
let reminder = bytes.len() - offset;
150-
match reminder {
151-
8.. => {
152-
let long = u64::from_ne_bytes(bytes[offset..(offset + 8)].try_into().unwrap());
153-
if long != 0 {
154-
trees.push(
155-
CILRoot::STIndI64(
156-
(CILNode::LDLoc(0)
157-
+ CILNode::V2(
158-
asm.alloc_node(Const::USize(offset.try_into().unwrap())),
159-
))
160-
.cast_ptr(asm.nptr(Type::Int(Int::U64))),
161-
CILNode::V2(asm.alloc_node(long)),
162-
)
163-
.into(),
164-
);
165-
}
166-
offset += 8;
167-
}
168-
4.. => {
169-
let long = u32::from_ne_bytes(bytes[offset..(offset + 4)].try_into().unwrap());
170-
if long != 0 {
171-
trees.push(
172-
CILRoot::STIndI32(
173-
(CILNode::LDLoc(0)
174-
+ CILNode::V2(
175-
asm.alloc_node(Const::USize(offset.try_into().unwrap())),
176-
))
177-
.cast_ptr(asm.nptr(Type::Int(Int::U32))),
178-
CILNode::V2(asm.alloc_node(long)),
179-
)
180-
.into(),
181-
);
182-
}
183-
offset += 4;
184-
}
185-
_ => {
186-
let byte = bytes[offset];
187-
if byte != 0 {
188-
trees.push(
189-
CILRoot::STIndI8(
190-
CILNode::LDLoc(0)
191-
+ CILNode::V2(
192-
asm.alloc_node(Const::USize(offset.try_into().unwrap())),
193-
),
194-
CILNode::V2(asm.alloc_node(byte)),
195-
)
196-
.into(),
197-
);
198-
}
199-
offset += 1;
200-
}
135+
trees.push(
136+
CILRoot::CpBlk {
137+
dst: Box::new(CILNode::LDLoc(0)),
138+
src: Box::new(CILNode::V2(asm.bytebuffer(bytes, Int::U8))),
139+
len: Box::new(CILNode::V2(
140+
asm.alloc_node(Const::USize(bytes.len() as u64)),
141+
)),
201142
}
202-
}
143+
.into(),
144+
);
145+
203146
if !ptrs.is_empty() {
204147
for (offset, prov) in ptrs.iter() {
205148
let offset = u32::try_from(offset.bytes_usize()).unwrap();

test/types/nbody.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ struct RNG {
8383
}
8484
impl RNG {
8585
fn next_i16(&mut self) -> i16 {
86-
self.state = 214013 * self.state + 2531011;
86+
self.state = 214013_i32.wrapping_mul(self.state).wrapping_add(2531011);
8787
return ((self.state >> 16) & 0xFFFF) as i16;
8888
}
8989
fn next_f32(&mut self) -> f32 {

0 commit comments

Comments
 (0)