aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-04-05 22:32:00 +0100
committerMichael Williamson <mike@zwobble.org>2026-04-05 22:32:00 +0100
commit6fc24f5205f2419f10a1729a749b4335332ecf79 (patch)
tree94047ba795220e3f05d22d9dfefdff049c02d539
parent7524f1a92aff4ec669be9b81ad390878d1dff0aa (diff)
Write null data pointers as data value
-rw-r--r--patio-to-cranelift/src/codegen/values.rs66
1 files changed, 47 insertions, 19 deletions
diff --git a/patio-to-cranelift/src/codegen/values.rs b/patio-to-cranelift/src/codegen/values.rs
index 32f1c70a..229dbc6f 100644
--- a/patio-to-cranelift/src/codegen/values.rs
+++ b/patio-to-cranelift/src/codegen/values.rs
@@ -1,6 +1,6 @@
use crate::{
codegen::types,
- patio::values::{PatioDataValue, PatioIntValue},
+ patio::values::{PatioDataPtrValue, PatioDataValue, PatioIntValue},
};
pub(crate) fn data_value_to_bytes(
@@ -37,25 +37,15 @@ fn write_data_value(
PatioDataValue::Byte(value) => bytes.push(*value),
- PatioDataValue::DataPtr(_) => todo!(),
+ PatioDataValue::DataPtr(PatioDataPtrValue::DataElement { name: _ }) => todo!(),
+
+ PatioDataValue::DataPtr(PatioDataPtrValue::Null) => {
+ write_patio_int(0, bytes, target_triple);
+ }
PatioDataValue::Int(int_value) => {
let value = eval_int_value(int_value, target_triple);
-
- match target_triple.pointer_width() {
- Ok(target_lexicon::PointerWidth::U16) => {
- panic!("unsupported pointer width: 16 bits")
- }
- Ok(target_lexicon::PointerWidth::U32) => {
- let value_at_width: i32 = value;
- bytes.extend_from_slice(&value_at_width.to_le_bytes());
- }
- Ok(target_lexicon::PointerWidth::U64) => {
- let value_at_width: i64 = value.into();
- bytes.extend_from_slice(&value_at_width.to_le_bytes());
- }
- Err(()) => panic!("pointer width unknown"),
- }
+ write_patio_int(value, bytes, target_triple);
}
PatioDataValue::Int32(int_value) => {
@@ -71,6 +61,23 @@ fn write_data_value(
}
}
+fn write_patio_int(value: i32, bytes: &mut Vec<u8>, target_triple: &target_lexicon::Triple) {
+ match target_triple.pointer_width() {
+ Ok(target_lexicon::PointerWidth::U16) => {
+ panic!("unsupported pointer width: 16 bits")
+ }
+ Ok(target_lexicon::PointerWidth::U32) => {
+ let value_at_width: i32 = value;
+ bytes.extend_from_slice(&value_at_width.to_le_bytes());
+ }
+ Ok(target_lexicon::PointerWidth::U64) => {
+ let value_at_width: i64 = value.into();
+ bytes.extend_from_slice(&value_at_width.to_le_bytes());
+ }
+ Err(()) => panic!("pointer width unknown"),
+ }
+}
+
pub(crate) fn eval_int_value(value: &PatioIntValue, target_triple: &target_lexicon::Triple) -> i32 {
match value {
PatioIntValue::ByteOffsetOf {
@@ -94,7 +101,7 @@ mod data_value_to_bytes_test {
use crate::patio::{
types::PatioDataLayout,
- values::{PatioDataValue, PatioIntValue},
+ values::{PatioDataPtrValue, PatioDataValue, PatioIntValue},
};
fn data_value_to_bytes(data_value: PatioDataValue) -> Box<[u8]> {
@@ -150,10 +157,31 @@ mod data_value_to_bytes_test {
}
#[test]
+ fn given_pointer_is_64_bits_wide_then_null_data_ptr_is_written_as_64_bit_0() {
+ let target_triple = target_lexicon::Triple::from_str("x86_64-unknown-linux-gnu").unwrap();
+ let data_value = PatioDataValue::DataPtr(PatioDataPtrValue::Null);
+
+ let bytes = super::data_value_to_bytes(&data_value, &target_triple);
+
+ assert_eq!(bytes.as_ref(), &[0, 0, 0, 0, 0, 0, 0, 0]);
+ }
+
+ #[test]
+ fn given_pointer_is_32_bits_wide_then_null_data_ptr_is_written_as_32_bit_0() {
+ let target_triple = target_lexicon::Triple::from_str("i686-unknown-linux-gnu").unwrap();
+ let data_value = PatioDataValue::DataPtr(PatioDataPtrValue::Null);
+
+ let bytes = super::data_value_to_bytes(&data_value, &target_triple);
+
+ assert_eq!(bytes.as_ref(), &[0, 0, 0, 0]);
+ }
+
+ #[test]
fn given_pointer_is_64_bits_wide_then_int_is_written_with_pointer_width() {
+ let target_triple = target_lexicon::Triple::from_str("x86_64-unknown-linux-gnu").unwrap();
let data_value = PatioDataValue::Int(PatioIntValue::Literal { value: 0x12345678 });
- let bytes = data_value_to_bytes(data_value);
+ let bytes = super::data_value_to_bytes(&data_value, &target_triple);
assert_eq!(bytes.as_ref(), &[0x78, 0x56, 0x34, 0x12, 0, 0, 0, 0]);
}