Skip to content
Snippets Groups Projects
Commit ae01ccb8 authored by Russel Arbore's avatar Russel Arbore
Browse files

Properly calculate runtime size of array

parent b9beeaf0
No related branches found
No related tags found
1 merge request!24Handle arrays properly in the runtime (part 1)
...@@ -65,6 +65,16 @@ pub fn codegen<W: Write>( ...@@ -65,6 +65,16 @@ pub fn codegen<W: Write>(
Ok(ModuleManifest { Ok(ModuleManifest {
functions: manifests, functions: manifests,
types: module.types.clone(), types: module.types.clone(),
type_sizes_aligns: (0..module.types.len())
.map(|idx| {
if module.types[idx].is_control() {
(None, 0)
} else {
type_size_and_alignment(module, TypeID::new(idx))
}
})
.collect(),
dynamic_constants: module.dynamic_constants.clone(),
// Get the types of all of the constants. This requires collecting over // Get the types of all of the constants. This requires collecting over
// all of the functions, since the calculated types of constants may be // all of the functions, since the calculated types of constants may be
// distributed over many functions. This may contain duplicate mappings, // distributed over many functions. This may contain duplicate mappings,
......
...@@ -113,7 +113,7 @@ pub enum Constant { ...@@ -113,7 +113,7 @@ pub enum Constant {
* allocation - by providing dynamic constants to the conductor API, the * allocation - by providing dynamic constants to the conductor API, the
* conductor can allocate memory as necessary. * conductor can allocate memory as necessary.
*/ */
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum DynamicConstant { pub enum DynamicConstant {
Constant(usize), Constant(usize),
Parameter(usize), Parameter(usize),
......
...@@ -17,6 +17,10 @@ pub struct ModuleManifest { ...@@ -17,6 +17,10 @@ pub struct ModuleManifest {
pub functions: Vec<FunctionManifest>, pub functions: Vec<FunctionManifest>,
// All of the types used in the module. // All of the types used in the module.
pub types: Vec<Type>, pub types: Vec<Type>,
// All of the sizes and alignments for types in the module.
pub type_sizes_aligns: Vec<(Option<usize>, usize)>,
// All of the dynamic constants used in the module.
pub dynamic_constants: Vec<DynamicConstant>,
// Store the types of constants. // Store the types of constants.
pub constant_types: Vec<(ConstantID, TypeID)>, pub constant_types: Vec<(ConstantID, TypeID)>,
// The only constants that aren't baked into the generated code are array // The only constants that aren't baked into the generated code are array
......
...@@ -53,11 +53,35 @@ fn generate_type_string(ty: &Type, rust_types: &Vec<String>) -> String { ...@@ -53,11 +53,35 @@ fn generate_type_string(ty: &Type, rust_types: &Vec<String>) -> String {
} }
/* /*
* Emit dynamic constant math to calculate the runtime size of an array, in * Emit a dynamic constant, which isn't necessarily just a dynamic constant
* number of bytes. * parameter.
*/ */
fn emit_array_size_expression(ty: TypeID, manifest: &ModuleManifest) -> String { fn emit_dynamic_constant(dc: DynamicConstantID, manifest: &ModuleManifest) -> String {
"16".to_string() match manifest.dynamic_constants[dc.idx()] {
DynamicConstant::Constant(val) => format!("{}", val),
DynamicConstant::Parameter(idx) => format!("dyn_cons_{}", idx),
}
}
/*
* Emit dynamic constant math to calculate the runtime size of a type, in number
* of bytes.
*/
fn emit_type_size_expression(ty: TypeID, manifest: &ModuleManifest) -> String {
match manifest.types[ty.idx()] {
Type::Array(elem, ref dcs) => {
dcs.iter().fold(
"(".to_string() + &emit_type_size_expression(elem, manifest),
|acc, dc| acc + " * " + &emit_dynamic_constant(*dc, manifest),
) + ")"
}
_ => format!(
"{}",
manifest.type_sizes_aligns[ty.idx()]
.0
.expect("PANIC: Size of non-array type is unknown at compile-time.")
),
}
} }
/* /*
...@@ -188,7 +212,7 @@ fn codegen(manifest: &ModuleManifest, elf: &[u8]) -> Result<String, anyhow::Erro ...@@ -188,7 +212,7 @@ fn codegen(manifest: &ModuleManifest, elf: &[u8]) -> Result<String, anyhow::Erro
)?; )?;
} }
// Declare all of the array constant memories. We declare them as Boxes // Declare all of the array constant memories. We declare them as Vecs
// to allocate the memories. We emit multiplications of the dynamic // to allocate the memories. We emit multiplications of the dynamic
// constant dimensions to allocate the whole memory as one contiguous // constant dimensions to allocate the whole memory as one contiguous
// range. TODO: emit only the array constants actually used in this // range. TODO: emit only the array constants actually used in this
...@@ -203,9 +227,9 @@ fn codegen(manifest: &ModuleManifest, elf: &[u8]) -> Result<String, anyhow::Erro ...@@ -203,9 +227,9 @@ fn codegen(manifest: &ModuleManifest, elf: &[u8]) -> Result<String, anyhow::Erro
.1; .1;
write!( write!(
rust_code, rust_code,
"let mut arr_cons_{}_vec = vec![0u8; {}];let mut arr_cons_{} = arr_cons_{}_vec.as_mut_ptr();arr_cons_{}_vec.leak();", "let mut arr_cons_{}_vec = vec![0u8; {} as usize];let mut arr_cons_{} = arr_cons_{}_vec.as_mut_ptr();arr_cons_{}_vec.leak();",
arr_cons_num, arr_cons_num,
emit_array_size_expression(arr_ty_id, manifest), emit_type_size_expression(arr_ty_id, manifest),
arr_cons_num, arr_cons_num,
arr_cons_num, arr_cons_num,
arr_cons_num, arr_cons_num,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment