From 996bf147d22911cffdba670159933d93b96b9990 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sat, 4 Apr 2026 09:21:03 +0100 Subject: Add rust-native PatioIntValue --- patio-to-cranelift/src/lib.rs | 63 +++++++++++------------------ patio-to-cranelift/src/patio/flatbuffers.rs | 37 ++++++++++++++++- patio-to-cranelift/src/patio/mod.rs | 1 + patio-to-cranelift/src/patio/values.rs | 14 +++++++ 4 files changed, 74 insertions(+), 41 deletions(-) create mode 100644 patio-to-cranelift/src/patio/values.rs diff --git a/patio-to-cranelift/src/lib.rs b/patio-to-cranelift/src/lib.rs index dfe30c9c..a9e9de51 100644 --- a/patio-to-cranelift/src/lib.rs +++ b/patio-to-cranelift/src/lib.rs @@ -8,14 +8,14 @@ use crate::{ patio::{ compilation_unit::{PatioLocal, PatioLocalType}, types::{PatioDataLayout, PatioType}, + values::PatioIntValue, }, patio_generated::patio::{ PatioBlock, PatioBoolToInt, PatioCall, PatioCompilationUnitElement, PatioCompilationUnitElementValue, PatioFunctionDefinition, PatioIf, PatioInstruction, PatioInstructionValue, PatioIntAdd, PatioIntEquals, PatioIntNotEqual, PatioIntSub, - PatioIntToBool, PatioIntValue, PatioIntValueValue, PatioLocalRef, PatioLocalStore, - PatioOperand, PatioOperandValue, PatioResume, PatioReturn, PatioReturnVoid, PatioVarLoad, - PatioVarStore, PatioVisibility, + PatioIntToBool, PatioLocalRef, PatioLocalStore, PatioOperand, PatioOperandValue, + PatioResume, PatioReturn, PatioReturnVoid, PatioVarLoad, PatioVarStore, PatioVisibility, }, }; @@ -501,12 +501,12 @@ fn compile_operand( PatioOperandValue::PatioIntConst => { let int_const = operand.value_as_patio_int_const().unwrap(); let cranelift_int_type = cranelift_int_type(&context.target_triple); - compile_int_value(int_const.value(), cranelift_int_type, context) + compile_int_value(&int_const.value().into(), cranelift_int_type, context) } PatioOperandValue::PatioInt32Const => { let int_32_const = operand.value_as_patio_int_32_const().unwrap(); - compile_int_value(int_32_const.value(), CRANELIFT_INT_32_TYPE, context) + compile_int_value(&int_32_const.value().into(), CRANELIFT_INT_32_TYPE, context) } PatioOperandValue::PatioLocalRef => { @@ -526,16 +526,13 @@ fn compile_operand( } fn compile_int_value( - int_value: PatioIntValue<'_>, + int_value: &PatioIntValue, cranelift_type: cranelift::prelude::Type, context: &mut CompilerFunctionContext<'_>, ) -> cranelift::prelude::Value { - match int_value.value_type() { - PatioIntValueValue::PatioIntValueByteSizeOf => { - let byte_size_of = int_value.value_as_patio_int_value_byte_size_of().unwrap(); - - let byte_size_of = - data_layout_byte_size(&byte_size_of.layout().into(), &context.target_triple); + match int_value { + PatioIntValue::ByteSizeOf { layout } => { + let byte_size_of = data_layout_byte_size(&layout, &context.target_triple); context .function_builder @@ -543,14 +540,12 @@ fn compile_int_value( .iconst(cranelift_type, i64::from(byte_size_of)) } - PatioIntValueValue::PatioIntValueByteOffsetOf => { - let byte_offset_of = int_value.value_as_patio_int_value_byte_offset_of().unwrap(); - - let byte_offset_of = data_layout_byte_offset( - &byte_offset_of.layout().into(), - byte_offset_of.offset().iter().collect(), - &context.target_triple, - ); + PatioIntValue::ByteOffsetOf { + layout, + element_offsets, + } => { + let byte_offset_of = + data_layout_byte_offset(&layout, &element_offsets, &context.target_triple); context .function_builder @@ -558,22 +553,10 @@ fn compile_int_value( .iconst(cranelift_type, i64::from(byte_offset_of)) } - PatioIntValueValue::PatioIntValueLiteral => { - let literal = int_value.value_as_patio_int_value_literal().unwrap(); - - context - .function_builder - .ins() - .iconst(cranelift_type, i64::from(literal.value())) - } - - int_value_type => { - todo!( - "Unhandled int value type: {:?} {}", - int_value_type.variant_name(), - int_value_type.0 - ) - } + PatioIntValue::Literal { value } => context + .function_builder + .ins() + .iconst(cranelift_type, i64::from(*value)), } } @@ -759,7 +742,7 @@ mod data_layout_byte_size_test { fn data_layout_byte_offset( layout: &PatioDataLayout, - element_offsets: Vec, + element_offsets: &[u32], target_triple: &target_lexicon::Triple, ) -> u32 { let mut byte_offset = 0; @@ -780,11 +763,11 @@ fn data_layout_byte_offset( PatioDataLayout::Int32 => panic!("offset not allowed for int32"), PatioDataLayout::Struct { elements } => { - for element in elements.iter().take(element_offset.try_into().unwrap()) { + for element in 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 = &elements[usize::try_from(*element_offset).unwrap()]; } } } @@ -801,7 +784,7 @@ mod data_layout_byte_offset_test { fn data_layout_byte_offset(layout: &PatioDataLayout, element_offsets: Vec) -> u32 { super::data_layout_byte_offset( layout, - element_offsets, + &element_offsets, &target_lexicon::Triple::from_str("x86_64-unknown-linux-gnu").unwrap(), ) } diff --git a/patio-to-cranelift/src/patio/flatbuffers.rs b/patio-to-cranelift/src/patio/flatbuffers.rs index cb99ec71..8b939bbf 100644 --- a/patio-to-cranelift/src/patio/flatbuffers.rs +++ b/patio-to-cranelift/src/patio/flatbuffers.rs @@ -2,10 +2,11 @@ use crate::{ patio::{ compilation_unit::{PatioLocal, PatioLocalType}, types::{PatioDataLayout, PatioType}, + values::PatioIntValue, }, patio_generated::{ self, - patio::{PatioDataLayoutValue, PatioTypeValue}, + patio::{PatioDataLayoutValue, PatioIntValueValue, PatioTypeValue}, }, }; @@ -98,3 +99,37 @@ impl From for PatioLocalType { } } } + +impl From> for PatioIntValue { + fn from(value: patio_generated::patio::PatioIntValue<'_>) -> Self { + match value.value_type() { + PatioIntValueValue::PatioIntValueByteOffsetOf => { + let byte_offset_of = value.value_as_patio_int_value_byte_offset_of().unwrap(); + Self::ByteOffsetOf { + layout: byte_offset_of.layout().into(), + element_offsets: byte_offset_of.offset().iter().collect(), + } + } + + PatioIntValueValue::PatioIntValueByteSizeOf => { + let byte_size_of = value.value_as_patio_int_value_byte_size_of().unwrap(); + Self::ByteSizeOf { + layout: byte_size_of.layout().into(), + } + } + + PatioIntValueValue::PatioIntValueLiteral => { + let literal = value.value_as_patio_int_value_literal().unwrap(); + Self::Literal { + value: literal.value(), + } + } + + int_value_type => todo!( + "Unhandled int value type: {:?} {}", + int_value_type.variant_name(), + int_value_type.0 + ), + } + } +} diff --git a/patio-to-cranelift/src/patio/mod.rs b/patio-to-cranelift/src/patio/mod.rs index 2975a23f..fe44e3de 100644 --- a/patio-to-cranelift/src/patio/mod.rs +++ b/patio-to-cranelift/src/patio/mod.rs @@ -1,3 +1,4 @@ pub(crate) mod compilation_unit; pub(crate) mod flatbuffers; pub(crate) mod types; +pub(crate) mod values; diff --git a/patio-to-cranelift/src/patio/values.rs b/patio-to-cranelift/src/patio/values.rs new file mode 100644 index 00000000..18e5b50f --- /dev/null +++ b/patio-to-cranelift/src/patio/values.rs @@ -0,0 +1,14 @@ +use crate::patio::types::PatioDataLayout; + +pub(crate) enum PatioIntValue { + ByteOffsetOf { + layout: PatioDataLayout, + element_offsets: Vec, + }, + ByteSizeOf { + layout: PatioDataLayout, + }, + Literal { + value: i32, + }, +} -- cgit v1.2.3