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 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 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 rhs_cmp = IRValue::from_const(&context, 200);
|
||||||
|
|
||||||
let compare = block.less_than(lhs_cmp.into(), rhs_cmp.into()).unwrap();
|
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);
|
pub struct IRValue<T: IRType>(PhantomData<T>, IROpaqueValue);
|
||||||
|
|
||||||
impl<T: IRType> IRValue<T> {
|
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 {
|
pub struct IRContext {
|
||||||
context: *mut LLVMContext,
|
context: *mut LLVMContext,
|
||||||
builder: *mut LLVMBuilder,
|
builder: *mut LLVMBuilder,
|
||||||
@ -209,8 +209,10 @@ impl<'a> Drop for IRModule<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct IRFunction<'a> {
|
pub struct IRFunction<'a> {
|
||||||
|
pub name: String,
|
||||||
pub module: &'a IRModule<'a>,
|
pub module: &'a IRModule<'a>,
|
||||||
pub functionref: *mut LLVMValue,
|
pub function_ref: *mut LLVMValue,
|
||||||
|
pub function_type: *mut LLVMType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IRFunction<'a> {
|
impl<'a> IRFunction<'a> {
|
||||||
@ -222,12 +224,17 @@ impl<'a> IRFunction<'a> {
|
|||||||
let func_type =
|
let func_type =
|
||||||
LLVMFunctionType(return_type, argts.as_mut_ptr(), argts.len() as u32, 0);
|
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);
|
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 {
|
IRFunction {
|
||||||
|
name: name.clone(),
|
||||||
module,
|
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>, ()> {
|
pub fn less_than(&self, lhs: IROpaqueValue, rhs: IROpaqueValue) -> Result<IRValue<bool>, ()> {
|
||||||
let IROpaqueValue(t1, lhs) = lhs;
|
let IROpaqueValue(t1, lhs) = lhs;
|
||||||
let IROpaqueValue(t2, rhs) = rhs;
|
let IROpaqueValue(t2, rhs) = rhs;
|
||||||
@ -302,7 +344,7 @@ impl<'a> IRBlock<'a> {
|
|||||||
|
|
||||||
unsafe fn append(mut self, function: &IRFunction<'a>) {
|
unsafe fn append(mut self, function: &IRFunction<'a>) {
|
||||||
unsafe {
|
unsafe {
|
||||||
LLVMAppendExistingBasicBlock(function.functionref, self.blockref);
|
LLVMAppendExistingBasicBlock(function.function_ref, self.blockref);
|
||||||
self.inserted = true;
|
self.inserted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user