use inkwell::types::BasicType;
use inkwell::values::BasicValue;
use crate::polkavm::context::address_space::AddressSpace;
use crate::polkavm::context::Context;
#[derive(Debug, Clone, Copy)]
pub struct Global<'ctx> {
pub r#type: inkwell::types::BasicTypeEnum<'ctx>,
pub value: inkwell::values::GlobalValue<'ctx>,
}
impl<'ctx> Global<'ctx> {
pub fn new<T, V>(
context: &mut Context<'ctx>,
r#type: T,
address_space: AddressSpace,
initializer: V,
name: &str,
) -> Self
where
T: BasicType<'ctx>,
V: BasicValue<'ctx>,
{
let r#type = r#type.as_basic_type_enum();
let value = context
.module()
.add_global(r#type, Some(address_space.into()), name);
let global = Self { r#type, value };
global.value.set_linkage(inkwell::module::Linkage::Internal);
global
.value
.set_visibility(inkwell::GlobalVisibility::Default);
global.value.set_externally_initialized(false);
if !r#type.is_pointer_type() {
global.value.set_initializer(&initializer);
} else {
global.value.set_initializer(&r#type.const_zero());
context.build_store(global.into(), initializer).unwrap();
}
global
}
pub fn declare<T>(
context: &mut Context<'ctx>,
r#type: T,
address_space: AddressSpace,
name: &str,
) -> Self
where
T: BasicType<'ctx>,
{
let r#type = r#type.as_basic_type_enum();
let value = context
.module()
.add_global(r#type, Some(address_space.into()), name);
let global = Self { r#type, value };
global.value.set_linkage(inkwell::module::Linkage::External);
global
.value
.set_visibility(inkwell::GlobalVisibility::Default);
global.value.set_externally_initialized(true);
global
}
}