From d0aa3e141013622b304fe34e2f706b87ce9c0328 Mon Sep 17 00:00:00 2001 From: sofia Date: Tue, 24 Jun 2025 23:30:29 +0300 Subject: [PATCH] Add the ability to call functions --- reid-llvm-lib/examples/libtest.rs | 9 +++++- reid-llvm-lib/src/lib.rs | 54 +++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/reid-llvm-lib/examples/libtest.rs b/reid-llvm-lib/examples/libtest.rs index b3e2917..67da38c 100644 --- a/reid-llvm-lib/examples/libtest.rs +++ b/reid-llvm-lib/examples/libtest.rs @@ -6,9 +6,16 @@ pub fn main() { let mainfunc = IRFunction::new(&module, &"mainfunc".to_owned()); + let secondary_func = IRFunction::new(&module, &"secondary".to_owned()); + + let secondary_block = IRBlock::new(&context, &"secondaryblock".to_owned()); + secondary_block.ret(&secondary_func, IRValue::from_const(&context, 54).into()); + let block = IRBlock::new(&context, &"mainblock".to_owned()); - let lhs_cmp = IRValue::from_const(&context, 100); + let lhs_1 = IRValue::from_const(&context, 100); + let lhs_2 = block.call(&secondary_func); + let lhs_cmp = block.add(lhs_1.into(), lhs_2.into()).unwrap(); let rhs_cmp = IRValue::from_const(&context, 200); let compare = block.less_than(lhs_cmp.into(), rhs_cmp.into()).unwrap(); diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 476e327..24357fd 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -61,6 +61,8 @@ impl IRType for i32 { } } +pub struct IROpaqueValue(LLVMTypeRef, LLVMValueRef); + pub struct IRValue(PhantomData, IROpaqueValue); impl IRValue { @@ -85,8 +87,6 @@ impl From> for IROpaqueValue { } } -pub struct IROpaqueValue(LLVMTypeRef, LLVMValueRef); - pub struct IRContext { context: *mut LLVMContext, builder: *mut LLVMBuilder, @@ -209,8 +209,10 @@ impl<'a> Drop for IRModule<'a> { } pub struct IRFunction<'a> { + pub name: String, pub module: &'a IRModule<'a>, - pub functionref: *mut LLVMValue, + pub function_ref: *mut LLVMValue, + pub function_type: *mut LLVMType, } impl<'a> IRFunction<'a> { @@ -222,12 +224,17 @@ impl<'a> IRFunction<'a> { let func_type = LLVMFunctionType(return_type, argts.as_mut_ptr(), argts.len() as u32, 0); - let functionref = + let function_ref = LLVMAddFunction(module.module, into_cstring(name).as_ptr(), func_type); + let function_type = + LLVMFunctionType(return_type, argts.as_mut_ptr(), argts.len() as u32, 0); + IRFunction { + name: name.clone(), module, - functionref, + function_ref, + function_type, } } } @@ -253,6 +260,41 @@ impl<'a> IRBlock<'a> { } } + pub fn call(&self, function: &IRFunction) -> IROpaqueValue { + unsafe { + let builder = self.context.builder; + LLVMPositionBuilderAtEnd(builder, self.blockref); + + // Add way to check and use parameters + let mut args = []; + + let value = LLVMBuildCall2( + builder, + function.function_type, + function.function_ref, + args.as_mut_ptr(), + args.len() as u32, + into_cstring(&function.name).as_ptr(), + ); + IROpaqueValue(i32::llvm_type(&self.context), value) + } + } + + pub fn add(&self, lhs: IROpaqueValue, rhs: IROpaqueValue) -> Result { + let IROpaqueValue(t1, lhs) = lhs; + let IROpaqueValue(t2, rhs) = rhs; + if t1 != t2 { + Err(()) + } else { + unsafe { + let builder = self.context.builder; + LLVMPositionBuilderAtEnd(builder, self.blockref); + let value = LLVMBuildAdd(builder, lhs, rhs, c"add".as_ptr()); + Ok(IROpaqueValue(t1, value)) + } + } + } + pub fn less_than(&self, lhs: IROpaqueValue, rhs: IROpaqueValue) -> Result, ()> { let IROpaqueValue(t1, lhs) = lhs; let IROpaqueValue(t2, rhs) = rhs; @@ -302,7 +344,7 @@ impl<'a> IRBlock<'a> { unsafe fn append(mut self, function: &IRFunction<'a>) { unsafe { - LLVMAppendExistingBasicBlock(function.functionref, self.blockref); + LLVMAppendExistingBasicBlock(function.function_ref, self.blockref); self.inserted = true; } }