inkwell/values/
generic_value.rs

1use libc::c_void;
2use llvm_sys::execution_engine::{
3    LLVMCreateGenericValueOfPointer, LLVMDisposeGenericValue, LLVMGenericValueIntWidth, LLVMGenericValueRef,
4    LLVMGenericValueToFloat, LLVMGenericValueToInt, LLVMGenericValueToPointer,
5};
6
7use crate::types::{AsTypeRef, FloatType};
8
9use std::marker::PhantomData;
10
11// SubTypes: GenericValue<IntValue, FloatValue, or PointerValue>
12#[derive(Debug)]
13pub struct GenericValue<'ctx> {
14    pub(crate) generic_value: LLVMGenericValueRef,
15    _phantom: PhantomData<&'ctx ()>,
16}
17
18impl<'ctx> GenericValue<'ctx> {
19    pub(crate) unsafe fn new(generic_value: LLVMGenericValueRef) -> Self {
20        assert!(!generic_value.is_null());
21
22        GenericValue {
23            generic_value,
24            _phantom: PhantomData,
25        }
26    }
27
28    // SubType: GenericValue<IntValue> only
29    pub fn int_width(self) -> u32 {
30        unsafe { LLVMGenericValueIntWidth(self.generic_value) }
31    }
32
33    // SubType: create_generic_value() -> GenericValue<PointerValue, T>
34    // REVIEW: How safe is this really?
35    pub unsafe fn create_generic_value_of_pointer<T>(value: &mut T) -> Self {
36        let value = LLVMCreateGenericValueOfPointer(value as *mut _ as *mut c_void);
37
38        GenericValue::new(value)
39    }
40
41    // SubType: impl only for GenericValue<IntValue>
42    pub fn as_int(self, is_signed: bool) -> u64 {
43        unsafe { LLVMGenericValueToInt(self.generic_value, is_signed as i32) }
44    }
45
46    // SubType: impl only for GenericValue<FloatValue>
47    pub fn as_float(self, float_type: &FloatType<'ctx>) -> f64 {
48        unsafe { LLVMGenericValueToFloat(float_type.as_type_ref(), self.generic_value) }
49    }
50
51    // SubType: impl only for GenericValue<PointerValue, T>
52    // REVIEW: How safe is this really?
53    pub unsafe fn into_pointer<T>(self) -> *mut T {
54        LLVMGenericValueToPointer(self.generic_value) as *mut T
55    }
56}
57
58impl Drop for GenericValue<'_> {
59    fn drop(&mut self) {
60        unsafe { LLVMDisposeGenericValue(self.generic_value) }
61    }
62}