Add the ability to call functions
This commit is contained in:
		
							parent
							
								
									5f93b7c9c2
								
							
						
					
					
						commit
						d0aa3e1410
					
				| @ -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(); | ||||
|  | ||||
| @ -61,6 +61,8 @@ impl IRType for i32 { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub struct IROpaqueValue(LLVMTypeRef, LLVMValueRef); | ||||
| 
 | ||||
| pub struct IRValue<T: IRType>(PhantomData<T>, IROpaqueValue); | ||||
| 
 | ||||
| impl<T: IRType> IRValue<T> { | ||||
| @ -85,8 +87,6 @@ impl<T: IRType> From<IRValue<T>> 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<IROpaqueValue, ()> { | ||||
|         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<IRValue<bool>, ()> { | ||||
|         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; | ||||
|         } | ||||
|     } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user