diff --git a/xlsynth/src/ir_package.rs b/xlsynth/src/ir_package.rs index 9665de34..9ab60bb0 100644 --- a/xlsynth/src/ir_package.rs +++ b/xlsynth/src/ir_package.rs @@ -10,8 +10,8 @@ use crate::{ lib_support::{ xls_function_get_name, xls_function_get_type, xls_function_type_to_string, xls_interpret_function, xls_package_free, xls_package_get_function, - xls_package_get_type_for_value, xls_package_to_string, xls_parse_ir_package, - xls_type_to_string, + xls_package_get_functions, xls_package_get_type_for_value, xls_package_to_string, + xls_parse_ir_package, xls_type_to_string, }, IrValue, }; @@ -122,6 +122,14 @@ impl IrPackage { self.with_read(|guard| xls_package_get_function(&self.ptr, guard, name)) } + /// Returns all functions contained in this package. + /// + /// The returned `IrFunction` values borrow the package; they remain valid + /// for as long as the package is alive. + pub fn get_functions(&self) -> Result, XlsynthError> { + self.with_read(|guard| xls_package_get_functions(&self.ptr, guard)) + } + pub fn get_type_for_value(&self, value: &IrValue) -> Result { self.with_write(|guard| xls_package_get_type_for_value(guard.mut_c_ptr(), value.ptr)) } @@ -351,6 +359,30 @@ mod tests { package.verify().expect("verify success"); } + #[test] + fn test_ir_package_get_functions() { + let ir = r#" +package test + +fn foo() -> bits[32] { + ret literal.1: bits[32] = literal(value=7) +} + +fn bar(x: bits[32]) -> bits[32] { + ret x: bits[32] = param(name=x, id=1) +} +"#; + let package = IrPackage::parse_ir(ir, None).expect("parse success"); + let mut names: Vec = package + .get_functions() + .expect("get functions") + .iter() + .map(|f| f.get_name()) + .collect(); + names.sort(); + assert_eq!(names, vec!["bar".to_string(), "foo".to_string()]); + } + #[test] fn test_ir_package_verify_fails_when_builder_skips_checks() { let mut package = IrPackage::new("test_package").unwrap(); diff --git a/xlsynth/src/lib_support.rs b/xlsynth/src/lib_support.rs index 021fe887..7bd00876 100644 --- a/xlsynth/src/lib_support.rs +++ b/xlsynth/src/lib_support.rs @@ -12,6 +12,7 @@ use std::{ sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}, }; +use libc::size_t; use xlsynth_sys::{ CIrBValue, CIrBits, CIrFunction, CIrFunctionJit, CIrFunctionType, CIrPackage, CIrType, CIrValue, CScheduleAndCodegenResult, CTraceMessage, XlsFormatPreference, @@ -565,6 +566,41 @@ pub(crate) fn xls_package_get_function( }) } +pub(crate) fn xls_package_get_functions( + package: &Arc>, + guard: RwLockReadGuard, +) -> Result, XlsynthError> { + let mut error_out: *mut std::os::raw::c_char = std::ptr::null_mut(); + let mut result_out: *mut *mut CIrFunction = std::ptr::null_mut(); + let mut count_out: size_t = 0; + let success = unsafe { + xlsynth_sys::xls_package_get_functions( + guard.const_c_ptr() as *mut CIrPackage, + &mut error_out, + &mut result_out, + &mut count_out, + ) + }; + if !success { + return Err(XlsynthError(unsafe { c_str_to_rust(error_out) })); + } + + let function_ptrs = unsafe { std::slice::from_raw_parts(result_out, count_out) }; + let functions = function_ptrs + .iter() + .map(|ptr| crate::ir_package::IrFunction { + parent: package.clone(), + ptr: *ptr, + }) + .collect(); + + unsafe { + xlsynth_sys::xls_function_ptr_array_free(result_out); + } + + Ok(functions) +} + pub(crate) fn xls_function_get_type( _package_write_guard: &RwLockWriteGuard, function: *const CIrFunction,