From e2ffa5726b6eda3e41980515acf43b5ceaaea697 Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Thu, 19 Mar 2020 21:21:38 +0100 Subject: [PATCH 01/12] feat: implemented static TypeInfo generation at runtime --- crates/mun_runtime/Cargo.toml | 1 + crates/mun_runtime/src/function.rs | 71 ++------ crates/mun_runtime/src/lib.rs | 6 + crates/mun_runtime/src/type_info.rs | 256 ++++++++++++++++++++-------- 4 files changed, 212 insertions(+), 122 deletions(-) diff --git a/crates/mun_runtime/Cargo.toml b/crates/mun_runtime/Cargo.toml index 1fadb6300..d275bde2e 100644 --- a/crates/mun_runtime/Cargo.toml +++ b/crates/mun_runtime/Cargo.toml @@ -17,6 +17,7 @@ notify = "4.0.12" parking_lot = "0.9" tempfile = "3" once_cell = "1.3.1" +generic_static = "0.1" [dev-dependencies] mun_compiler = { path="../mun_compiler" } diff --git a/crates/mun_runtime/src/function.rs b/crates/mun_runtime/src/function.rs index bd3e9b327..39e25fd1f 100644 --- a/crates/mun_runtime/src/function.rs +++ b/crates/mun_runtime/src/function.rs @@ -1,71 +1,33 @@ use std::ffi::CString; use std::ptr; -use crate::ReturnTypeReflection; -use abi::{FunctionInfo, FunctionSignature, Guid, Privacy, TypeGroup, TypeInfo}; +use crate::type_info::HasStaticTypeInfo; pub struct FunctionInfoStorage { _name: CString, - _type_names: Vec, - - // Clippy warns: `Vec` is already on the heap, the boxing is unnecessary. - // However, in this case we explicitly want to have a Vec of pointers. - #[allow(clippy::vec_box)] - _type_infos: Vec>, + _type_infos: Vec<&'static abi::TypeInfo>, } impl FunctionInfoStorage { pub fn new_function( name: &str, - args: &[String], - ret: Option, - privacy: Privacy, + args: &[&'static abi::TypeInfo], + ret: Option<&'static abi::TypeInfo>, + privacy: abi::Privacy, fn_ptr: *const std::ffi::c_void, - ) -> (FunctionInfo, FunctionInfoStorage) { + ) -> (abi::FunctionInfo, FunctionInfoStorage) { let name = CString::new(name).unwrap(); - let (mut type_names, mut type_infos): (Vec, Vec>) = args - .iter() - .cloned() - .map(|name| { - let name = CString::new(name).unwrap(); - let type_info = Box::new(TypeInfo { - guid: Guid { - b: md5::compute(name.as_bytes()).0, - }, - name: name.as_ptr(), - group: TypeGroup::FundamentalTypes, - }); - (name, type_info) - }) - .unzip(); - - let ret = ret.map(|name| { - let name = CString::new(name).unwrap(); - let type_info = Box::new(TypeInfo { - guid: Guid { - b: md5::compute(name.as_bytes()).0, - }, - name: name.as_ptr(), - group: TypeGroup::FundamentalTypes, - }); - (name, type_info) - }); + let type_infos: Vec<&'static abi::TypeInfo> = args.iter().copied().collect(); let num_arg_types = type_infos.len() as u16; - let return_type = if let Some((type_name, type_info)) = ret { - type_names.push(type_name); - - let ptr = Box::into_raw(type_info); - let type_info = unsafe { Box::from_raw(ptr) }; - type_infos.push(type_info); - - ptr + let return_type = if let Some(ty) = ret { + ty as *const _ } else { ptr::null() }; - let fn_info = FunctionInfo { - signature: FunctionSignature { + let fn_info = abi::FunctionInfo { + signature: abi::FunctionSignature { name: name.as_ptr(), arg_types: type_infos.as_ptr() as *const *const _, return_type, @@ -77,7 +39,6 @@ impl FunctionInfoStorage { let fn_storage = FunctionInfoStorage { _name: name, - _type_names: type_names, _type_infos: type_infos, }; @@ -90,7 +51,7 @@ pub trait IntoFunctionInfo { self, name: S, privacy: abi::Privacy, - ) -> (FunctionInfo, FunctionInfoStorage); + ) -> (abi::FunctionInfo, FunctionInfoStorage); } macro_rules! into_function_info_impl { @@ -98,14 +59,14 @@ macro_rules! into_function_info_impl { extern "C" fn($($T:ident),*) -> $R:ident; )+) => { $( - impl<$R: ReturnTypeReflection, $($T: ReturnTypeReflection,)*> IntoFunctionInfo + impl<$R: HasStaticTypeInfo, $($T: HasStaticTypeInfo,)*> IntoFunctionInfo for extern "C" fn($($T),*) -> $R { - fn into>(self, name: S, privacy: Privacy) -> (FunctionInfo, FunctionInfoStorage) { + fn into>(self, name: S, privacy: abi::Privacy) -> (abi::FunctionInfo, FunctionInfoStorage) { FunctionInfoStorage::new_function( name.as_ref(), - &[$($T::type_name().to_string(),)*], - Some($R::type_name().to_string()), + &[$($T::type_info(),)*], + Some($R::type_info()), privacy, self as *const std::ffi::c_void, ) diff --git a/crates/mun_runtime/src/lib.rs b/crates/mun_runtime/src/lib.rs index 19c7ea85c..92cec950a 100644 --- a/crates/mun_runtime/src/lib.rs +++ b/crates/mun_runtime/src/lib.rs @@ -12,6 +12,8 @@ mod allocator; mod marshal; mod reflection; mod r#struct; + +#[macro_use] mod type_info; #[cfg(test)] @@ -38,6 +40,10 @@ use crate::function::IntoFunctionInfo; pub use crate::r#struct::StructRef; use std::sync::Arc; +impl_has_type_info_name!( + abi::TypeInfo => "TypeInfo" +); + /// Options for the construction of a [`Runtime`]. pub struct RuntimeOptions { /// Path to the entry point library diff --git a/crates/mun_runtime/src/type_info.rs b/crates/mun_runtime/src/type_info.rs index 05f035d84..d8145b85b 100644 --- a/crates/mun_runtime/src/type_info.rs +++ b/crates/mun_runtime/src/type_info.rs @@ -1,67 +1,189 @@ -// use once_cell::unsync::OnceCell; -// use std::ffi::{CStr, CString}; -// -// /// A trait that defines that for a type we can statically return a abi::TypeInfo -// trait HasStaticTypeInfo { -// /// Returns a reference to the TypeInfo for the type -// fn type_info() -> &'static abi::TypeInfo; -// } -// -// /// A trait that defines that for a type we can statically return the name that would be used in a -// /// abi::TypeInfo. This is useful for opaque types that we do not know the full details of but we -// /// could use it as a pointer type -// trait HasStaticTypeInfoName { -// /// Returns the type info name for the type -// fn type_name() -> &'static CStr; -// -// /// Retrieves the type's `Guid`. -// fn type_guid() -> abi::Guid { -// abi::Guid { -// b: md5::compute(Self::type_name()).0, -// } -// } -// } -// -// /// Implement HasStaticTypeInfoName for everything that can produce a type info. -// impl HasStaticTypeInfoName for T { -// fn type_name() -> &'static CStr { -// unsafe { CStr::from_ptr(Self::type_info().name) } -// } -// } -// -// /// Every type that has at least a type name also has a valid pointer type name -// impl HasStaticTypeInfo for *const T { -// fn type_info() -> &'static abi::TypeInfo { -// let type_info: OnceCell = OnceCell::new(); -// type_info.get_or_init(|| { -// static TYPE_INFO_NAME: OnceCell = OnceCell::new(); -// let type_info_name: &'static CString = TYPE_INFO_NAME -// .get_or_init(|| CString::new(format!("*const {}", T::type_name().to_str().unwrap())).unwrap()); -// -// abi::TypeInfo { -// guid: abi::Guid{ b: md5::compute(&type_info_name.into_bytes()).0 }, -// name: type_info_name.as_ptr(), -// group: abi::TypeGroup::FundamentalTypes -// } -// }) -// } -// } -// -// /// Every type that has at least a type name also has a valid pointer type name -// impl HasStaticTypeInfo for *mut T { -// fn type_info() -> &'static abi::TypeInfo { -// let type_info: OnceCell = OnceCell::new(); -// type_info.get_or_init(|| { -// static TYPE_INFO_NAME: OnceCell = OnceCell::new(); -// let type_info_name: &'static CString = TYPE_INFO_NAME -// .get_or_init(|| CString::new(format!("*const {}", T::type_name().to_str().unwrap())).unwrap()); -// -// abi::TypeInfo { -// guid: abi::Guid{ b: md5::compute(&type_info_name.into_bytes()).0 }, -// name: type_info_name.as_ptr(), -// group: abi::TypeGroup::FundamentalTypes -// } -// }) -// } -// } -// +use generic_static::StaticTypeMap; +use once_cell::sync::OnceCell; +use std::ffi::{CStr, CString}; +use std::sync::Once; + +/// A trait that defines that for a type we can statically return a abi::TypeInfo +pub trait HasStaticTypeInfo { + /// Returns a reference to the TypeInfo for the type + fn type_info() -> &'static abi::TypeInfo; +} + +/// A trait that defines that for a type we can statically return the name that would be used in a +/// abi::TypeInfo. This is useful for opaque types that we do not know the full details of but we +/// could use it as a pointer type +pub trait HasStaticTypeInfoName { + /// Returns the type info name for the type + fn type_name() -> &'static CStr; +} + +/// Implement HasStaticTypeInfoName for everything that can produce a type info. +impl HasStaticTypeInfoName for T { + fn type_name() -> &'static CStr { + unsafe { CStr::from_ptr(Self::type_info().name) } + } +} + +/// Every type that has at least a type name also has a valid pointer type name +impl HasStaticTypeInfo for *const T { + fn type_info() -> &'static abi::TypeInfo { + static mut VALUE: Option> = None; + static INIT: Once = Once::new(); + + let map = unsafe { + INIT.call_once(|| { + VALUE = Some(StaticTypeMap::new()); + }); + VALUE.as_ref().unwrap() + }; + + &map.call_once::(|| { + let name = + CString::new(format!("*const {}", T::type_name().to_str().unwrap())).unwrap(); + let guid = abi::Guid { + b: md5::compute(&name.as_bytes()).0, + }; + let name_ptr = name.as_ptr(); + ( + name, + abi::TypeInfo { + guid, + name: name_ptr, + group: abi::TypeGroup::FundamentalTypes, + // size: std::mem::size_of::<*const T>() as u64, + // alignment: std::mem::align_of::<*const T>() as u32, + }, + ) + }) + .1 + } +} + +/// Every type that has at least a type name also has a valid pointer type name +impl HasStaticTypeInfo for *mut T { + fn type_info() -> &'static abi::TypeInfo { + static mut VALUE: Option> = None; + static INIT: Once = Once::new(); + + let map = unsafe { + INIT.call_once(|| { + VALUE = Some(StaticTypeMap::new()); + }); + VALUE.as_ref().unwrap() + }; + + &map.call_once::(|| { + let name = CString::new(format!("*mut {}", T::type_name().to_str().unwrap())).unwrap(); + let guid = abi::Guid { + b: md5::compute(&name.as_bytes()).0, + }; + let name_ptr = name.as_ptr(); + ( + name, + abi::TypeInfo { + guid, + name: name_ptr, + group: abi::TypeGroup::FundamentalTypes, + // size: std::mem::size_of::<*const T>() as u64, + // alignment: std::mem::align_of::<*const T>() as u32, + }, + ) + }) + .1 + } +} + +macro_rules! impl_basic_type_info { + ($( + $ty:ty + ),+) => { + $( + impl HasStaticTypeInfo for $ty { + fn type_info() -> &'static abi::TypeInfo { + static TYPE_INFO: OnceCell = OnceCell::new(); + TYPE_INFO.get_or_init(|| { + static TYPE_INFO_NAME: OnceCell = OnceCell::new(); + let type_info_name: &'static CString = TYPE_INFO_NAME + .get_or_init(|| CString::new(format!("core::{}", stringify!($ty))).unwrap()); + + abi::TypeInfo { + guid: abi::Guid{ b: md5::compute(&type_info_name.as_bytes()).0 }, + name: type_info_name.as_ptr(), + group: abi::TypeGroup::FundamentalTypes, + // size: std::mem::size_of::<$ty>() as u64, + // alignment: std::mem::align_of::<$ty>() as u32, + } + }) + } + } + )+ + } +} + +macro_rules! impl_has_type_info_name { + ($( + $ty:ty => $name:tt + ),+) => { + $( + impl crate::type_info::HasStaticTypeInfoName for $ty { + fn type_name() -> &'static std::ffi::CStr { + static TYPE_INFO_NAME: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); + let type_info_name: &'static std::ffi::CString = TYPE_INFO_NAME + .get_or_init(|| std::ffi::CString::new($name).unwrap()); + type_info_name.as_ref() + } + } + )+ + } +} + +impl_basic_type_info!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128, f32, f64, bool); + +impl_has_type_info_name!( + std::ffi::c_void => "core::void" +); + +#[cfg(target_pointer_width = "64")] +impl HasStaticTypeInfo for usize { + fn type_info() -> &'static abi::TypeInfo { + u64::type_info() + } +} + +#[cfg(target_pointer_width = "64")] +impl HasStaticTypeInfo for isize { + fn type_info() -> &'static abi::TypeInfo { + i64::type_info() + } +} + +#[cfg(target_pointer_width = "32")] +impl HasStaticTypeInfo for usize { + fn type_info() -> &'static abi::TypeInfo { + u32::type_info() + } +} + +#[cfg(target_pointer_width = "32")] +impl HasStaticTypeInfo for isize { + fn type_info() -> &'static abi::TypeInfo { + i32::type_info() + } +} + +#[cfg(test)] +mod tests { + use super::HasStaticTypeInfoName; + + #[test] + fn ptr_test() { + let ty = <*const std::ffi::c_void>::type_name(); + assert_eq!(ty.to_str().unwrap(), "*const core::void"); + + let ty = <*const *mut std::ffi::c_void>::type_name(); + assert_eq!(ty.to_str().unwrap(), "*const *mut core::void"); + + let ty = <*const *const std::ffi::c_void>::type_name(); + assert_eq!(ty.to_str().unwrap(), "*const *const core::void"); + } +} From a521271e1476c52b355d440e0fed1a6456eced63 Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Thu, 19 Mar 2020 21:26:56 +0100 Subject: [PATCH 02/12] feat: added names and types in ir for TypeTable --- crates/mun_codegen/src/code_gen.rs | 8 +++-- crates/mun_codegen/src/ir/type_table.rs | 30 +++++++++---------- .../src/snapshots/test__field_crash.snap | 16 +++++----- .../src/snapshots/test__field_expr.snap | 26 ++++++++-------- .../src/snapshots/test__gc_struct.snap | 16 +++++----- .../src/snapshots/test__struct_test.snap | 30 +++++++++---------- 6 files changed, 65 insertions(+), 61 deletions(-) diff --git a/crates/mun_codegen/src/code_gen.rs b/crates/mun_codegen/src/code_gen.rs index 7eae75402..8c9ce3e0f 100644 --- a/crates/mun_codegen/src/code_gen.rs +++ b/crates/mun_codegen/src/code_gen.rs @@ -228,7 +228,11 @@ pub(crate) fn gen_struct_ptr_array( } /// Generates a global array from the specified list of integers -pub(crate) fn gen_u16_array(module: &Module, integers: impl Iterator) -> PointerValue { +pub(crate) fn gen_u16_array( + module: &Module, + integers: impl Iterator, + name: &str, +) -> PointerValue { let u16_type = module.get_context().i16_type(); let mut integers = integers.peekable(); @@ -240,7 +244,7 @@ pub(crate) fn gen_u16_array(module: &Module, integers: impl Iterator .collect::>(); let array_ir = u16_type.const_array(&integers); - gen_global(module, &array_ir, "").as_pointer_value() + gen_global(module, &array_ir, name).as_pointer_value() } } diff --git a/crates/mun_codegen/src/ir/type_table.rs b/crates/mun_codegen/src/ir/type_table.rs index e02b59088..dacfbd1e3 100644 --- a/crates/mun_codegen/src/ir/type_table.rs +++ b/crates/mun_codegen/src/ir/type_table.rs @@ -169,22 +169,19 @@ impl<'a, D: IrDatabase> TypeTableBuilder<'a, D> { .i8_type() .const_int(u64::from(type_info.guid.b[i]), false) }); - let type_info_ir = context.const_struct( - &[ - context.i8_type().const_array(&guid_bytes_ir).into(), - intern_string( - self.module, - &type_info.name, - &format!("type_info::<{}>::name", type_info.name), - ) + let type_info_ir = self.abi_types.type_info_type.const_named_struct(&[ + context.i8_type().const_array(&guid_bytes_ir).into(), + intern_string( + self.module, + &type_info.name, + &format!("type_info::<{}>::name", type_info.name), + ) + .into(), + context + .i8_type() + .const_int(type_info.group.clone().into(), false) .into(), - context - .i8_type() - .const_int(type_info.group.clone().into(), false) - .into(), - ], - false, - ); + ]); let type_info_ir = match type_info.group { TypeGroup::FundamentalTypes => type_info_ir, TypeGroup::StructTypes(s) => { @@ -247,7 +244,9 @@ impl<'a, D: IrDatabase> TypeTableBuilder<'a, D> { .offset_of_element(&struct_ir, idx as u32) .unwrap() }), + &format!("struct_info::<{}>::field_offsets", name), ); + let field_sizes = gen_u16_array( self.module, fields.iter().map(|field| { @@ -258,6 +257,7 @@ impl<'a, D: IrDatabase> TypeTableBuilder<'a, D> { }, )) }), + &format!("struct_info::<{}>::field_sizes", name), ); let alignment = self.target_data.get_abi_alignment(&struct_ir); diff --git a/crates/mun_codegen/src/snapshots/test__field_crash.snap b/crates/mun_codegen/src/snapshots/test__field_crash.snap index 54decfdd9..3e2932a97 100644 --- a/crates/mun_codegen/src/snapshots/test__field_crash.snap +++ b/crates/mun_codegen/src/snapshots/test__field_crash.snap @@ -16,19 +16,19 @@ target triple = "x86-64" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @0 = private unnamed_addr constant [1 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names"] @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" -@"type_info::" = private unnamed_addr constant { [16 x i8], [10 x i8]*, i8 } { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i8 0 } @"struct_info::::field_types" = private unnamed_addr constant [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] -@1 = private unnamed_addr constant [1 x i16] zeroinitializer -@2 = private unnamed_addr constant [1 x i16] [i16 8] -@"type_info::" = private unnamed_addr constant { { [16 x i8], [4 x i8]*, i8 }, %struct.MunStructInfo } { { [16 x i8], [4 x i8]*, i8 } { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @1, [1 x i16]* @2, i16 1, i16 8, i8 0 } } +@"struct_info::::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer +@"struct_info::::field_sizes" = private unnamed_addr constant [1 x i16] [i16 8] +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", [1 x i16]* @"struct_info::::field_sizes", i16 1, i16 8, i8 0 } } @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00" -@"type_info::<*const TypeInfo>" = private unnamed_addr constant { [16 x i8], [16 x i8]*, i8 } { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i8 0 } +@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i8 0 } @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00" -@"type_info::<*const *mut core::void>" = private unnamed_addr constant { [16 x i8], [23 x i8]*, i8 } { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i8 0 } +@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i8 0 } @"type_info::<*const core::void>::name" = private unnamed_addr constant [18 x i8] c"*const core::void\00" -@"type_info::<*const core::void>" = private unnamed_addr constant { [16 x i8], [18 x i8]*, i8 } { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i8 0 } +@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i8 0 } @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" -@"type_info::<*mut core::void>" = private unnamed_addr constant { [16 x i8], [16 x i8]*, i8 } { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i8 0 } +@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i8 0 } @global_type_table = private unnamed_addr constant [6 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>"] @dispatchTable = global %DispatchTable zeroinitializer @allocatorHandle = private unnamed_addr global i8* null diff --git a/crates/mun_codegen/src/snapshots/test__field_expr.snap b/crates/mun_codegen/src/snapshots/test__field_expr.snap index e0b8b62cf..918dc8f80 100644 --- a/crates/mun_codegen/src/snapshots/test__field_expr.snap +++ b/crates/mun_codegen/src/snapshots/test__field_expr.snap @@ -17,30 +17,30 @@ target triple = "x86-64" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @0 = private unnamed_addr constant [1 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names"] @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" -@"type_info::" = private unnamed_addr constant { [16 x i8], [10 x i8]*, i8 } { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i8 0 } @"struct_info::::field_types" = private unnamed_addr constant [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] -@1 = private unnamed_addr constant [1 x i16] zeroinitializer -@2 = private unnamed_addr constant [1 x i16] [i16 8] -@"type_info::" = private unnamed_addr constant { { [16 x i8], [4 x i8]*, i8 }, %struct.MunStructInfo } { { [16 x i8], [4 x i8]*, i8 } { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @1, [1 x i16]* @2, i16 1, i16 8, i8 1 } } +@"struct_info::::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer +@"struct_info::::field_sizes" = private unnamed_addr constant [1 x i16] [i16 8] +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", [1 x i16]* @"struct_info::::field_sizes", i16 1, i16 8, i8 1 } } @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00" -@"type_info::<*const TypeInfo>" = private unnamed_addr constant { [16 x i8], [16 x i8]*, i8 } { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i8 0 } +@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i8 0 } @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::f64\00" -@"type_info::" = private unnamed_addr constant { [16 x i8], [10 x i8]*, i8 } { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i8 0 } @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00" -@"type_info::<*const *mut core::void>" = private unnamed_addr constant { [16 x i8], [23 x i8]*, i8 } { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i8 0 } +@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i8 0 } @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Bar\00" @"struct_info::::name" = private unnamed_addr constant [4 x i8] c"Bar\00" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"0\00" @"struct_info::::field_names.1" = private unnamed_addr constant [2 x i8] c"1\00" -@3 = private unnamed_addr constant [2 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names", i8 addrspace(4)* @"struct_info::::field_names.1"] +@1 = private unnamed_addr constant [2 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names", i8 addrspace(4)* @"struct_info::::field_names.1"] @"struct_info::::field_types" = private unnamed_addr constant [2 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::"] -@4 = private unnamed_addr constant [2 x i16] [i16 0, i16 8] -@5 = private unnamed_addr constant [2 x i16] [i16 8, i16 8] -@"type_info::" = private unnamed_addr constant { { [16 x i8], [4 x i8]*, i8 }, %struct.MunStructInfo } { { [16 x i8], [4 x i8]*, i8 } { [16 x i8] c"\DD\C3_\88\FAq\B6\EF\14*\E6\1F56FS", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [2 x i8 addrspace(4)*]* @3, [2 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [2 x i16]* @4, [2 x i16]* @5, i16 2, i16 8, i8 1 } } +@"struct_info::::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 8] +@"struct_info::::field_sizes" = private unnamed_addr constant [2 x i16] [i16 8, i16 8] +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\DD\C3_\88\FAq\B6\EF\14*\E6\1F56FS", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [2 x i8 addrspace(4)*]* @1, [2 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [2 x i16]* @"struct_info::::field_offsets", [2 x i16]* @"struct_info::::field_sizes", i16 2, i16 8, i8 1 } } @"type_info::<*const core::void>::name" = private unnamed_addr constant [18 x i8] c"*const core::void\00" -@"type_info::<*const core::void>" = private unnamed_addr constant { [16 x i8], [18 x i8]*, i8 } { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i8 0 } +@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i8 0 } @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" -@"type_info::<*mut core::void>" = private unnamed_addr constant { [16 x i8], [16 x i8]*, i8 } { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i8 0 } +@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i8 0 } @global_type_table = private unnamed_addr constant [8 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>"] @dispatchTable = global %DispatchTable { i8* addrspace(4)* (i8 addrspace(4)*, i8*)* null, i8* addrspace(4)* (i8 addrspace(4)*, i8*)* null, i64 (%Foo)* @foo_a, %Foo (%Bar)* @bar_1 } @allocatorHandle = private unnamed_addr global i8* null diff --git a/crates/mun_codegen/src/snapshots/test__gc_struct.snap b/crates/mun_codegen/src/snapshots/test__gc_struct.snap index 911ef8dde..116859641 100644 --- a/crates/mun_codegen/src/snapshots/test__gc_struct.snap +++ b/crates/mun_codegen/src/snapshots/test__gc_struct.snap @@ -17,19 +17,19 @@ target triple = "x86-64" @"struct_info::::field_names.1" = private unnamed_addr constant [2 x i8] c"b\00" @0 = private unnamed_addr constant [2 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names", i8 addrspace(4)* @"struct_info::::field_names.1"] @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" -@"type_info::" = private unnamed_addr constant { [16 x i8], [10 x i8]*, i8 } { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i8 0 } @"struct_info::::field_types" = private unnamed_addr constant [2 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::"] -@1 = private unnamed_addr constant [2 x i16] [i16 0, i16 8] -@2 = private unnamed_addr constant [2 x i16] [i16 8, i16 8] -@"type_info::" = private unnamed_addr constant { { [16 x i8], [4 x i8]*, i8 }, %struct.MunStructInfo } { { [16 x i8], [4 x i8]*, i8 } { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [2 x i8 addrspace(4)*]* @0, [2 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [2 x i16]* @1, [2 x i16]* @2, i16 2, i16 8, i8 0 } } +@"struct_info::::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 8] +@"struct_info::::field_sizes" = private unnamed_addr constant [2 x i16] [i16 8, i16 8] +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [2 x i8 addrspace(4)*]* @0, [2 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [2 x i16]* @"struct_info::::field_offsets", [2 x i16]* @"struct_info::::field_sizes", i16 2, i16 8, i8 0 } } @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00" -@"type_info::<*const TypeInfo>" = private unnamed_addr constant { [16 x i8], [16 x i8]*, i8 } { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i8 0 } +@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i8 0 } @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00" -@"type_info::<*const *mut core::void>" = private unnamed_addr constant { [16 x i8], [23 x i8]*, i8 } { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i8 0 } +@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i8 0 } @"type_info::<*const core::void>::name" = private unnamed_addr constant [18 x i8] c"*const core::void\00" -@"type_info::<*const core::void>" = private unnamed_addr constant { [16 x i8], [18 x i8]*, i8 } { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i8 0 } +@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i8 0 } @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" -@"type_info::<*mut core::void>" = private unnamed_addr constant { [16 x i8], [16 x i8]*, i8 } { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i8 0 } +@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i8 0 } @global_type_table = private unnamed_addr constant [6 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>"] @dispatchTable = global %DispatchTable zeroinitializer @allocatorHandle = private unnamed_addr global i8* null diff --git a/crates/mun_codegen/src/snapshots/test__struct_test.snap b/crates/mun_codegen/src/snapshots/test__struct_test.snap index c4d871f85..cb679ff6d 100644 --- a/crates/mun_codegen/src/snapshots/test__struct_test.snap +++ b/crates/mun_codegen/src/snapshots/test__struct_test.snap @@ -18,37 +18,37 @@ target triple = "x86-64" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @0 = private unnamed_addr constant [1 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names"] @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" -@"type_info::" = private unnamed_addr constant { [16 x i8], [10 x i8]*, i8 } { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i8 0 } @"struct_info::::field_types" = private unnamed_addr constant [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] -@1 = private unnamed_addr constant [1 x i16] zeroinitializer -@2 = private unnamed_addr constant [1 x i16] [i16 8] -@"type_info::" = private unnamed_addr constant { { [16 x i8], [4 x i8]*, i8 }, %struct.MunStructInfo } { { [16 x i8], [4 x i8]*, i8 } { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @1, [1 x i16]* @2, i16 1, i16 8, i8 1 } } +@"struct_info::::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer +@"struct_info::::field_sizes" = private unnamed_addr constant [1 x i16] [i16 8] +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", [1 x i16]* @"struct_info::::field_sizes", i16 1, i16 8, i8 1 } } @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00" -@"type_info::<*const TypeInfo>" = private unnamed_addr constant { [16 x i8], [16 x i8]*, i8 } { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i8 0 } +@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i8 0 } @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::f64\00" -@"type_info::" = private unnamed_addr constant { [16 x i8], [10 x i8]*, i8 } { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i8 0 } @"type_info::::name" = private unnamed_addr constant [11 x i8] c"core::bool\00" -@"type_info::" = private unnamed_addr constant { [16 x i8], [11 x i8]*, i8 } { [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [11 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [11 x i8]* @"type_info::::name", i8 0 } @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00" -@"type_info::<*const *mut core::void>" = private unnamed_addr constant { [16 x i8], [23 x i8]*, i8 } { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i8 0 } +@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i8 0 } @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Bar\00" @"struct_info::::name" = private unnamed_addr constant [4 x i8] c"Bar\00" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"0\00" @"struct_info::::field_names.1" = private unnamed_addr constant [2 x i8] c"1\00" @"struct_info::::field_names.2" = private unnamed_addr constant [2 x i8] c"2\00" @"struct_info::::field_names.3" = private unnamed_addr constant [2 x i8] c"3\00" -@3 = private unnamed_addr constant [4 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names", i8 addrspace(4)* @"struct_info::::field_names.1", i8 addrspace(4)* @"struct_info::::field_names.2", i8 addrspace(4)* @"struct_info::::field_names.3"] +@1 = private unnamed_addr constant [4 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names", i8 addrspace(4)* @"struct_info::::field_names.1", i8 addrspace(4)* @"struct_info::::field_names.2", i8 addrspace(4)* @"struct_info::::field_names.3"] @"struct_info::::field_types" = private unnamed_addr constant [4 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::"] -@4 = private unnamed_addr constant [4 x i16] [i16 0, i16 8, i16 16, i16 24] -@5 = private unnamed_addr constant [4 x i16] [i16 8, i16 8, i16 1, i16 8] -@"type_info::" = private unnamed_addr constant { { [16 x i8], [4 x i8]*, i8 }, %struct.MunStructInfo } { { [16 x i8], [4 x i8]*, i8 } { [16 x i8] c"\DD\C3_\88\FAq\B6\EF\14*\E6\1F56FS", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [4 x i8 addrspace(4)*]* @3, [4 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [4 x i16]* @4, [4 x i16]* @5, i16 4, i16 8, i8 1 } } +@"struct_info::::field_offsets" = private unnamed_addr constant [4 x i16] [i16 0, i16 8, i16 16, i16 24] +@"struct_info::::field_sizes" = private unnamed_addr constant [4 x i16] [i16 8, i16 8, i16 1, i16 8] +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\DD\C3_\88\FAq\B6\EF\14*\E6\1F56FS", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [4 x i8 addrspace(4)*]* @1, [4 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [4 x i16]* @"struct_info::::field_offsets", [4 x i16]* @"struct_info::::field_sizes", i16 4, i16 8, i8 1 } } @"type_info::<*const core::void>::name" = private unnamed_addr constant [18 x i8] c"*const core::void\00" -@"type_info::<*const core::void>" = private unnamed_addr constant { [16 x i8], [18 x i8]*, i8 } { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i8 0 } +@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i8 0 } @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" -@"type_info::<*mut core::void>" = private unnamed_addr constant { [16 x i8], [16 x i8]*, i8 } { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i8 0 } +@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i8 0 } @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Baz\00" @"struct_info::::name" = private unnamed_addr constant [4 x i8] c"Baz\00" -@"type_info::" = private unnamed_addr constant { { [16 x i8], [4 x i8]*, i8 }, %struct.MunStructInfo } { { [16 x i8], [4 x i8]*, i8 } { [16 x i8] c"\F8\DC\E6\7F,\948\82\82\ED?\A7\97\96\8A|", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", i8 addrspace(4)* addrspace(4)* null, %struct.MunTypeInfo addrspace(4)* addrspace(4)* null, i16 addrspace(4)* null, i16 addrspace(4)* null, i16 0, i16 1, i8 1 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\F8\DC\E6\7F,\948\82\82\ED?\A7\97\96\8A|", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", i8 addrspace(4)* addrspace(4)* null, %struct.MunTypeInfo addrspace(4)* addrspace(4)* null, i16 addrspace(4)* null, i16 addrspace(4)* null, i16 0, i16 1, i8 1 } } @global_type_table = private unnamed_addr constant [10 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::"] @dispatchTable = global %DispatchTable zeroinitializer @allocatorHandle = private unnamed_addr global i8* null From 4f97ff0877d860562373f5487407dc03fef3cd1d Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Thu, 19 Mar 2020 21:53:28 +0100 Subject: [PATCH 03/12] feat: take target data into account when creating types --- crates/mun_codegen/src/intrinsics.rs | 5 +- crates/mun_codegen/src/intrinsics/macros.rs | 12 +- crates/mun_codegen/src/ir.rs | 133 +++++++++++++++----- crates/mun_codegen/src/ir/dispatch_table.rs | 17 ++- crates/mun_codegen/src/ir/intrinsics.rs | 30 +++-- crates/mun_codegen/src/ir/module.rs | 6 +- crates/mun_codegen/src/type_info.rs | 129 +++++++++++-------- 7 files changed, 224 insertions(+), 108 deletions(-) diff --git a/crates/mun_codegen/src/intrinsics.rs b/crates/mun_codegen/src/intrinsics.rs index 46492553c..44b2e8664 100644 --- a/crates/mun_codegen/src/intrinsics.rs +++ b/crates/mun_codegen/src/intrinsics.rs @@ -1,6 +1,7 @@ use crate::ir::dispatch_table::FunctionPrototype; use crate::type_info::TypeInfo; use inkwell::context::Context; +use inkwell::targets::TargetData; use inkwell::types::FunctionType; use std::ffi; @@ -11,10 +12,10 @@ mod macros; /// are mostly used internally. pub trait Intrinsic: Sync { /// Returns the prototype of the intrinsic - fn prototype(&self) -> FunctionPrototype; + fn prototype(&self, context: &Context, target: &TargetData) -> FunctionPrototype; /// Returns the IR type for the function - fn ir_type(&self, context: &Context) -> FunctionType; + fn ir_type(&self, context: &Context, target: &TargetData) -> FunctionType; } intrinsics! { diff --git a/crates/mun_codegen/src/intrinsics/macros.rs b/crates/mun_codegen/src/intrinsics/macros.rs index dc49d3ac0..3a1e0a5f2 100644 --- a/crates/mun_codegen/src/intrinsics/macros.rs +++ b/crates/mun_codegen/src/intrinsics/macros.rs @@ -6,17 +6,17 @@ macro_rules! intrinsics{ } paste::item! { impl Intrinsic for [] { - fn prototype(&self) -> FunctionPrototype { + fn prototype(&self, context: &Context, target: &TargetData) -> FunctionPrototype { FunctionPrototype { name: stringify!($name).to_owned(), - arg_types: vec![$(<$arg as crate::type_info::HasStaticTypeInfo>::type_info()),*], - ret_type: <$ret as crate::type_info::HasStaticReturnTypeInfo>::return_type_info() + arg_types: vec![$(<$arg as crate::type_info::HasStaticTypeInfo>::type_info(context, target)),*], + ret_type: <$ret as crate::type_info::HasStaticReturnTypeInfo>::return_type_info(context, target) } } - fn ir_type(&self, context: &Context) -> FunctionType { - let args = vec![$(<$arg as crate::ir::IsBasicIrType>::ir_type(context)),*]; - <$ret as crate::ir::IsFunctionReturnType>::fn_type(context, &args, false) + fn ir_type(&self, context: &Context, target: &TargetData) -> FunctionType { + let args = vec![$(<$arg as crate::ir::IsBasicIrType>::ir_type(context, target)),*]; + <$ret as crate::ir::IsFunctionReturnType>::fn_type(context, target, &args, false) } } } diff --git a/crates/mun_codegen/src/ir.rs b/crates/mun_codegen/src/ir.rs index 74e1b103b..909aea7b5 100644 --- a/crates/mun_codegen/src/ir.rs +++ b/crates/mun_codegen/src/ir.rs @@ -1,7 +1,8 @@ use crate::type_info::TypeInfo; use inkwell::context::Context; +use inkwell::targets::TargetData; use inkwell::types::{ - AnyType, AnyTypeEnum, BasicType, BasicTypeEnum, FunctionType, IntType, PointerType, + AnyType, AnyTypeEnum, BasicType, BasicTypeEnum, FloatType, FunctionType, IntType, PointerType, }; use inkwell::AddressSpace; @@ -33,33 +34,49 @@ fn try_convert_any_to_basic(ty: AnyTypeEnum) -> Option { pub trait IsIrType { type Type: AnyType; - fn ir_type(context: &Context) -> Self::Type; + fn ir_type(context: &Context, target: &TargetData) -> Self::Type; } +/// Defines that a type has a static represention in inkwell that can be described as a BasicType. pub trait IsBasicIrType { - fn ir_type(context: &Context) -> BasicTypeEnum; + fn ir_type(context: &Context, target: &TargetData) -> BasicTypeEnum; } impl> IsBasicIrType for T { - fn ir_type(context: &Context) -> BasicTypeEnum { - Self::ir_type(context).as_basic_type_enum() + fn ir_type(context: &Context, target: &TargetData) -> BasicTypeEnum { + Self::ir_type(context, target).as_basic_type_enum() } } /// Defines that a type can statically be used as a return type for a function pub trait IsFunctionReturnType { - fn fn_type(context: &Context, arg_types: &[BasicTypeEnum], is_var_args: bool) -> FunctionType; + fn fn_type( + context: &Context, + target: &TargetData, + arg_types: &[BasicTypeEnum], + is_var_args: bool, + ) -> FunctionType; } /// All types that statically have a BasicTypeEnum can also be used as a function return type impl IsFunctionReturnType for T { - fn fn_type(context: &Context, arg_types: &[BasicTypeEnum], is_var_args: bool) -> FunctionType { - T::ir_type(context).fn_type(arg_types, is_var_args) + fn fn_type( + context: &Context, + target: &TargetData, + arg_types: &[BasicTypeEnum], + is_var_args: bool, + ) -> FunctionType { + T::ir_type(context, target).fn_type(arg_types, is_var_args) } } impl IsFunctionReturnType for () { - fn fn_type(context: &Context, arg_types: &[BasicTypeEnum], is_var_args: bool) -> FunctionType { + fn fn_type( + context: &Context, + _target: &TargetData, + arg_types: &[BasicTypeEnum], + is_var_args: bool, + ) -> FunctionType { context.void_type().fn_type(arg_types, is_var_args) } } @@ -68,16 +85,16 @@ impl IsFunctionReturnType for () { pub trait AsIrType { type Type: AnyType; - fn as_ir_type(&self, context: &Context) -> Self::Type; + fn as_ir_type(&self, context: &Context, target: &TargetData) -> Self::Type; } pub trait AsBasicIrType { - fn as_ir_type(&self, context: &Context) -> BasicTypeEnum; + fn as_ir_type(&self, context: &Context, target: &TargetData) -> BasicTypeEnum; } impl> AsBasicIrType for T { - fn as_ir_type(&self, context: &Context) -> BasicTypeEnum { - self.as_ir_type(context).as_basic_type_enum() + fn as_ir_type(&self, context: &Context, target: &TargetData) -> BasicTypeEnum { + self.as_ir_type(context, target).as_basic_type_enum() } } @@ -86,6 +103,7 @@ pub trait AsFunctionReturnType { fn as_fn_type( &self, context: &Context, + target: &TargetData, arg_types: &[BasicTypeEnum], is_var_args: bool, ) -> FunctionType; @@ -95,10 +113,12 @@ impl AsFunctionReturnType for T { fn as_fn_type( &self, context: &Context, + target: &TargetData, arg_types: &[BasicTypeEnum], is_var_args: bool, ) -> FunctionType { - self.as_ir_type(context).fn_type(arg_types, is_var_args) + self.as_ir_type(context, target) + .fn_type(arg_types, is_var_args) } } @@ -106,6 +126,7 @@ impl AsFunctionReturnType for () { fn as_fn_type( &self, context: &Context, + _target: &TargetData, arg_types: &[BasicTypeEnum], is_var_args: bool, ) -> FunctionType { @@ -116,7 +137,7 @@ impl AsFunctionReturnType for () { impl IsIrType for u8 { type Type = IntType; - fn ir_type(context: &Context) -> Self::Type { + fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { context.i8_type() } } @@ -124,7 +145,7 @@ impl IsIrType for u8 { impl IsIrType for u16 { type Type = IntType; - fn ir_type(context: &Context) -> Self::Type { + fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { context.i16_type() } } @@ -132,7 +153,7 @@ impl IsIrType for u16 { impl IsIrType for u32 { type Type = IntType; - fn ir_type(context: &Context) -> Self::Type { + fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { context.i32_type() } } @@ -140,7 +161,7 @@ impl IsIrType for u32 { impl IsIrType for u64 { type Type = IntType; - fn ir_type(context: &Context) -> Self::Type { + fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { context.i64_type() } } @@ -148,7 +169,7 @@ impl IsIrType for u64 { impl IsIrType for i8 { type Type = IntType; - fn ir_type(context: &Context) -> Self::Type { + fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { context.i8_type() } } @@ -156,7 +177,7 @@ impl IsIrType for i8 { impl IsIrType for i16 { type Type = IntType; - fn ir_type(context: &Context) -> Self::Type { + fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { context.i16_type() } } @@ -164,7 +185,7 @@ impl IsIrType for i16 { impl IsIrType for i32 { type Type = IntType; - fn ir_type(context: &Context) -> Self::Type { + fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { context.i32_type() } } @@ -172,52 +193,100 @@ impl IsIrType for i32 { impl IsIrType for i64 { type Type = IntType; - fn ir_type(context: &Context) -> Self::Type { + fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { context.i64_type() } } +impl IsIrType for usize { + type Type = IntType; + + fn ir_type(context: &Context, target: &TargetData) -> Self::Type { + match target.get_pointer_byte_size(None) { + 4 => ::ir_type(context, target), + 8 => ::ir_type(context, target), + _ => unimplemented!("unsupported pointer byte size"), + } + } +} + +impl IsIrType for isize { + type Type = IntType; + + fn ir_type(context: &Context, target: &TargetData) -> Self::Type { + match target.get_pointer_byte_size(None) { + 4 => ::ir_type(context, target), + 8 => ::ir_type(context, target), + _ => unimplemented!("unsupported pointer byte size"), + } + } +} + +impl IsIrType for f32 { + type Type = FloatType; + + fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { + context.f32_type() + } +} + +impl IsIrType for f64 { + type Type = FloatType; + + fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { + context.f64_type() + } +} + +impl IsIrType for bool { + type Type = IntType; + + fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { + context.bool_type() + } +} + pub trait IsPointerType { - fn ir_type(context: &Context) -> PointerType; + fn ir_type(context: &Context, target: &TargetData) -> PointerType; } impl> IsPointerType for *const T { - fn ir_type(context: &Context) -> PointerType { - T::ir_type(context).ptr_type(AddressSpace::Const) + fn ir_type(context: &Context, target: &TargetData) -> PointerType { + T::ir_type(context, target).ptr_type(AddressSpace::Const) } } // HACK: Manually add `*const TypeInfo` impl IsPointerType for *const TypeInfo { - fn ir_type(context: &Context) -> PointerType { + fn ir_type(context: &Context, _target: &TargetData) -> PointerType { context.i8_type().ptr_type(AddressSpace::Const) } } // HACK: Manually add `*const c_void` impl IsPointerType for *const std::ffi::c_void { - fn ir_type(context: &Context) -> PointerType { + fn ir_type(context: &Context, _target: &TargetData) -> PointerType { context.i8_type().ptr_type(AddressSpace::Const) } } // HACK: Manually add `*mut c_void` impl IsPointerType for *mut std::ffi::c_void { - fn ir_type(context: &Context) -> PointerType { + fn ir_type(context: &Context, _target: &TargetData) -> PointerType { context.i8_type().ptr_type(AddressSpace::Generic) } } impl> IsPointerType for *mut T { - fn ir_type(context: &Context) -> PointerType { - T::ir_type(context).ptr_type(AddressSpace::Generic) + fn ir_type(context: &Context, target: &TargetData) -> PointerType { + T::ir_type(context, target).ptr_type(AddressSpace::Generic) } } impl IsIrType for T { type Type = PointerType; - fn ir_type(context: &Context) -> Self::Type { - T::ir_type(context) + fn ir_type(context: &Context, target: &TargetData) -> Self::Type { + T::ir_type(context, target) } } diff --git a/crates/mun_codegen/src/ir/dispatch_table.rs b/crates/mun_codegen/src/ir/dispatch_table.rs index af9eaff15..ec3e29472 100644 --- a/crates/mun_codegen/src/ir/dispatch_table.rs +++ b/crates/mun_codegen/src/ir/dispatch_table.rs @@ -7,6 +7,8 @@ use inkwell::values::{BasicValueEnum, PointerValue}; use crate::intrinsics::Intrinsic; use crate::type_info::TypeInfo; use hir::{Body, Expr, ExprId, InferenceResult}; +use inkwell::context::Context; +use inkwell::targets::TargetData; use std::collections::{BTreeMap, HashMap}; use std::sync::Arc; @@ -24,6 +26,10 @@ use std::sync::Arc; /// functions. This basically enables all hot reloading within Mun. #[derive(Debug, Clone, Eq, PartialEq)] pub struct DispatchTable { + // The LLVM context in which all LLVM types live + context: Arc, + // The target for which to create the dispatch table + target: Arc, // This contains the function that map to the DispatchTable struct fields function_to_idx: HashMap, // Prototype to function index @@ -84,7 +90,7 @@ impl DispatchTable { builder: &inkwell::builder::Builder, intrinsic: &impl Intrinsic, ) -> PointerValue { - let prototype = intrinsic.prototype(); + let prototype = intrinsic.prototype(self.context.as_ref(), self.target.as_ref()); // Get the index of the intrinsic let index = *self @@ -129,7 +135,12 @@ impl DispatchTable { /// A struct that can be used to build the dispatch table from HIR. pub(crate) struct DispatchTableBuilder<'a, D: IrDatabase> { db: &'a D, + // The LLVM context in which all LLVM types live + context: Arc, + // The module in which all values live module: &'a Module, + // The target for which to create the dispatch table + target: Arc, // This contains the functions that map to the DispatchTable struct fields function_to_idx: HashMap, // Prototype to function index @@ -156,7 +167,9 @@ impl<'a, D: IrDatabase> DispatchTableBuilder<'a, D> { ) -> Self { let mut table = DispatchTableBuilder { db, + context: db.context(), module, + target: db.target_data(), function_to_idx: Default::default(), prototype_to_idx: Default::default(), entries: Default::default(), @@ -303,6 +316,8 @@ impl<'a, D: IrDatabase> DispatchTableBuilder<'a, D> { } DispatchTable { + context: self.context, + target: self.target, function_to_idx: self.function_to_idx, prototype_to_idx: self.prototype_to_idx, table_ref: self.table_ref, diff --git a/crates/mun_codegen/src/ir/intrinsics.rs b/crates/mun_codegen/src/ir/intrinsics.rs index 34059b15a..f6062c643 100644 --- a/crates/mun_codegen/src/ir/intrinsics.rs +++ b/crates/mun_codegen/src/ir/intrinsics.rs @@ -10,11 +10,17 @@ use std::sync::Arc; // Use a `BTreeMap` to guarantee deterministically ordered output pub type IntrinsicsMap = BTreeMap; -fn collect_intrinsic(module: &Module, entries: &mut IntrinsicsMap, intrinsic: &impl Intrinsic) { - let prototype = intrinsic.prototype(); +fn collect_intrinsic( + d: &D, + entries: &mut IntrinsicsMap, + intrinsic: &impl Intrinsic, +) { + let context = d.context(); + let target = d.target_data(); + let prototype = intrinsic.prototype(context.as_ref(), target.as_ref()); entries .entry(prototype) - .or_insert_with(|| intrinsic.ir_type(&module.get_context())); + .or_insert_with(|| intrinsic.ir_type(context.as_ref(), target.as_ref())); } fn collect_expr( @@ -32,8 +38,8 @@ fn collect_expr( if let Expr::Call { callee, .. } = expr { match infer[*callee].as_callable_def() { Some(hir::CallableDef::Struct(_)) => { - collect_intrinsic(module, entries, &intrinsics::new); - collect_intrinsic(module, entries, &intrinsics::clone); + collect_intrinsic(db, entries, &intrinsics::new); + collect_intrinsic(db, entries, &intrinsics::clone); // self.collect_intrinsic(module, entries, &intrinsics::drop); *needs_alloc = true; } @@ -43,8 +49,8 @@ fn collect_expr( } if let Expr::RecordLit { .. } = expr { - collect_intrinsic(module, entries, &intrinsics::new); - collect_intrinsic(module, entries, &intrinsics::clone); + collect_intrinsic(db, entries, &intrinsics::new); + collect_intrinsic(db, entries, &intrinsics::clone); // self.collect_intrinsic(module, entries, &intrinsics::drop); *needs_alloc = true; } @@ -57,8 +63,8 @@ fn collect_expr( .expect("unknown path"); if let hir::Resolution::Def(hir::ModuleDef::Struct(_)) = resolution { - collect_intrinsic(module, entries, &intrinsics::new); - collect_intrinsic(module, entries, &intrinsics::clone); + collect_intrinsic(db, entries, &intrinsics::new); + collect_intrinsic(db, entries, &intrinsics::clone); // self.collect_intrinsic( module, entries, &intrinsics::drop); *needs_alloc = true; } @@ -89,9 +95,9 @@ pub fn collect_fn_body( ); } -pub fn collect_wrapper_body(module: &Module, entries: &mut IntrinsicsMap, needs_alloc: &mut bool) { - collect_intrinsic(module, entries, &intrinsics::new); - collect_intrinsic(module, entries, &intrinsics::clone); +pub fn collect_wrapper_body(db: &D, entries: &mut IntrinsicsMap, needs_alloc: &mut bool) { + collect_intrinsic(db, entries, &intrinsics::new); + collect_intrinsic(db, entries, &intrinsics::clone); // self.collect_intrinsic(entries, &intrinsics::drop, module); *needs_alloc = true; } diff --git a/crates/mun_codegen/src/ir/module.rs b/crates/mun_codegen/src/ir/module.rs index 2fa8677e3..f57b7775c 100644 --- a/crates/mun_codegen/src/ir/module.rs +++ b/crates/mun_codegen/src/ir/module.rs @@ -56,11 +56,7 @@ pub(crate) fn ir_query(db: &impl IrDatabase, file_id: FileId) -> Arc { ); if !f.data(db).visibility().is_private() && !fn_sig.marshallable(db) { - intrinsics::collect_wrapper_body( - &llvm_module, - &mut intrinsics_map, - &mut needs_alloc, - ); + intrinsics::collect_wrapper_body(db, &mut intrinsics_map, &mut needs_alloc); // Generate wrapper function let wrapper_fun = function::gen_signature( diff --git a/crates/mun_codegen/src/type_info.rs b/crates/mun_codegen/src/type_info.rs index fee303fa6..1d045550a 100644 --- a/crates/mun_codegen/src/type_info.rs +++ b/crates/mun_codegen/src/type_info.rs @@ -1,4 +1,6 @@ use abi::Guid; +use inkwell::context::Context; +use inkwell::targets::TargetData; use std::hash::{Hash, Hasher}; #[derive(Clone, Debug, Eq, PartialEq)] @@ -61,110 +63,137 @@ impl TypeInfo { /// A trait that statically defines that a type can be used as an argument. pub trait HasStaticTypeInfo { - fn type_info() -> TypeInfo; + fn type_info( + context: &inkwell::context::Context, + target: &inkwell::targets::TargetData, + ) -> TypeInfo; } pub trait HasTypeInfo { - fn type_info(&self) -> TypeInfo; + fn type_info(&self, context: &Context, target: &TargetData) -> TypeInfo; } impl HasTypeInfo for T { - fn type_info(&self) -> TypeInfo { - T::type_info() + fn type_info(&self, context: &Context, target: &TargetData) -> TypeInfo { + T::type_info(context, target) } } -impl HasStaticTypeInfo for u8 { - fn type_info() -> TypeInfo { - TypeInfo::new("core::u8", TypeGroup::FundamentalTypes) - } +pub trait HasStaticTypeName { + fn type_name(context: &Context, target: &TargetData) -> String; } -impl HasStaticTypeInfo for u64 { - fn type_info() -> TypeInfo { - TypeInfo::new("core::u64", TypeGroup::FundamentalTypes) +impl HasStaticTypeName for T { + fn type_name(context: &Context, target: &TargetData) -> String { + T::type_info(context, target).name } } -impl HasStaticTypeInfo for i64 { - fn type_info() -> TypeInfo { - TypeInfo::new("core::i64", TypeGroup::FundamentalTypes) +macro_rules! impl_fundamental_static_type_info { + ($( + $ty:ty + ),+) => { + $( + impl HasStaticTypeInfo for $ty { + fn type_info(_context: &Context, _target: &TargetData) -> TypeInfo { + //let ty = <$ty>::ir_type(context, target); + TypeInfo::new( + format!("core::{}", stringify!($ty)), + // target.get_abi_size(&ty), + // target.get_abi_alignment(&ty), + TypeGroup::FundamentalTypes, + ) + } + } + )+ } } -impl HasStaticTypeInfo for f32 { - fn type_info() -> TypeInfo { - TypeInfo::new("core::f32", TypeGroup::FundamentalTypes) - } -} +impl_fundamental_static_type_info!(u8, u16, u32, u64, i8, i16, i32, i64, f32, f64, bool); -impl HasStaticTypeInfo for bool { - fn type_info() -> TypeInfo { - TypeInfo::new("core::bool", TypeGroup::FundamentalTypes) - } -} - -impl HasStaticTypeInfo for std::ffi::c_void { - fn type_info() -> TypeInfo { - TypeInfo::new("core::void", TypeGroup::FundamentalTypes) +impl HasStaticTypeInfo for *mut T { + fn type_info(context: &Context, target: &TargetData) -> TypeInfo { + //let ty = target.ptr_sized_int_type(None); + TypeInfo::new( + format!("*mut {}", T::type_name(context, target)), + // target.get_abi_size(&ty), + // target.get_abi_alignment(&ty), + TypeGroup::FundamentalTypes, + ) } } -impl HasStaticTypeInfo for *mut T { - fn type_info() -> TypeInfo { +impl HasStaticTypeInfo for *const T { + fn type_info( + context: &inkwell::context::Context, + target: &inkwell::targets::TargetData, + ) -> TypeInfo { + //let ty = target.ptr_sized_int_type(None); TypeInfo::new( - format!("*mut {}", T::type_info().name), + format!("*const {}", T::type_name(context, target)), + // target.get_abi_size(&ty), + // target.get_abi_alignment(&ty), TypeGroup::FundamentalTypes, ) } } impl HasStaticTypeInfo for usize { - fn type_info() -> TypeInfo { - TypeInfo::new("core::u64", TypeGroup::FundamentalTypes) + fn type_info(context: &Context, target: &TargetData) -> TypeInfo { + match target.get_pointer_byte_size(None) { + 4 => ::type_info(context, target), + 8 => ::type_info(context, target), + _ => unreachable!("unsupported pointer byte size"), + } } } -impl HasStaticTypeInfo for *const T { - fn type_info() -> TypeInfo { - TypeInfo::new( - format!("*const {}", T::type_info().name), - TypeGroup::FundamentalTypes, - ) +impl HasStaticTypeInfo for isize { + fn type_info(context: &Context, target: &TargetData) -> TypeInfo { + match target.get_pointer_byte_size(None) { + 4 => ::type_info(context, target), + 8 => ::type_info(context, target), + _ => unreachable!("unsupported pointer byte size"), + } + } +} + +impl HasStaticTypeName for TypeInfo { + fn type_name(_context: &Context, _target: &TargetData) -> String { + "TypeInfo".to_owned() } } -// HACK: Manually add `*const TypeInfo` -impl HasStaticTypeInfo for *const TypeInfo { - fn type_info() -> TypeInfo { - TypeInfo::new("*const TypeInfo", TypeGroup::FundamentalTypes) +impl HasStaticTypeName for std::ffi::c_void { + fn type_name(_context: &Context, _target: &TargetData) -> String { + "core::void".to_owned() } } /// A trait that statically defines that a type can be used as a return type for a function. pub trait HasStaticReturnTypeInfo { - fn return_type_info() -> Option; + fn return_type_info(context: &Context, target: &TargetData) -> Option; } /// A trait that defines that a type can be used as a return type for a function. pub trait HasReturnTypeInfo { - fn return_type_info(&self) -> Option; + fn return_type_info(&self, context: &Context, target: &TargetData) -> Option; } impl HasReturnTypeInfo for T { - fn return_type_info(&self) -> Option { - T::return_type_info() + fn return_type_info(&self, context: &Context, target: &TargetData) -> Option { + T::return_type_info(context, target) } } impl HasStaticReturnTypeInfo for T { - fn return_type_info() -> Option { - Some(T::type_info()) + fn return_type_info(context: &Context, target: &TargetData) -> Option { + Some(T::type_info(context, target)) } } impl HasStaticReturnTypeInfo for () { - fn return_type_info() -> Option { + fn return_type_info(_context: &Context, _target: &TargetData) -> Option { None } } From 8aebb96d2cfdb2ff59b9ab1326aba4513366d4b5 Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Thu, 19 Mar 2020 23:02:35 +0100 Subject: [PATCH 04/12] feat: derive size and alignment information for types --- crates/mun_codegen/src/ir/module.rs | 15 +++++- crates/mun_codegen/src/ir/ty.rs | 83 +++++++++++++++++++---------- crates/mun_codegen/src/type_info.rs | 49 +++++++++++++---- 3 files changed, 107 insertions(+), 40 deletions(-) diff --git a/crates/mun_codegen/src/ir/module.rs b/crates/mun_codegen/src/ir/module.rs index f57b7775c..1d6055fea 100644 --- a/crates/mun_codegen/src/ir/module.rs +++ b/crates/mun_codegen/src/ir/module.rs @@ -80,10 +80,23 @@ pub(crate) fn ir_query(db: &impl IrDatabase, file_id: FileId) -> Arc { let mut type_table_builder = TypeTableBuilder::new(db, &llvm_module, &abi_types, intrinsics_map.keys()); + // First generate the bodies of all structs + for s in db + .module_data(file_id) + .definitions() + .iter() + .filter_map(|def| match def { + ModuleDef::Struct(s) => Some(s), + _ => None, + }) + { + adt::gen_struct_decl(db, *s); + } + + // Next, collect type information of all structs for def in db.module_data(file_id).definitions() { match def { ModuleDef::Struct(s) => { - adt::gen_struct_decl(db, *s); type_table_builder.collect_struct(*s); } ModuleDef::Function(f) => { diff --git a/crates/mun_codegen/src/ir/ty.rs b/crates/mun_codegen/src/ir/ty.rs index 5ed9f959c..04c67722b 100644 --- a/crates/mun_codegen/src/ir/ty.rs +++ b/crates/mun_codegen/src/ir/ty.rs @@ -1,10 +1,11 @@ use super::try_convert_any_to_basic; +use crate::type_info::TypeSize; use crate::{ type_info::{TypeGroup, TypeInfo}, CodeGenParams, IrDatabase, }; use hir::{ApplicationTy, CallableDef, FloatBitness, FloatTy, IntBitness, IntTy, Ty, TypeCtor}; -use inkwell::types::{AnyTypeEnum, BasicType, BasicTypeEnum, StructType}; +use inkwell::types::{AnyTypeEnum, BasicType, BasicTypeEnum, FloatType, IntType, StructType}; use inkwell::AddressSpace; use mun_target::spec::Target; @@ -15,23 +16,8 @@ pub(crate) fn ir_query(db: &impl IrDatabase, ty: Ty, params: CodeGenParams) -> A match ty { Ty::Empty => AnyTypeEnum::StructType(context.struct_type(&[], false)), Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { - // Float primitives - TypeCtor::Float(fty) => match fty.resolve(&db.target()).bitness { - FloatBitness::X64 => AnyTypeEnum::FloatType(context.f64_type()), - FloatBitness::X32 => AnyTypeEnum::FloatType(context.f32_type()), - _ => unreachable!() - } - - // Int primitives - TypeCtor::Int(ity) => match ity.resolve(&db.target()).bitness { - IntBitness::X64 => AnyTypeEnum::IntType(context.i64_type()), - IntBitness::X32 => AnyTypeEnum::IntType(context.i32_type()), - IntBitness::X16 => AnyTypeEnum::IntType(context.i16_type()), - IntBitness::X8 => AnyTypeEnum::IntType(context.i8_type()), - _ => unreachable!() - } - - // Boolean + TypeCtor::Float(fty) => float_ty_query(db, fty).into(), + TypeCtor::Int(ity) => int_ty_query(db, ity).into(), TypeCtor::Bool => AnyTypeEnum::IntType(context.bool_type()), TypeCtor::FnDef(def @ CallableDef::Function(_)) => { @@ -72,6 +58,28 @@ pub(crate) fn ir_query(db: &impl IrDatabase, ty: Ty, params: CodeGenParams) -> A } } +/// Returns the LLVM IR type of the specified float type +fn float_ty_query(db: &impl IrDatabase, fty: FloatTy) -> FloatType { + let context = db.context(); + match fty.resolve(&db.target()).bitness { + FloatBitness::X64 => context.f64_type(), + FloatBitness::X32 => context.f32_type(), + _ => unreachable!(), + } +} + +/// Returns the LLVM IR type of the specified int type +fn int_ty_query(db: &impl IrDatabase, ity: IntTy) -> IntType { + let context = db.context(); + match ity.resolve(&db.target()).bitness { + IntBitness::X64 => context.i64_type(), + IntBitness::X32 => context.i32_type(), + IntBitness::X16 => context.i16_type(), + IntBitness::X8 => context.i8_type(), + _ => unreachable!(), + } +} + /// Returns the LLVM IR type of the specified struct pub fn struct_ty_query(db: &impl IrDatabase, s: hir::Struct) -> StructType { let name = s.name(db).to_string(); @@ -90,18 +98,37 @@ pub fn struct_ty_query(db: &impl IrDatabase, s: hir::Struct) -> StructType { /// Constructs the `TypeInfo` for the specified HIR type pub fn type_info_query(db: &impl IrDatabase, ty: Ty) -> TypeInfo { + let target = db.target_data(); match ty { Ty::Apply(ctor) => match ctor.ctor { - TypeCtor::Float(ty) => TypeInfo::new( - format!("core::{}", ty.resolve(&db.target())), - TypeGroup::FundamentalTypes, - ), - TypeCtor::Int(ty) => TypeInfo::new( - format!("core::{}", ty.resolve(&db.target())), - TypeGroup::FundamentalTypes, - ), - TypeCtor::Bool => TypeInfo::new("core::bool", TypeGroup::FundamentalTypes), - TypeCtor::Struct(s) => TypeInfo::new(s.name(db).to_string(), TypeGroup::StructTypes(s)), + TypeCtor::Float(ty) => { + let ir_ty = float_ty_query(db, ty); + let type_size = TypeSize::from_ir_type(&ir_ty, target.as_ref()); + TypeInfo::new( + format!("core::{}", ty.resolve(&db.target())), + TypeGroup::FundamentalTypes, + type_size, + ) + } + TypeCtor::Int(ty) => { + let ir_ty = int_ty_query(db, ty); + let type_size = TypeSize::from_ir_type(&ir_ty, target.as_ref()); + TypeInfo::new( + format!("core::{}", ty.resolve(&db.target())), + TypeGroup::FundamentalTypes, + type_size, + ) + } + TypeCtor::Bool => { + let ir_ty = db.context().bool_type(); + let type_size = TypeSize::from_ir_type(&ir_ty, target.as_ref()); + TypeInfo::new("core::bool", TypeGroup::FundamentalTypes, type_size) + } + TypeCtor::Struct(s) => { + let ir_ty = db.struct_ty(s); + let type_size = TypeSize::from_ir_type(&ir_ty, target.as_ref()); + TypeInfo::new(s.name(db).to_string(), TypeGroup::StructTypes(s), type_size) + } _ => unreachable!("{:?} unhandled", ctor), }, _ => unreachable!("{:?} unhandled", ty), diff --git a/crates/mun_codegen/src/type_info.rs b/crates/mun_codegen/src/type_info.rs index 1d045550a..10ba18c22 100644 --- a/crates/mun_codegen/src/type_info.rs +++ b/crates/mun_codegen/src/type_info.rs @@ -1,6 +1,8 @@ +use super::ir::IsIrType; use abi::Guid; use inkwell::context::Context; use inkwell::targets::TargetData; +use inkwell::types::AnyType; use std::hash::{Hash, Hasher}; #[derive(Clone, Debug, Eq, PartialEq)] @@ -18,11 +20,38 @@ impl From for u64 { } } +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct TypeSize { + // The size of the type in bits + pub bit_size: u64, + + // The number of bytes required to store the type + pub store_size: u64, + + // The number of bytes between successive object, including alignment and padding + pub alloc_size: u64, + + // The alignment of the type + pub alignment: u32, +} + +impl TypeSize { + pub fn from_ir_type(ty: &impl AnyType, target: &TargetData) -> Self { + Self { + bit_size: target.get_bit_size(ty), + store_size: target.get_store_size(ty), + alloc_size: target.get_abi_size(ty), + alignment: target.get_abi_alignment(ty), + } + } +} + #[derive(Clone, Debug, Eq)] pub struct TypeInfo { pub guid: Guid, pub name: String, pub group: TypeGroup, + pub size: TypeSize, } impl Hash for TypeInfo { @@ -50,13 +79,14 @@ impl PartialOrd for TypeInfo { } impl TypeInfo { - pub fn new>(name: S, group: TypeGroup) -> TypeInfo { + pub fn new>(name: S, group: TypeGroup, type_size: TypeSize) -> TypeInfo { TypeInfo { name: name.as_ref().to_string(), guid: Guid { b: md5::compute(name.as_ref()).0, }, group, + size: type_size, } } } @@ -95,13 +125,12 @@ macro_rules! impl_fundamental_static_type_info { ),+) => { $( impl HasStaticTypeInfo for $ty { - fn type_info(_context: &Context, _target: &TargetData) -> TypeInfo { - //let ty = <$ty>::ir_type(context, target); + fn type_info(context: &Context, target: &TargetData) -> TypeInfo { + let ty = <$ty as IsIrType>::ir_type(context, target); TypeInfo::new( format!("core::{}", stringify!($ty)), - // target.get_abi_size(&ty), - // target.get_abi_alignment(&ty), TypeGroup::FundamentalTypes, + TypeSize::from_ir_type(&ty, target) ) } } @@ -113,12 +142,11 @@ impl_fundamental_static_type_info!(u8, u16, u32, u64, i8, i16, i32, i64, f32, f6 impl HasStaticTypeInfo for *mut T { fn type_info(context: &Context, target: &TargetData) -> TypeInfo { - //let ty = target.ptr_sized_int_type(None); + let ty = target.ptr_sized_int_type(None); TypeInfo::new( format!("*mut {}", T::type_name(context, target)), - // target.get_abi_size(&ty), - // target.get_abi_alignment(&ty), TypeGroup::FundamentalTypes, + TypeSize::from_ir_type(&ty, target), ) } } @@ -128,12 +156,11 @@ impl HasStaticTypeInfo for *const T { context: &inkwell::context::Context, target: &inkwell::targets::TargetData, ) -> TypeInfo { - //let ty = target.ptr_sized_int_type(None); + let ty = target.ptr_sized_int_type(None); TypeInfo::new( format!("*const {}", T::type_name(context, target)), - // target.get_abi_size(&ty), - // target.get_abi_alignment(&ty), TypeGroup::FundamentalTypes, + TypeSize::from_ir_type(&ty, target), ) } } From d3ffad8a8b0e43e92b8ceeb1349ca349c6930162 Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Thu, 19 Mar 2020 23:33:19 +0100 Subject: [PATCH 05/12] feat: added size and alignment to TypeInfo removed from StructInfo --- crates/mun_abi/c | 2 +- crates/mun_abi/src/autogen.rs | 58 +++---- crates/mun_abi/src/autogen_impl.rs | 150 +++++++----------- crates/mun_codegen/src/ir/abi_types.rs | 10 +- crates/mun_codegen/src/ir/type_table.rs | 31 ++-- .../src/snapshots/test__field_crash.snap | 17 +- .../src/snapshots/test__field_expr.snap | 22 ++- .../src/snapshots/test__gc_struct.snap | 17 +- .../src/snapshots/test__struct_test.snap | 26 ++- crates/mun_runtime/src/allocator.rs | 14 +- crates/mun_runtime/src/struct.rs | 7 +- crates/mun_runtime/src/type_info.rs | 12 +- crates/mun_runtime_capi/ffi | 2 +- crates/tools/src/abi.rs | 1 + 14 files changed, 158 insertions(+), 211 deletions(-) diff --git a/crates/mun_abi/c b/crates/mun_abi/c index fe351ecde..b8ead3779 160000 --- a/crates/mun_abi/c +++ b/crates/mun_abi/c @@ -1 +1 @@ -Subproject commit fe351ecdec31624373f92851089e665f1314840f +Subproject commit b8ead37791c40f9c8b84380fb0f6dc3b50321b7c diff --git a/crates/mun_abi/src/autogen.rs b/crates/mun_abi/src/autogen.rs index 92a987042..f54ed93de 100644 --- a/crates/mun_abi/src/autogen.rs +++ b/crates/mun_abi/src/autogen.rs @@ -46,6 +46,10 @@ pub struct TypeInfo { pub guid: Guid, #[doc = " Type name"] pub name: *const ::std::os::raw::c_char, + #[doc = " The exact size of the type in bits without any padding"] + pub size_in_bits: u64, + #[doc = " The alignment of the type"] + pub alignment: u32, #[doc = " Type group"] pub group: TypeGroup, } @@ -53,7 +57,7 @@ pub struct TypeInfo { fn bindgen_test_layout_TypeInfo() { assert_eq!( ::std::mem::size_of::(), - 32usize, + 40usize, concat!("Size of: ", stringify!(TypeInfo)) ); assert_eq!( @@ -82,8 +86,28 @@ fn bindgen_test_layout_TypeInfo() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).group as *const _ as usize }, + unsafe { &(*(::std::ptr::null::())).size_in_bits as *const _ as usize }, 24usize, + concat!( + "Offset of field: ", + stringify!(TypeInfo), + "::", + stringify!(size_in_bits) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).alignment as *const _ as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(TypeInfo), + "::", + stringify!(alignment) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).group as *const _ as usize }, + 36usize, concat!( "Offset of field: ", stringify!(TypeInfo), @@ -232,12 +256,8 @@ pub struct StructInfo { pub field_types: *const *const TypeInfo, #[doc = " Struct fields' offsets"] pub field_offsets: *const u16, - #[doc = " Struct fields' sizes (in bytes)"] - pub field_sizes: *const u16, #[doc = " Number of fields"] pub num_fields: u16, - #[doc = " Struct memory alignment"] - pub alignment: u16, #[doc = " Struct memory kind"] pub memory_kind: StructMemoryKind, } @@ -245,7 +265,7 @@ pub struct StructInfo { fn bindgen_test_layout_StructInfo() { assert_eq!( ::std::mem::size_of::(), - 48usize, + 40usize, concat!("Size of: ", stringify!(StructInfo)) ); assert_eq!( @@ -293,19 +313,9 @@ fn bindgen_test_layout_StructInfo() { stringify!(field_offsets) ) ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).field_sizes as *const _ as usize }, - 32usize, - concat!( - "Offset of field: ", - stringify!(StructInfo), - "::", - stringify!(field_sizes) - ) - ); assert_eq!( unsafe { &(*(::std::ptr::null::())).num_fields as *const _ as usize }, - 40usize, + 32usize, concat!( "Offset of field: ", stringify!(StructInfo), @@ -313,19 +323,9 @@ fn bindgen_test_layout_StructInfo() { stringify!(num_fields) ) ); - assert_eq!( - unsafe { &(*(::std::ptr::null::())).alignment as *const _ as usize }, - 42usize, - concat!( - "Offset of field: ", - stringify!(StructInfo), - "::", - stringify!(alignment) - ) - ); assert_eq!( unsafe { &(*(::std::ptr::null::())).memory_kind as *const _ as usize }, - 44usize, + 34usize, concat!( "Offset of field: ", stringify!(StructInfo), diff --git a/crates/mun_abi/src/autogen_impl.rs b/crates/mun_abi/src/autogen_impl.rs index f2aad2d20..8c40e42a8 100644 --- a/crates/mun_abi/src/autogen_impl.rs +++ b/crates/mun_abi/src/autogen_impl.rs @@ -25,6 +25,21 @@ impl TypeInfo { None } } + + /// Returns the size of the type in bits + pub fn size_in_bits(&self) -> u64 { + self.size_in_bits + } + + /// Returns the size of the type in bytes + pub fn size_in_bytes(&self) -> u64 { + (self.size_in_bits + 7) / 8 + } + + /// Returns the alignment of the type in bytes + pub fn alignment(&self) -> u32 { + self.alignment + } } impl fmt::Display for TypeInfo { @@ -138,15 +153,6 @@ impl StructInfo { } } - /// Returns the struct's field sizes. - pub fn field_sizes(&self) -> &[u16] { - if self.num_fields == 0 { - &[] - } else { - unsafe { slice::from_raw_parts(self.field_sizes, self.num_fields as usize) } - } - } - /// Returns the index of the field matching the specified `field_name`. pub fn find_field_index(struct_info: &StructInfo, field_name: &str) -> Result { struct_info @@ -162,13 +168,6 @@ impl StructInfo { ) }) } - - /// Returns the size of the struct - pub fn size(&self) -> usize { - (self.field_offsets().last().cloned().unwrap_or(0) - + self.field_sizes().last().cloned().unwrap_or(0)) - .into() - } } impl fmt::Display for StructInfo { @@ -333,17 +332,24 @@ mod tests { struct_info: StructInfo, } - fn fake_type_info(name: &CStr, group: TypeGroup) -> TypeInfo { + fn fake_type_info(name: &CStr, group: TypeGroup, size: u64, alignment: u32) -> TypeInfo { TypeInfo { guid: FAKE_TYPE_GUID, name: name.as_ptr(), + size_in_bits: size, + alignment, group, } } - fn fake_struct_type_info(name: &CStr, struct_info: StructInfo) -> StructTypeInfo { + fn fake_struct_type_info( + name: &CStr, + struct_info: StructInfo, + size: u64, + alignment: u32, + ) -> StructTypeInfo { StructTypeInfo { - type_info: fake_type_info(name, TypeGroup::StructTypes), + type_info: fake_type_info(name, TypeGroup::StructTypes, size, alignment), struct_info, } } @@ -358,16 +364,26 @@ mod tests { #[test] fn test_type_info_name() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); assert_eq!(type_info.name(), FAKE_TYPE_NAME); } + #[test] + fn test_type_info_size_alignment() { + let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 24, 8); + + assert_eq!(type_info.size_in_bits(), 24); + assert_eq!(type_info.size_in_bytes(), 3); + assert_eq!(type_info.alignment(), 8); + } + #[test] fn test_type_info_group_fundamental() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); let type_group = TypeGroup::FundamentalTypes; - let type_info = fake_type_info(&type_name, type_group); + let type_info = fake_type_info(&type_name, type_group, 1, 1); assert_eq!(type_info.group, type_group); assert!(type_info.group.is_fundamental()); @@ -378,7 +394,7 @@ mod tests { fn test_type_info_group_struct() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); let type_group = TypeGroup::StructTypes; - let type_info = fake_type_info(&type_name, type_group); + let type_info = fake_type_info(&type_name, type_group, 1, 1); assert_eq!(type_info.group, type_group); assert!(type_info.group.is_struct()); @@ -388,7 +404,7 @@ mod tests { #[test] fn test_type_info_eq() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); assert_eq!(type_info, type_info); } @@ -439,7 +455,7 @@ mod tests { #[test] fn test_fn_signature_arg_types_some() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let arg_types = &[&type_info]; let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); @@ -460,7 +476,7 @@ mod tests { #[test] fn test_fn_signature_return_type_some() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); @@ -474,22 +490,17 @@ mod tests { field_names: &[*const c_char], field_types: &[&TypeInfo], field_offsets: &[u16], - field_sizes: &[u16], - alignment: u16, memory_kind: StructMemoryKind, ) -> StructInfo { assert!(field_names.len() == field_types.len()); assert!(field_types.len() == field_offsets.len()); - assert!(field_offsets.len() == field_sizes.len()); StructInfo { name: name.as_ptr(), field_names: field_names.as_ptr(), field_types: field_types.as_ptr().cast::<*const TypeInfo>(), field_offsets: field_offsets.as_ptr(), - field_sizes: field_sizes.as_ptr(), num_fields: field_names.len() as u16, - alignment, memory_kind, } } @@ -499,7 +510,7 @@ mod tests { #[test] fn test_struct_info_name() { let struct_name = CString::new(FAKE_STRUCT_NAME).expect("Invalid fake struct name."); - let struct_info = fake_struct_info(&struct_name, &[], &[], &[], &[], 1, Default::default()); + let struct_info = fake_struct_info(&struct_name, &[], &[], &[], Default::default()); assert_eq!(struct_info.name(), FAKE_STRUCT_NAME); } @@ -509,44 +520,35 @@ mod tests { let field_names = &[]; let field_types = &[]; let field_offsets = &[]; - let field_sizes = &[]; let struct_name = CString::new(FAKE_STRUCT_NAME).expect("Invalid fake struct name."); let struct_info = fake_struct_info( &struct_name, field_names, field_types, field_offsets, - field_sizes, - 1, Default::default(), ); assert_eq!(struct_info.field_names().count(), 0); assert_eq!(struct_info.field_types(), field_types); assert_eq!(struct_info.field_offsets(), field_offsets); - assert_eq!(struct_info.field_sizes(), field_sizes); - assert_eq!(struct_info.size(), 0); } #[test] fn test_struct_info_fields_some() { let field_name = CString::new(FAKE_FIELD_NAME).expect("Invalid fake field name."); let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let field_names = &[field_name.as_ptr()]; let field_types = &[&type_info]; let field_offsets = &[1]; - let field_sizes = &[2]; - let alignment = 1; let struct_name = CString::new(FAKE_STRUCT_NAME).expect("Invalid fake struct name."); let struct_info = fake_struct_info( &struct_name, field_names, field_types, field_offsets, - field_sizes, - alignment, Default::default(), ); @@ -555,43 +557,13 @@ mod tests { } assert_eq!(struct_info.field_types(), field_types); assert_eq!(struct_info.field_offsets(), field_offsets); - assert_eq!(struct_info.field_sizes(), field_sizes); - assert_eq!( - struct_info.size() as u16, - field_offsets.last().unwrap() + field_sizes.last().unwrap() - ) - } - - #[test] - fn test_struct_info_alignment() { - let struct_name = CString::new(FAKE_STRUCT_NAME).expect("Invalid fake struct name."); - let struct_alignment = 4; - let struct_info = fake_struct_info( - &struct_name, - &[], - &[], - &[], - &[], - struct_alignment, - Default::default(), - ); - - assert_eq!(struct_info.alignment, struct_alignment); } #[test] fn test_struct_info_memory_kind_gc() { let struct_name = CString::new(FAKE_STRUCT_NAME).expect("Invalid fake struct name."); let struct_memory_kind = StructMemoryKind::GC; - let struct_info = fake_struct_info( - &struct_name, - &[], - &[], - &[], - &[], - 1, - struct_memory_kind.clone(), - ); + let struct_info = fake_struct_info(&struct_name, &[], &[], &[], struct_memory_kind.clone()); assert_eq!(struct_info.memory_kind, struct_memory_kind); } @@ -600,15 +572,7 @@ mod tests { fn test_struct_info_memory_kind_value() { let struct_name = CString::new(FAKE_STRUCT_NAME).expect("Invalid fake struct name."); let struct_memory_kind = StructMemoryKind::Value; - let struct_info = fake_struct_info( - &struct_name, - &[], - &[], - &[], - &[], - 1, - struct_memory_kind.clone(), - ); + let struct_info = fake_struct_info(&struct_name, &[], &[], &[], struct_memory_kind.clone()); assert_eq!(struct_info.memory_kind, struct_memory_kind); } @@ -651,7 +615,7 @@ mod tests { #[test] fn test_module_info_types_some() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); @@ -664,8 +628,8 @@ mod tests { let functions = &[fn_info]; let struct_name = CString::new(FAKE_STRUCT_NAME).expect("Invalid fake struct name"); - let struct_info = fake_struct_info(&struct_name, &[], &[], &[], &[], 1, Default::default()); - let struct_type_info = fake_struct_type_info(&struct_name, struct_info); + let struct_info = fake_struct_info(&struct_name, &[], &[], &[], Default::default()); + let struct_type_info = fake_struct_type_info(&struct_name, struct_info, 1, 1); let types = &[unsafe { mem::transmute(&struct_type_info) }]; let module_path = CString::new(FAKE_MODULE_PATH).expect("Invalid fake module path."); @@ -722,7 +686,7 @@ mod tests { #[test] fn test_dispatch_table_iter_mut_some() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); @@ -756,7 +720,7 @@ mod tests { #[test] fn test_dispatch_table_ptrs_mut_some() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); @@ -785,7 +749,7 @@ mod tests { #[test] fn test_dispatch_table_signatures_some() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); @@ -808,7 +772,7 @@ mod tests { #[test] fn test_dispatch_table_get_ptr_unchecked() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); @@ -824,7 +788,7 @@ mod tests { #[test] fn test_dispatch_table_get_ptr_none() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); @@ -840,7 +804,7 @@ mod tests { #[test] fn test_dispatch_table_get_ptr_some() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); @@ -856,7 +820,7 @@ mod tests { #[test] fn test_dispatch_table_get_ptr_unchecked_mut() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); @@ -875,7 +839,7 @@ mod tests { #[test] fn test_dispatch_table_get_ptr_mut_none() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); @@ -891,7 +855,7 @@ mod tests { #[test] fn test_dispatch_table_get_ptr_mut_some() { let type_name = CString::new(FAKE_TYPE_NAME).expect("Invalid fake type name."); - let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes); + let type_info = fake_type_info(&type_name, TypeGroup::FundamentalTypes, 1, 1); let return_type = Some(&type_info); let fn_name = CString::new(FAKE_FN_NAME).expect("Invalid fake fn name."); diff --git a/crates/mun_codegen/src/ir/abi_types.rs b/crates/mun_codegen/src/ir/abi_types.rs index cc06b71be..5c8f9fc4d 100644 --- a/crates/mun_codegen/src/ir/abi_types.rs +++ b/crates/mun_codegen/src/ir/abi_types.rs @@ -32,9 +32,11 @@ pub(crate) fn gen_abi_types(context: ContextRef) -> AbiTypes { let type_info_type = context.opaque_struct_type("struct.MunTypeInfo"); type_info_type.set_body( &[ - guid_type.into(), // guid - str_type.into(), // name - type_group_type.into(), // group + guid_type.into(), // guid + str_type.into(), // name + context.i64_type().into(), // size_in_bits + context.i32_type().into(), // alignment + type_group_type.into(), // group ], false, ); @@ -76,9 +78,7 @@ pub(crate) fn gen_abi_types(context: ContextRef) -> AbiTypes { str_type.ptr_type(AddressSpace::Const).into(), // field_names type_info_ptr_type.ptr_type(AddressSpace::Const).into(), // field_types context.i16_type().ptr_type(AddressSpace::Const).into(), // field_offsets - context.i16_type().ptr_type(AddressSpace::Const).into(), // field_sizes context.i16_type().into(), // num_fields - context.i16_type().into(), // alignment context.i8_type().into(), // memory_kind ], false, diff --git a/crates/mun_codegen/src/ir/type_table.rs b/crates/mun_codegen/src/ir/type_table.rs index dacfbd1e3..4f66bc445 100644 --- a/crates/mun_codegen/src/ir/type_table.rs +++ b/crates/mun_codegen/src/ir/type_table.rs @@ -3,7 +3,7 @@ use crate::code_gen::{ }; use crate::ir::{abi_types::AbiTypes, dispatch_table::FunctionPrototype}; use crate::type_info::{TypeGroup, TypeInfo}; -use crate::{CodeGenParams, IrDatabase}; +use crate::IrDatabase; use hir::{Body, ExprId, InferenceResult}; use inkwell::{ module::Module, @@ -177,6 +177,14 @@ impl<'a, D: IrDatabase> TypeTableBuilder<'a, D> { &format!("type_info::<{}>::name", type_info.name), ) .into(), + context + .i64_type() + .const_int(type_info.size.bit_size, false) + .into(), + context + .i32_type() + .const_int(type_info.size.alignment as u64, false) + .into(), context .i8_type() .const_int(type_info.group.clone().into(), false) @@ -247,37 +255,16 @@ impl<'a, D: IrDatabase> TypeTableBuilder<'a, D> { &format!("struct_info::<{}>::field_offsets", name), ); - let field_sizes = gen_u16_array( - self.module, - fields.iter().map(|field| { - self.target_data.get_store_size(&self.db.type_ir( - field.ty(self.db), - CodeGenParams { - make_marshallable: false, - }, - )) - }), - &format!("struct_info::<{}>::field_sizes", name), - ); - - let alignment = self.target_data.get_abi_alignment(&struct_ir); - self.abi_types.struct_info_type.const_named_struct(&[ name_str.into(), field_names.into(), field_types.into(), field_offsets.into(), - field_sizes.into(), self.module .get_context() .i16_type() .const_int(fields.len() as u64, false) .into(), - self.module - .get_context() - .i16_type() - .const_int(alignment.into(), false) - .into(), self.module .get_context() .i8_type() diff --git a/crates/mun_codegen/src/snapshots/test__field_crash.snap b/crates/mun_codegen/src/snapshots/test__field_crash.snap index 3e2932a97..161cf4c4d 100644 --- a/crates/mun_codegen/src/snapshots/test__field_crash.snap +++ b/crates/mun_codegen/src/snapshots/test__field_crash.snap @@ -6,8 +6,8 @@ expression: "struct(gc) Foo { a: int };\n\nfn main(c:int):int {\n let b = Foo source_filename = "main.mun" target triple = "x86-64" -%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i8 } -%struct.MunStructInfo = type { i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16 addrspace(4)*, i16, i16, i8 } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i64, i32, i8 } +%struct.MunStructInfo = type { i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } %DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)*, i8* addrspace(4)* (i8 addrspace(4)*, i8*)* } %Foo = type { i64 } @@ -16,19 +16,18 @@ target triple = "x86-64" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @0 = private unnamed_addr constant [1 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names"] @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i64 64, i32 8, i8 0 } @"struct_info::::field_types" = private unnamed_addr constant [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] @"struct_info::::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer -@"struct_info::::field_sizes" = private unnamed_addr constant [1 x i16] [i16 8] -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", [1 x i16]* @"struct_info::::field_sizes", i16 1, i16 8, i8 0 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i64 64, i32 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", i16 1, i8 0 } } @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00" -@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i8 0 } +@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i64 64, i32 8, i8 0 } @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00" -@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i8 0 } +@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i64 64, i32 8, i8 0 } @"type_info::<*const core::void>::name" = private unnamed_addr constant [18 x i8] c"*const core::void\00" -@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i8 0 } +@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i64 64, i32 8, i8 0 } @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" -@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i8 0 } +@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i64 64, i32 8, i8 0 } @global_type_table = private unnamed_addr constant [6 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>"] @dispatchTable = global %DispatchTable zeroinitializer @allocatorHandle = private unnamed_addr global i8* null diff --git a/crates/mun_codegen/src/snapshots/test__field_expr.snap b/crates/mun_codegen/src/snapshots/test__field_expr.snap index 918dc8f80..b9070875d 100644 --- a/crates/mun_codegen/src/snapshots/test__field_expr.snap +++ b/crates/mun_codegen/src/snapshots/test__field_expr.snap @@ -6,8 +6,8 @@ expression: "struct(value) Bar(float, Foo);\nstruct(value) Foo { a: int };\n\nfn source_filename = "main.mun" target triple = "x86-64" -%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i8 } -%struct.MunStructInfo = type { i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16 addrspace(4)*, i16, i16, i8 } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i64, i32, i8 } +%struct.MunStructInfo = type { i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } %DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)*, i8* addrspace(4)* (i8 addrspace(4)*, i8*)*, i64 (%Foo)*, %Foo (%Bar)* } %Foo = type { i64 } %Bar = type { double, %Foo } @@ -17,17 +17,16 @@ target triple = "x86-64" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @0 = private unnamed_addr constant [1 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names"] @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i64 64, i32 8, i8 0 } @"struct_info::::field_types" = private unnamed_addr constant [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] @"struct_info::::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer -@"struct_info::::field_sizes" = private unnamed_addr constant [1 x i16] [i16 8] -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", [1 x i16]* @"struct_info::::field_sizes", i16 1, i16 8, i8 1 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i64 64, i32 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", i16 1, i8 1 } } @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00" -@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i8 0 } +@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i64 64, i32 8, i8 0 } @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::f64\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i64 64, i32 8, i8 0 } @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00" -@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i8 0 } +@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i64 64, i32 8, i8 0 } @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Bar\00" @"struct_info::::name" = private unnamed_addr constant [4 x i8] c"Bar\00" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"0\00" @@ -35,12 +34,11 @@ target triple = "x86-64" @1 = private unnamed_addr constant [2 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names", i8 addrspace(4)* @"struct_info::::field_names.1"] @"struct_info::::field_types" = private unnamed_addr constant [2 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::"] @"struct_info::::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 8] -@"struct_info::::field_sizes" = private unnamed_addr constant [2 x i16] [i16 8, i16 8] -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\DD\C3_\88\FAq\B6\EF\14*\E6\1F56FS", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [2 x i8 addrspace(4)*]* @1, [2 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [2 x i16]* @"struct_info::::field_offsets", [2 x i16]* @"struct_info::::field_sizes", i16 2, i16 8, i8 1 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\DD\C3_\88\FAq\B6\EF\14*\E6\1F56FS", [4 x i8]* @"type_info::::name", i64 128, i32 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [2 x i8 addrspace(4)*]* @1, [2 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [2 x i16]* @"struct_info::::field_offsets", i16 2, i8 1 } } @"type_info::<*const core::void>::name" = private unnamed_addr constant [18 x i8] c"*const core::void\00" -@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i8 0 } +@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i64 64, i32 8, i8 0 } @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" -@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i8 0 } +@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i64 64, i32 8, i8 0 } @global_type_table = private unnamed_addr constant [8 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>"] @dispatchTable = global %DispatchTable { i8* addrspace(4)* (i8 addrspace(4)*, i8*)* null, i8* addrspace(4)* (i8 addrspace(4)*, i8*)* null, i64 (%Foo)* @foo_a, %Foo (%Bar)* @bar_1 } @allocatorHandle = private unnamed_addr global i8* null diff --git a/crates/mun_codegen/src/snapshots/test__gc_struct.snap b/crates/mun_codegen/src/snapshots/test__gc_struct.snap index 116859641..50d8201b8 100644 --- a/crates/mun_codegen/src/snapshots/test__gc_struct.snap +++ b/crates/mun_codegen/src/snapshots/test__gc_struct.snap @@ -6,8 +6,8 @@ expression: "struct(gc) Foo { a: int, b: int };\n\nfn foo() {\n let a = Foo { source_filename = "main.mun" target triple = "x86-64" -%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i8 } -%struct.MunStructInfo = type { i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16 addrspace(4)*, i16, i16, i8 } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i64, i32, i8 } +%struct.MunStructInfo = type { i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } %DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)*, i8* addrspace(4)* (i8 addrspace(4)*, i8*)* } %Foo = type { i64, i64 } @@ -17,19 +17,18 @@ target triple = "x86-64" @"struct_info::::field_names.1" = private unnamed_addr constant [2 x i8] c"b\00" @0 = private unnamed_addr constant [2 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names", i8 addrspace(4)* @"struct_info::::field_names.1"] @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i64 64, i32 8, i8 0 } @"struct_info::::field_types" = private unnamed_addr constant [2 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::"] @"struct_info::::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 8] -@"struct_info::::field_sizes" = private unnamed_addr constant [2 x i16] [i16 8, i16 8] -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [2 x i8 addrspace(4)*]* @0, [2 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [2 x i16]* @"struct_info::::field_offsets", [2 x i16]* @"struct_info::::field_sizes", i16 2, i16 8, i8 0 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i64 128, i32 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [2 x i8 addrspace(4)*]* @0, [2 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [2 x i16]* @"struct_info::::field_offsets", i16 2, i8 0 } } @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00" -@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i8 0 } +@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i64 64, i32 8, i8 0 } @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00" -@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i8 0 } +@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i64 64, i32 8, i8 0 } @"type_info::<*const core::void>::name" = private unnamed_addr constant [18 x i8] c"*const core::void\00" -@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i8 0 } +@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i64 64, i32 8, i8 0 } @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" -@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i8 0 } +@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i64 64, i32 8, i8 0 } @global_type_table = private unnamed_addr constant [6 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>"] @dispatchTable = global %DispatchTable zeroinitializer @allocatorHandle = private unnamed_addr global i8* null diff --git a/crates/mun_codegen/src/snapshots/test__struct_test.snap b/crates/mun_codegen/src/snapshots/test__struct_test.snap index cb679ff6d..a660b62b6 100644 --- a/crates/mun_codegen/src/snapshots/test__struct_test.snap +++ b/crates/mun_codegen/src/snapshots/test__struct_test.snap @@ -6,8 +6,8 @@ expression: "struct(value) Bar(float, int, bool, Foo);\nstruct(value) Foo { a: i source_filename = "main.mun" target triple = "x86-64" -%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i8 } -%struct.MunStructInfo = type { i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16 addrspace(4)*, i16, i16, i8 } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i64, i32, i8 } +%struct.MunStructInfo = type { i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } %DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)*, i8* addrspace(4)* (i8 addrspace(4)*, i8*)* } %Baz = type {} %Bar = type { double, i64, i1, %Foo } @@ -18,19 +18,18 @@ target triple = "x86-64" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @0 = private unnamed_addr constant [1 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names"] @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i64 64, i32 8, i8 0 } @"struct_info::::field_types" = private unnamed_addr constant [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] @"struct_info::::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer -@"struct_info::::field_sizes" = private unnamed_addr constant [1 x i16] [i16 8] -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", [1 x i16]* @"struct_info::::field_sizes", i16 1, i16 8, i8 1 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i64 64, i32 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", i16 1, i8 1 } } @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00" -@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i8 0 } +@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i64 64, i32 8, i8 0 } @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::f64\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i64 64, i32 8, i8 0 } @"type_info::::name" = private unnamed_addr constant [11 x i8] c"core::bool\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [11 x i8]* @"type_info::::name", i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [11 x i8]* @"type_info::::name", i64 1, i32 1, i8 0 } @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00" -@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i8 0 } +@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i64 64, i32 8, i8 0 } @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Bar\00" @"struct_info::::name" = private unnamed_addr constant [4 x i8] c"Bar\00" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"0\00" @@ -40,15 +39,14 @@ target triple = "x86-64" @1 = private unnamed_addr constant [4 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names", i8 addrspace(4)* @"struct_info::::field_names.1", i8 addrspace(4)* @"struct_info::::field_names.2", i8 addrspace(4)* @"struct_info::::field_names.3"] @"struct_info::::field_types" = private unnamed_addr constant [4 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::"] @"struct_info::::field_offsets" = private unnamed_addr constant [4 x i16] [i16 0, i16 8, i16 16, i16 24] -@"struct_info::::field_sizes" = private unnamed_addr constant [4 x i16] [i16 8, i16 8, i16 1, i16 8] -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\DD\C3_\88\FAq\B6\EF\14*\E6\1F56FS", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [4 x i8 addrspace(4)*]* @1, [4 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [4 x i16]* @"struct_info::::field_offsets", [4 x i16]* @"struct_info::::field_sizes", i16 4, i16 8, i8 1 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\DD\C3_\88\FAq\B6\EF\14*\E6\1F56FS", [4 x i8]* @"type_info::::name", i64 256, i32 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [4 x i8 addrspace(4)*]* @1, [4 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [4 x i16]* @"struct_info::::field_offsets", i16 4, i8 1 } } @"type_info::<*const core::void>::name" = private unnamed_addr constant [18 x i8] c"*const core::void\00" -@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i8 0 } +@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i64 64, i32 8, i8 0 } @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" -@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i8 0 } +@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i64 64, i32 8, i8 0 } @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Baz\00" @"struct_info::::name" = private unnamed_addr constant [4 x i8] c"Baz\00" -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\F8\DC\E6\7F,\948\82\82\ED?\A7\97\96\8A|", [4 x i8]* @"type_info::::name", i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", i8 addrspace(4)* addrspace(4)* null, %struct.MunTypeInfo addrspace(4)* addrspace(4)* null, i16 addrspace(4)* null, i16 addrspace(4)* null, i16 0, i16 1, i8 1 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\F8\DC\E6\7F,\948\82\82\ED?\A7\97\96\8A|", [4 x i8]* @"type_info::::name", i64 0, i32 1, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", i8 addrspace(4)* addrspace(4)* null, %struct.MunTypeInfo addrspace(4)* addrspace(4)* null, i16 addrspace(4)* null, i16 0, i8 1 } } @global_type_table = private unnamed_addr constant [10 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::"] @dispatchTable = global %DispatchTable zeroinitializer @allocatorHandle = private unnamed_addr global i8* null diff --git a/crates/mun_runtime/src/allocator.rs b/crates/mun_runtime/src/allocator.rs index af6f2f8f2..4f0accbf1 100644 --- a/crates/mun_runtime/src/allocator.rs +++ b/crates/mun_runtime/src/allocator.rs @@ -39,9 +39,12 @@ impl Allocator { /// `type_info` must be a valid pointer and remain valid throughout the lifetime of the created /// object. pub(crate) unsafe fn create_object(&self, type_info: *const abi::TypeInfo) -> ObjectHandle { - let struct_info = type_info.as_ref().unwrap().as_struct().unwrap(); + let type_info = type_info.as_ref().unwrap(); - let ptr = self.alloc(struct_info.size() as u64, struct_info.alignment.into()); + let ptr = self.alloc( + type_info.size_in_bytes() as u64, + type_info.alignment().into(), + ); let object = Box::pin(ObjectInfo { ptr, type_info }); // We want to return a pointer to the `ObjectInfo`, to be used as handle. @@ -66,11 +69,10 @@ impl Allocator { .unwrap_or_else(|| panic!("Object with handle '{:?}' does not exist.", src)); let type_info = src.type_info.as_ref().unwrap(); - let struct_info = type_info.as_struct().unwrap(); - let size = struct_info.size(); - let dest = self.alloc(size as u64, struct_info.alignment.into()); - ptr::copy_nonoverlapping(src.ptr, dest, size); + let size = type_info.size_in_bytes(); + let dest = self.alloc(size as u64, type_info.alignment() as u64); + ptr::copy_nonoverlapping(src.ptr, dest, size as usize); Box::pin(ObjectInfo { ptr: dest, diff --git a/crates/mun_runtime/src/struct.rs b/crates/mun_runtime/src/struct.rs index 58a834a56..21064812a 100644 --- a/crates/mun_runtime/src/struct.rs +++ b/crates/mun_runtime/src/struct.rs @@ -184,8 +184,8 @@ impl Marshal for RawStruct { let src = ptr.cast::().as_ptr() as *const _; let dest = unsafe { handle.as_ref() }.unwrap().ptr; - let size = struct_info.size(); - unsafe { ptr::copy_nonoverlapping(src, dest, size) }; + let size = type_info.size_in_bytes(); + unsafe { ptr::copy_nonoverlapping(src, dest, size as usize) }; handle } else { @@ -208,8 +208,7 @@ impl Marshal for RawStruct { let struct_info = type_info.as_struct().unwrap(); if struct_info.memory_kind == abi::StructMemoryKind::Value { let dest = ptr.cast::().as_ptr(); - let size = struct_info.field_offsets().last().cloned().unwrap_or(0) - + struct_info.field_sizes().last().cloned().unwrap_or(0); + let size = type_info.size_in_bytes(); unsafe { ptr::copy_nonoverlapping(value.get_ptr(), dest, size as usize) }; } else { unsafe { *ptr.as_mut() = value }; diff --git a/crates/mun_runtime/src/type_info.rs b/crates/mun_runtime/src/type_info.rs index d8145b85b..175977454 100644 --- a/crates/mun_runtime/src/type_info.rs +++ b/crates/mun_runtime/src/type_info.rs @@ -50,8 +50,8 @@ impl HasStaticTypeInfo for *const T { guid, name: name_ptr, group: abi::TypeGroup::FundamentalTypes, - // size: std::mem::size_of::<*const T>() as u64, - // alignment: std::mem::align_of::<*const T>() as u32, + size_in_bits: std::mem::size_of::<*const T>() as u64 * 8, + alignment: std::mem::align_of::<*const T>() as u32, }, ) }) @@ -84,8 +84,8 @@ impl HasStaticTypeInfo for *mut T { guid, name: name_ptr, group: abi::TypeGroup::FundamentalTypes, - // size: std::mem::size_of::<*const T>() as u64, - // alignment: std::mem::align_of::<*const T>() as u32, + size_in_bits: std::mem::size_of::<*const T>() as u64 * 8, + alignment: std::mem::align_of::<*const T>() as u32, }, ) }) @@ -110,8 +110,8 @@ macro_rules! impl_basic_type_info { guid: abi::Guid{ b: md5::compute(&type_info_name.as_bytes()).0 }, name: type_info_name.as_ptr(), group: abi::TypeGroup::FundamentalTypes, - // size: std::mem::size_of::<$ty>() as u64, - // alignment: std::mem::align_of::<$ty>() as u32, + size_in_bits: std::mem::size_of::<$ty>() as u64 * 8, + alignment: std::mem::align_of::<$ty>() as u32, } }) } diff --git a/crates/mun_runtime_capi/ffi b/crates/mun_runtime_capi/ffi index 5c8770e76..df873262d 160000 --- a/crates/mun_runtime_capi/ffi +++ b/crates/mun_runtime_capi/ffi @@ -1 +1 @@ -Subproject commit 5c8770e76ec0a68eafd61949a6fc18b547a73a83 +Subproject commit df873262d81d9dcbccdc3048a9aa5f88a1c86ae1 diff --git a/crates/tools/src/abi.rs b/crates/tools/src/abi.rs index 184934358..3f1939f35 100644 --- a/crates/tools/src/abi.rs +++ b/crates/tools/src/abi.rs @@ -52,6 +52,7 @@ pub fn generate(mode: Mode) -> Result<()> { .blacklist_type("__uint8_t") .blacklist_type("__uint16_t") .blacklist_type("__uint32_t") + .blacklist_type("__uint64_t") .parse_callbacks(Box::new(RemoveVendorName)) // FIXME: Prevent double derivation of Copy and Debug attributes on Windows .derive_copy(false) From 3fcf8e2f61a0ae9b9ce71368e178dbfb224fd0ea Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Fri, 20 Mar 2020 13:25:06 +0100 Subject: [PATCH 06/12] fix: the static_type_map crate can fail because its not thread safe --- crates/mun_runtime/Cargo.toml | 1 - crates/mun_runtime/src/lib.rs | 1 + crates/mun_runtime/src/static_type_map.rs | 55 +++++++++++++++++++++++ crates/mun_runtime/src/type_info.rs | 2 +- 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 crates/mun_runtime/src/static_type_map.rs diff --git a/crates/mun_runtime/Cargo.toml b/crates/mun_runtime/Cargo.toml index d275bde2e..1fadb6300 100644 --- a/crates/mun_runtime/Cargo.toml +++ b/crates/mun_runtime/Cargo.toml @@ -17,7 +17,6 @@ notify = "4.0.12" parking_lot = "0.9" tempfile = "3" once_cell = "1.3.1" -generic_static = "0.1" [dev-dependencies] mun_compiler = { path="../mun_compiler" } diff --git a/crates/mun_runtime/src/lib.rs b/crates/mun_runtime/src/lib.rs index 92cec950a..d4e83ef31 100644 --- a/crates/mun_runtime/src/lib.rs +++ b/crates/mun_runtime/src/lib.rs @@ -11,6 +11,7 @@ mod macros; mod allocator; mod marshal; mod reflection; +mod static_type_map; mod r#struct; #[macro_use] diff --git a/crates/mun_runtime/src/static_type_map.rs b/crates/mun_runtime/src/static_type_map.rs new file mode 100644 index 000000000..112f542bf --- /dev/null +++ b/crates/mun_runtime/src/static_type_map.rs @@ -0,0 +1,55 @@ +use std::any::TypeId; +use std::collections::HashMap; +use std::sync::RwLock; + +pub struct StaticTypeMap { + map: RwLock>, +} + +impl StaticTypeMap { + pub fn new() -> Self { + Self { + map: RwLock::new(HashMap::new()), + } + } + + /// Initialize static value corresponding to provided type. + /// + /// Initialized value will stay on heap until program terminated. + /// No drop method will be called. + pub fn call_once(&'static self, f: Init) -> &'static T + where + Type: 'static, + Init: FnOnce() -> T, + { + // If already initialized, just return stored value + { + let reader = self.map.read().unwrap(); + if let Some(ref reference) = reader.get(&TypeId::of::()) { + return &reference; + } + } + + // Construct new value and put inside map allocate value on heap + let boxed = Box::new(f()); + + // Get exclusive access + let mut writer = self.map.write().unwrap(); + + // Recheck because maybe we are the second writer and the previous writer inserted the + // value. + if let Some(ref reference) = writer.get(&TypeId::of::()) { + return &reference; + } + + // leak it's value until program is terminated + let reference: &'static T = Box::leak(boxed); + + // Insert the value into the map + let old = writer.insert(TypeId::of::(), reference); + if old.is_some() { + panic!("StaticTypeMap value was reinitialized. This is a bug.") + } + reference + } +} diff --git a/crates/mun_runtime/src/type_info.rs b/crates/mun_runtime/src/type_info.rs index 175977454..ab618b0a2 100644 --- a/crates/mun_runtime/src/type_info.rs +++ b/crates/mun_runtime/src/type_info.rs @@ -1,4 +1,4 @@ -use generic_static::StaticTypeMap; +use super::static_type_map::StaticTypeMap; use once_cell::sync::OnceCell; use std::ffi::{CStr, CString}; use std::sync::Once; From 071c19d6f41cdc8d1519a484255946c4a21c4edc Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Sat, 21 Mar 2020 12:33:07 +0100 Subject: [PATCH 07/12] misc: changed to u32 and alignment to u8 to save space --- crates/mun_abi/c | 2 +- crates/mun_abi/src/autogen.rs | 10 ++++---- crates/mun_abi/src/autogen_impl.rs | 18 ++++++------- crates/mun_codegen/src/ir/abi_types.rs | 4 +-- crates/mun_codegen/src/ir/intrinsics.rs | 6 ++++- crates/mun_codegen/src/ir/type_table.rs | 4 +-- .../src/snapshots/test__field_crash.snap | 14 +++++------ .../src/snapshots/test__field_expr.snap | 18 ++++++------- .../src/snapshots/test__gc_struct.snap | 14 +++++------ .../src/snapshots/test__struct_test.snap | 22 ++++++++-------- crates/mun_runtime/src/allocator.rs | 9 +++---- crates/mun_runtime/src/type_info.rs | 25 ++++++++++++++----- crates/mun_runtime_capi/ffi | 2 +- 13 files changed, 81 insertions(+), 67 deletions(-) diff --git a/crates/mun_abi/c b/crates/mun_abi/c index b8ead3779..986c49fb3 160000 --- a/crates/mun_abi/c +++ b/crates/mun_abi/c @@ -1 +1 @@ -Subproject commit b8ead37791c40f9c8b84380fb0f6dc3b50321b7c +Subproject commit 986c49fb3c9d1e45ad6ce74ea9e76ab0a52c6bd2 diff --git a/crates/mun_abi/src/autogen.rs b/crates/mun_abi/src/autogen.rs index f54ed93de..ef7091691 100644 --- a/crates/mun_abi/src/autogen.rs +++ b/crates/mun_abi/src/autogen.rs @@ -47,9 +47,9 @@ pub struct TypeInfo { #[doc = " Type name"] pub name: *const ::std::os::raw::c_char, #[doc = " The exact size of the type in bits without any padding"] - pub size_in_bits: u64, + pub size_in_bits: u32, #[doc = " The alignment of the type"] - pub alignment: u32, + pub alignment: u8, #[doc = " Type group"] pub group: TypeGroup, } @@ -57,7 +57,7 @@ pub struct TypeInfo { fn bindgen_test_layout_TypeInfo() { assert_eq!( ::std::mem::size_of::(), - 40usize, + 32usize, concat!("Size of: ", stringify!(TypeInfo)) ); assert_eq!( @@ -97,7 +97,7 @@ fn bindgen_test_layout_TypeInfo() { ); assert_eq!( unsafe { &(*(::std::ptr::null::())).alignment as *const _ as usize }, - 32usize, + 28usize, concat!( "Offset of field: ", stringify!(TypeInfo), @@ -107,7 +107,7 @@ fn bindgen_test_layout_TypeInfo() { ); assert_eq!( unsafe { &(*(::std::ptr::null::())).group as *const _ as usize }, - 36usize, + 29usize, concat!( "Offset of field: ", stringify!(TypeInfo), diff --git a/crates/mun_abi/src/autogen_impl.rs b/crates/mun_abi/src/autogen_impl.rs index 8c40e42a8..c912a5d01 100644 --- a/crates/mun_abi/src/autogen_impl.rs +++ b/crates/mun_abi/src/autogen_impl.rs @@ -27,18 +27,18 @@ impl TypeInfo { } /// Returns the size of the type in bits - pub fn size_in_bits(&self) -> u64 { - self.size_in_bits + pub fn size_in_bits(&self) -> usize { + self.size_in_bits as usize } /// Returns the size of the type in bytes - pub fn size_in_bytes(&self) -> u64 { - (self.size_in_bits + 7) / 8 + pub fn size_in_bytes(&self) -> usize { + ((self.size_in_bits + 7) / 8) as usize } /// Returns the alignment of the type in bytes - pub fn alignment(&self) -> u32 { - self.alignment + pub fn alignment(&self) -> usize { + self.alignment as usize } } @@ -332,7 +332,7 @@ mod tests { struct_info: StructInfo, } - fn fake_type_info(name: &CStr, group: TypeGroup, size: u64, alignment: u32) -> TypeInfo { + fn fake_type_info(name: &CStr, group: TypeGroup, size: u32, alignment: u8) -> TypeInfo { TypeInfo { guid: FAKE_TYPE_GUID, name: name.as_ptr(), @@ -345,8 +345,8 @@ mod tests { fn fake_struct_type_info( name: &CStr, struct_info: StructInfo, - size: u64, - alignment: u32, + size: u32, + alignment: u8, ) -> StructTypeInfo { StructTypeInfo { type_info: fake_type_info(name, TypeGroup::StructTypes, size, alignment), diff --git a/crates/mun_codegen/src/ir/abi_types.rs b/crates/mun_codegen/src/ir/abi_types.rs index 5c8f9fc4d..de6e0a53d 100644 --- a/crates/mun_codegen/src/ir/abi_types.rs +++ b/crates/mun_codegen/src/ir/abi_types.rs @@ -34,8 +34,8 @@ pub(crate) fn gen_abi_types(context: ContextRef) -> AbiTypes { &[ guid_type.into(), // guid str_type.into(), // name - context.i64_type().into(), // size_in_bits - context.i32_type().into(), // alignment + context.i32_type().into(), // size_in_bits + context.i8_type().into(), // alignment type_group_type.into(), // group ], false, diff --git a/crates/mun_codegen/src/ir/intrinsics.rs b/crates/mun_codegen/src/ir/intrinsics.rs index f6062c643..6119686a6 100644 --- a/crates/mun_codegen/src/ir/intrinsics.rs +++ b/crates/mun_codegen/src/ir/intrinsics.rs @@ -95,7 +95,11 @@ pub fn collect_fn_body( ); } -pub fn collect_wrapper_body(db: &D, entries: &mut IntrinsicsMap, needs_alloc: &mut bool) { +pub fn collect_wrapper_body( + db: &D, + entries: &mut IntrinsicsMap, + needs_alloc: &mut bool, +) { collect_intrinsic(db, entries, &intrinsics::new); collect_intrinsic(db, entries, &intrinsics::clone); // self.collect_intrinsic(entries, &intrinsics::drop, module); diff --git a/crates/mun_codegen/src/ir/type_table.rs b/crates/mun_codegen/src/ir/type_table.rs index 4f66bc445..b1899bee2 100644 --- a/crates/mun_codegen/src/ir/type_table.rs +++ b/crates/mun_codegen/src/ir/type_table.rs @@ -178,11 +178,11 @@ impl<'a, D: IrDatabase> TypeTableBuilder<'a, D> { ) .into(), context - .i64_type() + .i32_type() .const_int(type_info.size.bit_size, false) .into(), context - .i32_type() + .i8_type() .const_int(type_info.size.alignment as u64, false) .into(), context diff --git a/crates/mun_codegen/src/snapshots/test__field_crash.snap b/crates/mun_codegen/src/snapshots/test__field_crash.snap index 161cf4c4d..093e4c0ed 100644 --- a/crates/mun_codegen/src/snapshots/test__field_crash.snap +++ b/crates/mun_codegen/src/snapshots/test__field_crash.snap @@ -6,7 +6,7 @@ expression: "struct(gc) Foo { a: int };\n\nfn main(c:int):int {\n let b = Foo source_filename = "main.mun" target triple = "x86-64" -%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i64, i32, i8 } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } %struct.MunStructInfo = type { i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } %DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)*, i8* addrspace(4)* (i8 addrspace(4)*, i8*)* } %Foo = type { i64 } @@ -16,18 +16,18 @@ target triple = "x86-64" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @0 = private unnamed_addr constant [1 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names"] @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i64 64, i32 8, i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } @"struct_info::::field_types" = private unnamed_addr constant [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] @"struct_info::::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i64 64, i32 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", i16 1, i8 0 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i32 64, i8 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", i16 1, i8 0 } } @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00" -@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i64 64, i32 8, i8 0 } +@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 64, i8 8, i8 0 } @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00" -@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i64 64, i32 8, i8 0 } +@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 64, i8 8, i8 0 } @"type_info::<*const core::void>::name" = private unnamed_addr constant [18 x i8] c"*const core::void\00" -@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i64 64, i32 8, i8 0 } +@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i32 64, i8 8, i8 0 } @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" -@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i64 64, i32 8, i8 0 } +@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i32 64, i8 8, i8 0 } @global_type_table = private unnamed_addr constant [6 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>"] @dispatchTable = global %DispatchTable zeroinitializer @allocatorHandle = private unnamed_addr global i8* null diff --git a/crates/mun_codegen/src/snapshots/test__field_expr.snap b/crates/mun_codegen/src/snapshots/test__field_expr.snap index b9070875d..a5144ddf1 100644 --- a/crates/mun_codegen/src/snapshots/test__field_expr.snap +++ b/crates/mun_codegen/src/snapshots/test__field_expr.snap @@ -6,7 +6,7 @@ expression: "struct(value) Bar(float, Foo);\nstruct(value) Foo { a: int };\n\nfn source_filename = "main.mun" target triple = "x86-64" -%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i64, i32, i8 } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } %struct.MunStructInfo = type { i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } %DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)*, i8* addrspace(4)* (i8 addrspace(4)*, i8*)*, i64 (%Foo)*, %Foo (%Bar)* } %Foo = type { i64 } @@ -17,16 +17,16 @@ target triple = "x86-64" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @0 = private unnamed_addr constant [1 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names"] @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i64 64, i32 8, i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } @"struct_info::::field_types" = private unnamed_addr constant [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] @"struct_info::::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i64 64, i32 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", i16 1, i8 1 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i32 64, i8 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", i16 1, i8 1 } } @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00" -@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i64 64, i32 8, i8 0 } +@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 64, i8 8, i8 0 } @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::f64\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i64 64, i32 8, i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00" -@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i64 64, i32 8, i8 0 } +@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 64, i8 8, i8 0 } @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Bar\00" @"struct_info::::name" = private unnamed_addr constant [4 x i8] c"Bar\00" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"0\00" @@ -34,11 +34,11 @@ target triple = "x86-64" @1 = private unnamed_addr constant [2 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names", i8 addrspace(4)* @"struct_info::::field_names.1"] @"struct_info::::field_types" = private unnamed_addr constant [2 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::"] @"struct_info::::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 8] -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\DD\C3_\88\FAq\B6\EF\14*\E6\1F56FS", [4 x i8]* @"type_info::::name", i64 128, i32 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [2 x i8 addrspace(4)*]* @1, [2 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [2 x i16]* @"struct_info::::field_offsets", i16 2, i8 1 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\DD\C3_\88\FAq\B6\EF\14*\E6\1F56FS", [4 x i8]* @"type_info::::name", i32 128, i8 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [2 x i8 addrspace(4)*]* @1, [2 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [2 x i16]* @"struct_info::::field_offsets", i16 2, i8 1 } } @"type_info::<*const core::void>::name" = private unnamed_addr constant [18 x i8] c"*const core::void\00" -@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i64 64, i32 8, i8 0 } +@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i32 64, i8 8, i8 0 } @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" -@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i64 64, i32 8, i8 0 } +@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i32 64, i8 8, i8 0 } @global_type_table = private unnamed_addr constant [8 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>"] @dispatchTable = global %DispatchTable { i8* addrspace(4)* (i8 addrspace(4)*, i8*)* null, i8* addrspace(4)* (i8 addrspace(4)*, i8*)* null, i64 (%Foo)* @foo_a, %Foo (%Bar)* @bar_1 } @allocatorHandle = private unnamed_addr global i8* null diff --git a/crates/mun_codegen/src/snapshots/test__gc_struct.snap b/crates/mun_codegen/src/snapshots/test__gc_struct.snap index 50d8201b8..f737ba888 100644 --- a/crates/mun_codegen/src/snapshots/test__gc_struct.snap +++ b/crates/mun_codegen/src/snapshots/test__gc_struct.snap @@ -6,7 +6,7 @@ expression: "struct(gc) Foo { a: int, b: int };\n\nfn foo() {\n let a = Foo { source_filename = "main.mun" target triple = "x86-64" -%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i64, i32, i8 } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } %struct.MunStructInfo = type { i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } %DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)*, i8* addrspace(4)* (i8 addrspace(4)*, i8*)* } %Foo = type { i64, i64 } @@ -17,18 +17,18 @@ target triple = "x86-64" @"struct_info::::field_names.1" = private unnamed_addr constant [2 x i8] c"b\00" @0 = private unnamed_addr constant [2 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names", i8 addrspace(4)* @"struct_info::::field_names.1"] @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i64 64, i32 8, i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } @"struct_info::::field_types" = private unnamed_addr constant [2 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::"] @"struct_info::::field_offsets" = private unnamed_addr constant [2 x i16] [i16 0, i16 8] -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i64 128, i32 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [2 x i8 addrspace(4)*]* @0, [2 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [2 x i16]* @"struct_info::::field_offsets", i16 2, i8 0 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i32 128, i8 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [2 x i8 addrspace(4)*]* @0, [2 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [2 x i16]* @"struct_info::::field_offsets", i16 2, i8 0 } } @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00" -@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i64 64, i32 8, i8 0 } +@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 64, i8 8, i8 0 } @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00" -@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i64 64, i32 8, i8 0 } +@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 64, i8 8, i8 0 } @"type_info::<*const core::void>::name" = private unnamed_addr constant [18 x i8] c"*const core::void\00" -@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i64 64, i32 8, i8 0 } +@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i32 64, i8 8, i8 0 } @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" -@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i64 64, i32 8, i8 0 } +@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i32 64, i8 8, i8 0 } @global_type_table = private unnamed_addr constant [6 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>"] @dispatchTable = global %DispatchTable zeroinitializer @allocatorHandle = private unnamed_addr global i8* null diff --git a/crates/mun_codegen/src/snapshots/test__struct_test.snap b/crates/mun_codegen/src/snapshots/test__struct_test.snap index a660b62b6..f3dd5a4b8 100644 --- a/crates/mun_codegen/src/snapshots/test__struct_test.snap +++ b/crates/mun_codegen/src/snapshots/test__struct_test.snap @@ -6,7 +6,7 @@ expression: "struct(value) Bar(float, int, bool, Foo);\nstruct(value) Foo { a: i source_filename = "main.mun" target triple = "x86-64" -%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i64, i32, i8 } +%struct.MunTypeInfo = type { [16 x i8], i8 addrspace(4)*, i32, i8, i8 } %struct.MunStructInfo = type { i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)*, %struct.MunTypeInfo addrspace(4)* addrspace(4)*, i16 addrspace(4)*, i16, i8 } %DispatchTable = type { i8* addrspace(4)* (i8 addrspace(4)*, i8*)*, i8* addrspace(4)* (i8 addrspace(4)*, i8*)* } %Baz = type {} @@ -18,18 +18,18 @@ target triple = "x86-64" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"a\00" @0 = private unnamed_addr constant [1 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names"] @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::i64\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i64 64, i32 8, i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"G\13;t\97j8\18\D7M\83`\1D\C8\19%", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } @"struct_info::::field_types" = private unnamed_addr constant [1 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::"] @"struct_info::::field_offsets" = private unnamed_addr constant [1 x i16] zeroinitializer -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i64 64, i32 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", i16 1, i8 1 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\13V\C6}z\D1c\8D\81k\FB\82-\D2\C2]", [4 x i8]* @"type_info::::name", i32 64, i8 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [1 x i8 addrspace(4)*]* @0, [1 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [1 x i16]* @"struct_info::::field_offsets", i16 1, i8 1 } } @"type_info::<*const TypeInfo>::name" = private unnamed_addr constant [16 x i8] c"*const TypeInfo\00" -@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i64 64, i32 8, i8 0 } +@"type_info::<*const TypeInfo>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"=\A1-\1F\C2\A7\88`d\90\F4\B5\BEE}x", [16 x i8]* @"type_info::<*const TypeInfo>::name", i32 64, i8 8, i8 0 } @"type_info::::name" = private unnamed_addr constant [10 x i8] c"core::f64\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i64 64, i32 8, i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"`\DBF\9C?YJ%G\AD4\9F\D5\92%A", [10 x i8]* @"type_info::::name", i32 64, i8 8, i8 0 } @"type_info::::name" = private unnamed_addr constant [11 x i8] c"core::bool\00" -@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [11 x i8]* @"type_info::::name", i64 1, i32 1, i8 0 } +@"type_info::" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"x\82\81m t7\03\CB\F8k\81-;\C9\84", [11 x i8]* @"type_info::::name", i32 1, i8 1, i8 0 } @"type_info::<*const *mut core::void>::name" = private unnamed_addr constant [23 x i8] c"*const *mut core::void\00" -@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i64 64, i32 8, i8 0 } +@"type_info::<*const *mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\C5fO\BD\84\DF\06\BFd+\B1\9Abv\CE\00", [23 x i8]* @"type_info::<*const *mut core::void>::name", i32 64, i8 8, i8 0 } @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Bar\00" @"struct_info::::name" = private unnamed_addr constant [4 x i8] c"Bar\00" @"struct_info::::field_names" = private unnamed_addr constant [2 x i8] c"0\00" @@ -39,14 +39,14 @@ target triple = "x86-64" @1 = private unnamed_addr constant [4 x i8 addrspace(4)*] [i8 addrspace(4)* @"struct_info::::field_names", i8 addrspace(4)* @"struct_info::::field_names.1", i8 addrspace(4)* @"struct_info::::field_names.2", i8 addrspace(4)* @"struct_info::::field_names.3"] @"struct_info::::field_types" = private unnamed_addr constant [4 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::"] @"struct_info::::field_offsets" = private unnamed_addr constant [4 x i16] [i16 0, i16 8, i16 16, i16 24] -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\DD\C3_\88\FAq\B6\EF\14*\E6\1F56FS", [4 x i8]* @"type_info::::name", i64 256, i32 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [4 x i8 addrspace(4)*]* @1, [4 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [4 x i16]* @"struct_info::::field_offsets", i16 4, i8 1 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\DD\C3_\88\FAq\B6\EF\14*\E6\1F56FS", [4 x i8]* @"type_info::::name", i32 256, i8 8, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", [4 x i8 addrspace(4)*]* @1, [4 x %struct.MunTypeInfo addrspace(4)*]* @"struct_info::::field_types", [4 x i16]* @"struct_info::::field_offsets", i16 4, i8 1 } } @"type_info::<*const core::void>::name" = private unnamed_addr constant [18 x i8] c"*const core::void\00" -@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i64 64, i32 8, i8 0 } +@"type_info::<*const core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\EF\D3\E0ac~\5C\D4\EF\AE\B1}\CA\BE\DA\16", [18 x i8]* @"type_info::<*const core::void>::name", i32 64, i8 8, i8 0 } @"type_info::<*mut core::void>::name" = private unnamed_addr constant [16 x i8] c"*mut core::void\00" -@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i64 64, i32 8, i8 0 } +@"type_info::<*mut core::void>" = private unnamed_addr constant %struct.MunTypeInfo { [16 x i8] c"\F0Y\22\FC\95\9E\7F\CE\08T\B1\A2\CD\A7\FAz", [16 x i8]* @"type_info::<*mut core::void>::name", i32 64, i8 8, i8 0 } @"type_info::::name" = private unnamed_addr constant [4 x i8] c"Baz\00" @"struct_info::::name" = private unnamed_addr constant [4 x i8] c"Baz\00" -@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\F8\DC\E6\7F,\948\82\82\ED?\A7\97\96\8A|", [4 x i8]* @"type_info::::name", i64 0, i32 1, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", i8 addrspace(4)* addrspace(4)* null, %struct.MunTypeInfo addrspace(4)* addrspace(4)* null, i16 addrspace(4)* null, i16 0, i8 1 } } +@"type_info::" = private unnamed_addr constant { %struct.MunTypeInfo, %struct.MunStructInfo } { %struct.MunTypeInfo { [16 x i8] c"\F8\DC\E6\7F,\948\82\82\ED?\A7\97\96\8A|", [4 x i8]* @"type_info::::name", i32 0, i8 1, i8 1 }, %struct.MunStructInfo { [4 x i8]* @"struct_info::::name", i8 addrspace(4)* addrspace(4)* null, %struct.MunTypeInfo addrspace(4)* addrspace(4)* null, i16 addrspace(4)* null, i16 0, i8 1 } } @global_type_table = private unnamed_addr constant [10 x %struct.MunTypeInfo addrspace(4)*] [%struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const TypeInfo>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const *mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::", %struct.MunTypeInfo addrspace(4)* @"type_info::<*const core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::<*mut core::void>", %struct.MunTypeInfo addrspace(4)* @"type_info::"] @dispatchTable = global %DispatchTable zeroinitializer @allocatorHandle = private unnamed_addr global i8* null diff --git a/crates/mun_runtime/src/allocator.rs b/crates/mun_runtime/src/allocator.rs index 4f0accbf1..aa118da56 100644 --- a/crates/mun_runtime/src/allocator.rs +++ b/crates/mun_runtime/src/allocator.rs @@ -26,7 +26,7 @@ impl Allocator { } /// Allocates a block of memory - fn alloc(&self, size: u64, alignment: u64) -> *mut u8 { + fn alloc(&self, size: usize, alignment: usize) -> *mut u8 { unsafe { std::alloc::alloc(Layout::from_size_align(size as usize, alignment as usize).unwrap()) } @@ -41,10 +41,7 @@ impl Allocator { pub(crate) unsafe fn create_object(&self, type_info: *const abi::TypeInfo) -> ObjectHandle { let type_info = type_info.as_ref().unwrap(); - let ptr = self.alloc( - type_info.size_in_bytes() as u64, - type_info.alignment().into(), - ); + let ptr = self.alloc(type_info.size_in_bytes(), type_info.alignment()); let object = Box::pin(ObjectInfo { ptr, type_info }); // We want to return a pointer to the `ObjectInfo`, to be used as handle. @@ -71,7 +68,7 @@ impl Allocator { let type_info = src.type_info.as_ref().unwrap(); let size = type_info.size_in_bytes(); - let dest = self.alloc(size as u64, type_info.alignment() as u64); + let dest = self.alloc(size, type_info.alignment()); ptr::copy_nonoverlapping(src.ptr, dest, size as usize); Box::pin(ObjectInfo { diff --git a/crates/mun_runtime/src/type_info.rs b/crates/mun_runtime/src/type_info.rs index ab618b0a2..139fd5ee1 100644 --- a/crates/mun_runtime/src/type_info.rs +++ b/crates/mun_runtime/src/type_info.rs @@ -1,5 +1,6 @@ use super::static_type_map::StaticTypeMap; use once_cell::sync::OnceCell; +use std::convert::TryInto; use std::ffi::{CStr, CString}; use std::sync::Once; @@ -50,8 +51,12 @@ impl HasStaticTypeInfo for *const T { guid, name: name_ptr, group: abi::TypeGroup::FundamentalTypes, - size_in_bits: std::mem::size_of::<*const T>() as u64 * 8, - alignment: std::mem::align_of::<*const T>() as u32, + size_in_bits: (std::mem::size_of::<*const T>() * 8) + .try_into() + .expect("size of T is larger than the maximum according the API size. Please file a bug."), + alignment: (std::mem::align_of::<*const T>()) + .try_into() + .expect("alignment of T is larger than the maximum according the API size. Please file a bug."), }, ) }) @@ -84,8 +89,12 @@ impl HasStaticTypeInfo for *mut T { guid, name: name_ptr, group: abi::TypeGroup::FundamentalTypes, - size_in_bits: std::mem::size_of::<*const T>() as u64 * 8, - alignment: std::mem::align_of::<*const T>() as u32, + size_in_bits: (std::mem::size_of::<*const T>() * 8) + .try_into() + .expect("size of T is larger than the maximum according the API size. Please file a bug."), + alignment: (std::mem::align_of::<*const T>()) + .try_into() + .expect("alignment of T is larger than the maximum according the API size. Please file a bug."), }, ) }) @@ -110,8 +119,12 @@ macro_rules! impl_basic_type_info { guid: abi::Guid{ b: md5::compute(&type_info_name.as_bytes()).0 }, name: type_info_name.as_ptr(), group: abi::TypeGroup::FundamentalTypes, - size_in_bits: std::mem::size_of::<$ty>() as u64 * 8, - alignment: std::mem::align_of::<$ty>() as u32, + size_in_bits: (std::mem::size_of::<$ty>() * 8) + .try_into() + .expect("size of T is larger than the maximum according the API size. Please file a bug."), + alignment: (std::mem::align_of::<$ty>()) + .try_into() + .expect("alignment of T is larger than the maximum according the API size. Please file a bug."), } }) } diff --git a/crates/mun_runtime_capi/ffi b/crates/mun_runtime_capi/ffi index df873262d..038c0d554 160000 --- a/crates/mun_runtime_capi/ffi +++ b/crates/mun_runtime_capi/ffi @@ -1 +1 @@ -Subproject commit df873262d81d9dcbccdc3048a9aa5f88a1c86ae1 +Subproject commit 038c0d554344ccb6e35db5d752b01cf5179d5290 From 5c05080233a97051280199602466e83cd440ebe3 Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Sat, 21 Mar 2020 20:22:28 +0100 Subject: [PATCH 08/12] fix: use mutex instead of rwlock to ensure thread safety --- crates/mun_runtime/Cargo.toml | 1 + crates/mun_runtime/src/static_type_map.rs | 31 +++++++---------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/crates/mun_runtime/Cargo.toml b/crates/mun_runtime/Cargo.toml index 1fadb6300..9daa7cba9 100644 --- a/crates/mun_runtime/Cargo.toml +++ b/crates/mun_runtime/Cargo.toml @@ -17,6 +17,7 @@ notify = "4.0.12" parking_lot = "0.9" tempfile = "3" once_cell = "1.3.1" +lock_api = "0.3" [dev-dependencies] mun_compiler = { path="../mun_compiler" } diff --git a/crates/mun_runtime/src/static_type_map.rs b/crates/mun_runtime/src/static_type_map.rs index 112f542bf..6d8fccfbe 100644 --- a/crates/mun_runtime/src/static_type_map.rs +++ b/crates/mun_runtime/src/static_type_map.rs @@ -1,15 +1,16 @@ +use parking_lot::ReentrantMutex; use std::any::TypeId; +use std::cell::RefCell; use std::collections::HashMap; -use std::sync::RwLock; pub struct StaticTypeMap { - map: RwLock>, + map: ReentrantMutex>>, } impl StaticTypeMap { pub fn new() -> Self { Self { - map: RwLock::new(HashMap::new()), + map: ReentrantMutex::new(RefCell::new(HashMap::default())), } } @@ -23,30 +24,16 @@ impl StaticTypeMap { Init: FnOnce() -> T, { // If already initialized, just return stored value - { - let reader = self.map.read().unwrap(); - if let Some(ref reference) = reader.get(&TypeId::of::()) { - return &reference; - } - } - - // Construct new value and put inside map allocate value on heap - let boxed = Box::new(f()); - - // Get exclusive access - let mut writer = self.map.write().unwrap(); - - // Recheck because maybe we are the second writer and the previous writer inserted the - // value. - if let Some(ref reference) = writer.get(&TypeId::of::()) { - return &reference; + let map = self.map.lock(); + if let Some(r) = map.borrow().get(&TypeId::of::()) { + return r; } // leak it's value until program is terminated - let reference: &'static T = Box::leak(boxed); + let reference = Box::leak(Box::new(f())); // Insert the value into the map - let old = writer.insert(TypeId::of::(), reference); + let old = map.borrow_mut().insert(TypeId::of::(), reference); if old.is_some() { panic!("StaticTypeMap value was reinitialized. This is a bug.") } From 8f841275a3b49f1d56ffec5a4ef67ab0db3b81ad Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Sat, 21 Mar 2020 20:26:32 +0100 Subject: [PATCH 09/12] misc: apply suggestions from code review Co-Authored-By: Wodann --- crates/mun_abi/src/autogen_impl.rs | 13 ++++++++++--- crates/mun_runtime/src/allocator.rs | 4 +--- crates/mun_runtime/src/type_info.rs | 12 ++++++------ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/crates/mun_abi/src/autogen_impl.rs b/crates/mun_abi/src/autogen_impl.rs index c912a5d01..6752ba810 100644 --- a/crates/mun_abi/src/autogen_impl.rs +++ b/crates/mun_abi/src/autogen_impl.rs @@ -1,5 +1,6 @@ use crate::prelude::*; +use std::convert::TryInto; use std::ffi::{c_void, CStr}; use std::fmt::Formatter; use std::marker::{Send, Sync}; @@ -28,17 +29,23 @@ impl TypeInfo { /// Returns the size of the type in bits pub fn size_in_bits(&self) -> usize { - self.size_in_bits as usize + self.size_in_bits + .try_into() + .expect("cannot convert size in bits to platform size") } /// Returns the size of the type in bytes pub fn size_in_bytes(&self) -> usize { - ((self.size_in_bits + 7) / 8) as usize + ((self.size_in_bits + 7) / 8) + .try_into() + .expect("cannot covert size in bytes to platform size") } /// Returns the alignment of the type in bytes pub fn alignment(&self) -> usize { - self.alignment as usize + self.alignment + .try_into() + .expect("cannot convert alignment to platform size") } } diff --git a/crates/mun_runtime/src/allocator.rs b/crates/mun_runtime/src/allocator.rs index aa118da56..ae3261c87 100644 --- a/crates/mun_runtime/src/allocator.rs +++ b/crates/mun_runtime/src/allocator.rs @@ -27,9 +27,7 @@ impl Allocator { /// Allocates a block of memory fn alloc(&self, size: usize, alignment: usize) -> *mut u8 { - unsafe { - std::alloc::alloc(Layout::from_size_align(size as usize, alignment as usize).unwrap()) - } + unsafe { std::alloc::alloc(Layout::from_size_align_unchecked(size, alignment)) } } /// Allocates a managed object of the specified type. diff --git a/crates/mun_runtime/src/type_info.rs b/crates/mun_runtime/src/type_info.rs index 139fd5ee1..cef4ff4c2 100644 --- a/crates/mun_runtime/src/type_info.rs +++ b/crates/mun_runtime/src/type_info.rs @@ -53,10 +53,10 @@ impl HasStaticTypeInfo for *const T { group: abi::TypeGroup::FundamentalTypes, size_in_bits: (std::mem::size_of::<*const T>() * 8) .try_into() - .expect("size of T is larger than the maximum according the API size. Please file a bug."), + .expect("size of T is larger than the maximum allowed ABI size. Please file a bug."), alignment: (std::mem::align_of::<*const T>()) .try_into() - .expect("alignment of T is larger than the maximum according the API size. Please file a bug."), + .expect("alignment of T is larger than the maximum allowed ABI size. Please file a bug."), }, ) }) @@ -91,10 +91,10 @@ impl HasStaticTypeInfo for *mut T { group: abi::TypeGroup::FundamentalTypes, size_in_bits: (std::mem::size_of::<*const T>() * 8) .try_into() - .expect("size of T is larger than the maximum according the API size. Please file a bug."), + .expect("size of T is larger than the maximum allowed ABI size. Please file a bug."), alignment: (std::mem::align_of::<*const T>()) .try_into() - .expect("alignment of T is larger than the maximum according the API size. Please file a bug."), + .expect("alignment of T is larger than the maximum allowed ABI size. Please file a bug."), }, ) }) @@ -121,10 +121,10 @@ macro_rules! impl_basic_type_info { group: abi::TypeGroup::FundamentalTypes, size_in_bits: (std::mem::size_of::<$ty>() * 8) .try_into() - .expect("size of T is larger than the maximum according the API size. Please file a bug."), + .expect("size of T is larger than the maximum allowed ABI size. Please file a bug."), alignment: (std::mem::align_of::<$ty>()) .try_into() - .expect("alignment of T is larger than the maximum according the API size. Please file a bug."), + .expect("alignment of T is larger than the maximum allowed ABI size. Please file a bug."), } }) } From e0548c9bacb85ce89d8041baf97a4c6050bc953d Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Sat, 21 Mar 2020 20:46:59 +0100 Subject: [PATCH 10/12] misc: nocapture for github test action --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b6ec3ac6..3526afefa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,6 +64,7 @@ jobs: continue-on-error: ${{ matrix.config.toolchain == 'nightly' }} with: command: test + args: -- --nocapture style: name: Check Style From af003534726bc957a6fae6d330ffa300a44cb2e3 Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Sat, 21 Mar 2020 21:14:24 +0100 Subject: [PATCH 11/12] fix: removed unused dependency --- crates/mun_runtime/Cargo.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/mun_runtime/Cargo.toml b/crates/mun_runtime/Cargo.toml index 9daa7cba9..1fadb6300 100644 --- a/crates/mun_runtime/Cargo.toml +++ b/crates/mun_runtime/Cargo.toml @@ -17,7 +17,6 @@ notify = "4.0.12" parking_lot = "0.9" tempfile = "3" once_cell = "1.3.1" -lock_api = "0.3" [dev-dependencies] mun_compiler = { path="../mun_compiler" } From e66cbbcccea88fa4d5ba915512f6c3b46a57d220 Mon Sep 17 00:00:00 2001 From: Bas Zalmstra Date: Sat, 21 Mar 2020 21:25:39 +0100 Subject: [PATCH 12/12] misc: added macro for IsIrType of fundamental types --- crates/mun_codegen/src/ir.rs | 105 +++++++++-------------------------- 1 file changed, 25 insertions(+), 80 deletions(-) diff --git a/crates/mun_codegen/src/ir.rs b/crates/mun_codegen/src/ir.rs index 909aea7b5..9009338d3 100644 --- a/crates/mun_codegen/src/ir.rs +++ b/crates/mun_codegen/src/ir.rs @@ -134,69 +134,38 @@ impl AsFunctionReturnType for () { } } -impl IsIrType for u8 { - type Type = IntType; - - fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { - context.i8_type() - } -} - -impl IsIrType for u16 { - type Type = IntType; +macro_rules! impl_fundamental_ir_types { + ($( + $ty:ty => $context_fun:ident():$inkwell_ty:ty + ),+) => { + $( + impl IsIrType for $ty { + type Type = $inkwell_ty; - fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { - context.i16_type() + fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { + context.$context_fun() + } + } + )+ } } -impl IsIrType for u32 { - type Type = IntType; +impl_fundamental_ir_types!( + i8 => i8_type():IntType, + i16 => i16_type():IntType, + i32 => i32_type():IntType, + i64 => i64_type():IntType, - fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { - context.i32_type() - } -} + u8 => i8_type():IntType, + u16 => i16_type():IntType, + u32 => i32_type():IntType, + u64 => i64_type():IntType, -impl IsIrType for u64 { - type Type = IntType; + bool => bool_type():IntType, - fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { - context.i64_type() - } -} - -impl IsIrType for i8 { - type Type = IntType; - - fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { - context.i8_type() - } -} - -impl IsIrType for i16 { - type Type = IntType; - - fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { - context.i16_type() - } -} - -impl IsIrType for i32 { - type Type = IntType; - - fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { - context.i32_type() - } -} - -impl IsIrType for i64 { - type Type = IntType; - - fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { - context.i64_type() - } -} + f32 => f32_type():FloatType, + f64 => f64_type():FloatType +); impl IsIrType for usize { type Type = IntType; @@ -222,30 +191,6 @@ impl IsIrType for isize { } } -impl IsIrType for f32 { - type Type = FloatType; - - fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { - context.f32_type() - } -} - -impl IsIrType for f64 { - type Type = FloatType; - - fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { - context.f64_type() - } -} - -impl IsIrType for bool { - type Type = IntType; - - fn ir_type(context: &Context, _target: &TargetData) -> Self::Type { - context.bool_type() - } -} - pub trait IsPointerType { fn ir_type(context: &Context, target: &TargetData) -> PointerType; }