aboutsummaryrefslogtreecommitdiff
path: root/patio-to-cranelift/src/codegen/types.rs
diff options
context:
space:
mode:
Diffstat (limited to 'patio-to-cranelift/src/codegen/types.rs')
-rw-r--r--patio-to-cranelift/src/codegen/types.rs321
1 files changed, 207 insertions, 114 deletions
diff --git a/patio-to-cranelift/src/codegen/types.rs b/patio-to-cranelift/src/codegen/types.rs
index 21833f3f..616520f7 100644
--- a/patio-to-cranelift/src/codegen/types.rs
+++ b/patio-to-cranelift/src/codegen/types.rs
@@ -1,21 +1,28 @@
-use crate::patio::types::{PatioDataLayout, PatioType};
+use crate::patio::types::{
+ PatioBoolType, PatioByteType, PatioDataLayout, PatioDataPtrType, PatioFunctionPtrType,
+ PatioInt32Type, PatioIntType, PatioType,
+};
pub(crate) fn patio_type_to_cranelift_type(
- patio_type: PatioType,
+ patio_type: &PatioType,
target_triple: &target_lexicon::Triple,
) -> cranelift::prelude::Type {
match patio_type {
- PatioType::Bool => CRANELIFT_BOOL_TYPE,
+ PatioType::PatioBoolType(_) => CRANELIFT_BOOL_TYPE,
- PatioType::Byte => CRANELIFT_BYTE_TYPE,
+ PatioType::PatioByteType(_) => CRANELIFT_BYTE_TYPE,
- PatioType::DataPtr => cranelift::prelude::Type::triple_pointer_type(&target_triple),
+ PatioType::PatioDataPtrType(_) => {
+ cranelift::prelude::Type::triple_pointer_type(&target_triple)
+ }
- PatioType::FunctionPtr => cranelift::prelude::Type::triple_pointer_type(&target_triple),
+ PatioType::PatioFunctionPtrType(_) => {
+ cranelift::prelude::Type::triple_pointer_type(&target_triple)
+ }
- PatioType::Int => cranelift_int_type(target_triple),
+ PatioType::PatioIntType(_) => cranelift_int_type(target_triple),
- PatioType::Int32 => CRANELIFT_INT_32_TYPE,
+ PatioType::PatioInt32Type(_) => CRANELIFT_INT_32_TYPE,
}
}
@@ -41,27 +48,29 @@ pub(crate) fn data_layout_byte_size(
target_triple: &target_lexicon::Triple,
) -> u32 {
match layout {
- PatioDataLayout::Array { element, size } => {
- data_layout_byte_size(element, target_triple) * size
+ PatioDataLayout::PatioDataLayoutArray(array) => {
+ data_layout_byte_size(&array.element, target_triple)
+ * u32::try_from(array.size).unwrap()
}
- PatioDataLayout::Bool => CRANELIFT_BOOL_TYPE.bytes(),
+ PatioDataLayout::PatioDataLayoutBool(_) => CRANELIFT_BOOL_TYPE.bytes(),
- PatioDataLayout::Byte => CRANELIFT_BYTE_TYPE.bytes(),
+ PatioDataLayout::PatioDataLayoutByte(_) => CRANELIFT_BYTE_TYPE.bytes(),
- PatioDataLayout::DataPtr => {
+ PatioDataLayout::PatioDataLayoutDataPtr(_) => {
cranelift::prelude::Type::triple_pointer_type(&target_triple).bytes()
}
- PatioDataLayout::FunctionPtr => {
+ PatioDataLayout::PatioDataLayoutFunctionPtr(_) => {
cranelift::prelude::Type::triple_pointer_type(&target_triple).bytes()
}
- PatioDataLayout::Int => cranelift_int_type(target_triple).bytes(),
+ PatioDataLayout::PatioDataLayoutInt(_) => cranelift_int_type(target_triple).bytes(),
- PatioDataLayout::Int32 => CRANELIFT_INT_32_TYPE.bytes(),
+ PatioDataLayout::PatioDataLayoutInt32(_) => CRANELIFT_INT_32_TYPE.bytes(),
- PatioDataLayout::Struct { elements } => elements
+ PatioDataLayout::PatioDataLayoutStruct(layout_struct) => layout_struct
+ .elements
.iter()
.map(|element| data_layout_byte_size(element, target_triple))
.sum(),
@@ -72,7 +81,11 @@ pub(crate) fn data_layout_byte_size(
mod data_layout_byte_size_test {
use std::str::FromStr;
- use crate::patio::types::PatioDataLayout;
+ use crate::patio::types::{
+ PatioDataLayout, PatioDataLayoutArray, PatioDataLayoutBool, PatioDataLayoutByte,
+ PatioDataLayoutDataPtr, PatioDataLayoutFunctionPtr, PatioDataLayoutInt,
+ PatioDataLayoutInt32, PatioDataLayoutStruct,
+ };
fn data_layout_byte_size(layout: &PatioDataLayout) -> u32 {
super::data_layout_byte_size(
@@ -83,38 +96,44 @@ mod data_layout_byte_size_test {
#[test]
fn bool_is_one_byte() {
- assert_eq!(data_layout_byte_size(&PatioDataLayout::Bool), 1);
+ assert_eq!(data_layout_byte_size(&PatioDataLayoutBool.into()), 1);
}
#[test]
fn byte_is_one_byte() {
- assert_eq!(data_layout_byte_size(&PatioDataLayout::Byte), 1);
+ assert_eq!(data_layout_byte_size(&PatioDataLayoutByte.into()), 1);
}
#[test]
fn data_ptr_is_width_of_pointer() {
- assert_eq!(data_layout_byte_size(&PatioDataLayout::DataPtr), 8);
+ assert_eq!(data_layout_byte_size(&PatioDataLayoutDataPtr.into()), 8);
}
#[test]
fn function_ptr_is_width_of_pointer() {
- assert_eq!(data_layout_byte_size(&PatioDataLayout::FunctionPtr), 8);
+ assert_eq!(data_layout_byte_size(&PatioDataLayoutFunctionPtr.into()), 8);
}
#[test]
fn int_is_width_of_pointer_and_at_least_32_bits() {
- assert_eq!(data_layout_byte_size(&PatioDataLayout::Int), 8);
+ assert_eq!(data_layout_byte_size(&PatioDataLayoutInt.into()), 8);
}
#[test]
fn int32_is_four_bytes() {
- assert_eq!(data_layout_byte_size(&PatioDataLayout::Int32), 4);
+ assert_eq!(data_layout_byte_size(&PatioDataLayoutInt32.into()), 4);
}
#[test]
fn array_size_is_size_of_each_element_multiplied_by_number_of_elements() {
assert_eq!(
- data_layout_byte_size(&PatioDataLayout::array(PatioDataLayout::Int32, 7)),
+ data_layout_byte_size(
+ &PatioDataLayoutArray {
+ element: PatioDataLayoutInt32.into(),
+ size: 7
+ }
+ .into()
+ ),
28
);
}
@@ -122,10 +141,15 @@ mod data_layout_byte_size_test {
#[test]
fn struct_size_is_sum_of_element_sizes() {
assert_eq!(
- data_layout_byte_size(&PatioDataLayout::struct_(vec![
- PatioDataLayout::Int32,
- PatioDataLayout::Byte
- ])),
+ data_layout_byte_size(
+ &PatioDataLayoutStruct {
+ elements: vec![
+ PatioDataLayout::PatioDataLayoutInt32(PatioDataLayoutInt32),
+ PatioDataLayout::PatioDataLayoutByte(PatioDataLayoutByte)
+ ]
+ }
+ .into()
+ ),
5
);
}
@@ -133,7 +157,7 @@ mod data_layout_byte_size_test {
pub(crate) fn data_layout_byte_offset(
layout: &PatioDataLayout,
- element_offsets: &[u32],
+ element_offsets: &[i32],
target_triple: &target_lexicon::Triple,
) -> u32 {
let mut byte_offset = 0;
@@ -141,24 +165,32 @@ pub(crate) fn data_layout_byte_offset(
for element_offset in element_offsets {
match current_element {
- PatioDataLayout::Array { element, size: _ } => {
- byte_offset += data_layout_byte_size(element, target_triple) * element_offset;
- current_element = element;
+ PatioDataLayout::PatioDataLayoutArray(array) => {
+ byte_offset += data_layout_byte_size(&array.element, target_triple)
+ * u32::try_from(*element_offset).unwrap();
+ current_element = &array.element;
}
- PatioDataLayout::Bool => panic!("offset not allowed for bool"),
- PatioDataLayout::Byte => panic!("offset not allowed for byte"),
- PatioDataLayout::DataPtr => panic!("offset not allowed for data ptr"),
- PatioDataLayout::FunctionPtr => panic!("offset not allowed for function ptr"),
- PatioDataLayout::Int => panic!("offset not allowed for int"),
- PatioDataLayout::Int32 => panic!("offset not allowed for int32"),
-
- PatioDataLayout::Struct { elements } => {
- for element in elements.iter().take((*element_offset).try_into().unwrap()) {
+ PatioDataLayout::PatioDataLayoutBool(_) => panic!("offset not allowed for bool"),
+ PatioDataLayout::PatioDataLayoutByte(_) => panic!("offset not allowed for byte"),
+ PatioDataLayout::PatioDataLayoutDataPtr(_) => panic!("offset not allowed for data ptr"),
+ PatioDataLayout::PatioDataLayoutFunctionPtr(_) => {
+ panic!("offset not allowed for function ptr")
+ }
+ PatioDataLayout::PatioDataLayoutInt(_) => panic!("offset not allowed for int"),
+ PatioDataLayout::PatioDataLayoutInt32(_) => panic!("offset not allowed for int32"),
+
+ PatioDataLayout::PatioDataLayoutStruct(layout_struct) => {
+ for element in layout_struct
+ .elements
+ .iter()
+ .take((*element_offset).try_into().unwrap())
+ {
byte_offset += data_layout_byte_size(element, target_triple);
}
- current_element = &elements[usize::try_from(*element_offset).unwrap()];
+ current_element =
+ &layout_struct.elements[usize::try_from(*element_offset).unwrap()];
}
}
}
@@ -170,9 +202,12 @@ pub(crate) fn data_layout_byte_offset(
mod data_layout_byte_offset_test {
use std::str::FromStr;
- use crate::patio::types::PatioDataLayout;
+ use crate::patio::types::{
+ PatioDataLayout, PatioDataLayoutArray, PatioDataLayoutByte, PatioDataLayoutDataPtr,
+ PatioDataLayoutInt32, PatioDataLayoutStruct,
+ };
- fn data_layout_byte_offset(layout: &PatioDataLayout, element_offsets: Vec<u32>) -> u32 {
+ fn data_layout_byte_offset(layout: &PatioDataLayout, element_offsets: Vec<i32>) -> u32 {
super::data_layout_byte_offset(
layout,
&element_offsets,
@@ -182,7 +217,11 @@ mod data_layout_byte_offset_test {
#[test]
fn byte_offset_of_first_element_of_array_is_zero() {
- let layout = PatioDataLayout::array(PatioDataLayout::Int32, 2);
+ let layout = PatioDataLayoutArray {
+ element: PatioDataLayoutInt32.into(),
+ size: 2,
+ }
+ .into();
let byte_offset = data_layout_byte_offset(&layout, vec![0]);
@@ -191,7 +230,11 @@ mod data_layout_byte_offset_test {
#[test]
fn byte_offset_of_element_of_array_is_size_of_skipped_elements() {
- let layout = PatioDataLayout::array(PatioDataLayout::Int32, 5);
+ let layout = PatioDataLayoutArray {
+ element: PatioDataLayoutInt32.into(),
+ size: 5,
+ }
+ .into();
let byte_offset = data_layout_byte_offset(&layout, vec![2]);
@@ -200,7 +243,15 @@ mod data_layout_byte_offset_test {
#[test]
fn byte_offset_of_element_of_element_of_array_is_size_of_skipped_elements() {
- let layout = PatioDataLayout::array(PatioDataLayout::array(PatioDataLayout::Byte, 7), 5);
+ let layout = PatioDataLayoutArray {
+ element: PatioDataLayoutArray {
+ element: PatioDataLayoutByte.into(),
+ size: 7,
+ }
+ .into(),
+ size: 5,
+ }
+ .into();
let byte_offset = data_layout_byte_offset(&layout, vec![2, 3]);
@@ -209,11 +260,14 @@ mod data_layout_byte_offset_test {
#[test]
fn byte_offset_of_first_element_of_struct_is_zero() {
- let layout = PatioDataLayout::struct_(vec![
- PatioDataLayout::Int32,
- PatioDataLayout::Byte,
- PatioDataLayout::DataPtr,
- ]);
+ let layout = PatioDataLayoutStruct {
+ elements: vec![
+ PatioDataLayoutInt32.into(),
+ PatioDataLayoutByte.into(),
+ PatioDataLayoutDataPtr.into(),
+ ],
+ }
+ .into();
let byte_offset = data_layout_byte_offset(&layout, vec![0]);
@@ -222,11 +276,14 @@ mod data_layout_byte_offset_test {
#[test]
fn byte_offset_of_element_of_struct_is_size_of_skipped_elements() {
- let layout = PatioDataLayout::struct_(vec![
- PatioDataLayout::Int32,
- PatioDataLayout::Byte,
- PatioDataLayout::DataPtr,
- ]);
+ let layout = PatioDataLayoutStruct {
+ elements: vec![
+ PatioDataLayoutInt32.into(),
+ PatioDataLayoutByte.into(),
+ PatioDataLayoutDataPtr.into(),
+ ],
+ }
+ .into();
let byte_offset = data_layout_byte_offset(&layout, vec![2]);
@@ -235,15 +292,21 @@ mod data_layout_byte_offset_test {
#[test]
fn byte_offset_of_element_of_element_of_struct_is_size_of_skipped_elements() {
- let layout = PatioDataLayout::struct_(vec![
- PatioDataLayout::Int32,
- PatioDataLayout::struct_(vec![
- PatioDataLayout::Byte,
- PatioDataLayout::DataPtr,
- PatioDataLayout::Byte,
- ]),
- PatioDataLayout::Int32,
- ]);
+ let layout = PatioDataLayoutStruct {
+ elements: vec![
+ PatioDataLayoutInt32.into(),
+ PatioDataLayoutStruct {
+ elements: vec![
+ PatioDataLayoutByte.into(),
+ PatioDataLayoutDataPtr.into(),
+ PatioDataLayoutByte.into(),
+ ],
+ }
+ .into(),
+ PatioDataLayoutInt32.into(),
+ ],
+ }
+ .into();
let byte_offset = data_layout_byte_offset(&layout, vec![1, 2]);
@@ -253,25 +316,28 @@ mod data_layout_byte_offset_test {
pub(crate) fn data_layout_element_at<'a>(
layout: &'a PatioDataLayout,
- element_offsets: &[u32],
+ element_offsets: &[i32],
) -> &'a PatioDataLayout {
let mut current_element = layout;
for element_offset in element_offsets {
match current_element {
- PatioDataLayout::Array { element, size: _ } => {
- current_element = element;
+ PatioDataLayout::PatioDataLayoutArray(array) => {
+ current_element = &array.element;
}
- PatioDataLayout::Bool => panic!("offset not allowed for bool"),
- PatioDataLayout::Byte => panic!("offset not allowed for byte"),
- PatioDataLayout::DataPtr => panic!("offset not allowed for data ptr"),
- PatioDataLayout::FunctionPtr => panic!("offset not allowed for function ptr"),
- PatioDataLayout::Int => panic!("offset not allowed for int"),
- PatioDataLayout::Int32 => panic!("offset not allowed for int32"),
+ PatioDataLayout::PatioDataLayoutBool(_) => panic!("offset not allowed for bool"),
+ PatioDataLayout::PatioDataLayoutByte(_) => panic!("offset not allowed for byte"),
+ PatioDataLayout::PatioDataLayoutDataPtr(_) => panic!("offset not allowed for data ptr"),
+ PatioDataLayout::PatioDataLayoutFunctionPtr(_) => {
+ panic!("offset not allowed for function ptr")
+ }
+ PatioDataLayout::PatioDataLayoutInt(_) => panic!("offset not allowed for int"),
+ PatioDataLayout::PatioDataLayoutInt32(_) => panic!("offset not allowed for int32"),
- PatioDataLayout::Struct { elements } => {
- current_element = &elements[usize::try_from(*element_offset).unwrap()];
+ PatioDataLayout::PatioDataLayoutStruct(layout_struct) => {
+ current_element =
+ &layout_struct.elements[usize::try_from(*element_offset).unwrap()];
}
}
}
@@ -281,86 +347,113 @@ pub(crate) fn data_layout_element_at<'a>(
#[cfg(test)]
mod data_layout_element_at_test {
- use crate::patio::types::PatioDataLayout;
+ use crate::patio::types::{
+ PatioDataLayout, PatioDataLayoutArray, PatioDataLayoutByte, PatioDataLayoutDataPtr,
+ PatioDataLayoutInt32, PatioDataLayoutStruct,
+ };
fn data_layout_element_at(
layout: &PatioDataLayout,
- element_offsets: Vec<u32>,
+ element_offsets: Vec<i32>,
) -> &PatioDataLayout {
super::data_layout_element_at(layout, &element_offsets)
}
#[test]
fn element_of_array_is_element_layout() {
- let layout = PatioDataLayout::array(PatioDataLayout::Int32, 2);
+ let layout = PatioDataLayoutArray {
+ element: PatioDataLayoutInt32.into(),
+ size: 2,
+ }
+ .into();
let element = data_layout_element_at(&layout, vec![0]);
- assert_eq!(element, &PatioDataLayout::Int32);
+ assert_eq!(element, &PatioDataLayoutInt32.into());
}
#[test]
fn element_of_element_of_array() {
- let layout = PatioDataLayout::array(PatioDataLayout::array(PatioDataLayout::Byte, 7), 5);
+ let layout = PatioDataLayoutArray {
+ element: PatioDataLayoutArray {
+ element: PatioDataLayoutByte.into(),
+ size: 7,
+ }
+ .into(),
+ size: 5,
+ }
+ .into();
let element = data_layout_element_at(&layout, vec![2, 3]);
- assert_eq!(element, &PatioDataLayout::Byte);
+ assert_eq!(element, &PatioDataLayoutByte.into());
}
#[test]
fn first_element_of_struct() {
- let layout = PatioDataLayout::struct_(vec![
- PatioDataLayout::Int32,
- PatioDataLayout::Byte,
- PatioDataLayout::DataPtr,
- ]);
+ let layout = PatioDataLayoutStruct {
+ elements: vec![
+ PatioDataLayoutInt32.into(),
+ PatioDataLayoutByte.into(),
+ PatioDataLayoutDataPtr.into(),
+ ],
+ }
+ .into();
let element = data_layout_element_at(&layout, vec![0]);
- assert_eq!(element, &PatioDataLayout::Int32);
+ assert_eq!(element, &PatioDataLayoutInt32.into());
}
#[test]
fn non_first_element_of_struct() {
- let layout = PatioDataLayout::struct_(vec![
- PatioDataLayout::Int32,
- PatioDataLayout::Byte,
- PatioDataLayout::DataPtr,
- ]);
+ let layout = PatioDataLayoutStruct {
+ elements: vec![
+ PatioDataLayoutInt32.into(),
+ PatioDataLayoutByte.into(),
+ PatioDataLayoutDataPtr.into(),
+ ],
+ }
+ .into();
let element = data_layout_element_at(&layout, vec![2]);
- assert_eq!(element, &PatioDataLayout::DataPtr);
+ assert_eq!(element, &PatioDataLayoutDataPtr.into());
}
#[test]
fn element_of_element_of_struct() {
- let layout = PatioDataLayout::struct_(vec![
- PatioDataLayout::Int32,
- PatioDataLayout::struct_(vec![
- PatioDataLayout::Byte,
- PatioDataLayout::DataPtr,
- PatioDataLayout::Byte,
- ]),
- PatioDataLayout::Int32,
- ]);
+ let layout = PatioDataLayoutStruct {
+ elements: vec![
+ PatioDataLayoutInt32.into(),
+ PatioDataLayoutStruct {
+ elements: vec![
+ PatioDataLayoutByte.into(),
+ PatioDataLayoutDataPtr.into(),
+ PatioDataLayoutByte.into(),
+ ],
+ }
+ .into(),
+ PatioDataLayoutInt32.into(),
+ ],
+ }
+ .into();
let element = data_layout_element_at(&layout, vec![1, 2]);
- assert_eq!(element, &PatioDataLayout::Byte);
+ assert_eq!(element, &PatioDataLayoutByte.into());
}
}
pub(crate) fn data_layout_to_type(layout: &PatioDataLayout) -> PatioType {
match layout {
- PatioDataLayout::Array { .. } => panic!("array cannot be represented as type"),
- PatioDataLayout::Bool => PatioType::Bool,
- PatioDataLayout::Byte => PatioType::Byte,
- PatioDataLayout::DataPtr => PatioType::DataPtr,
- PatioDataLayout::FunctionPtr => PatioType::FunctionPtr,
- PatioDataLayout::Int => PatioType::Int,
- PatioDataLayout::Int32 => PatioType::Int32,
- PatioDataLayout::Struct { .. } => panic!("struct cannot be represented as type"),
+ PatioDataLayout::PatioDataLayoutArray(_) => panic!("array cannot be represented as type"),
+ PatioDataLayout::PatioDataLayoutBool(_) => PatioBoolType.into(),
+ PatioDataLayout::PatioDataLayoutByte(_) => PatioByteType.into(),
+ PatioDataLayout::PatioDataLayoutDataPtr(_) => PatioDataPtrType.into(),
+ PatioDataLayout::PatioDataLayoutFunctionPtr(_) => PatioFunctionPtrType.into(),
+ PatioDataLayout::PatioDataLayoutInt(_) => PatioIntType.into(),
+ PatioDataLayout::PatioDataLayoutInt32(_) => PatioInt32Type.into(),
+ PatioDataLayout::PatioDataLayoutStruct(_) => panic!("struct cannot be represented as type"),
}
}