From 525dab2147a525899f54e5719fc7674462477240 Mon Sep 17 00:00:00 2001 From: sofia Date: Wed, 21 Aug 2024 22:00:53 +0300 Subject: [PATCH] dd IRValue, IRBlock --- src/codegen/llvm.rs | 94 ++++++++++++++++++++++++++++++++++++--------- src/codegen/mod.rs | 7 +++- 2 files changed, 80 insertions(+), 21 deletions(-) diff --git a/src/codegen/llvm.rs b/src/codegen/llvm.rs index 607f4f0..5b144db 100644 --- a/src/codegen/llvm.rs +++ b/src/codegen/llvm.rs @@ -1,7 +1,9 @@ use std::ffi::{CStr, CString}; use std::mem; -use llvm_sys::{core::*, prelude::*, LLVMBuilder, LLVMContext, LLVMModule, LLVMType, LLVMValue}; +use llvm_sys::{ + core::*, prelude::*, LLVMBasicBlock, LLVMBuilder, LLVMContext, LLVMModule, LLVMType, LLVMValue, +}; fn into_cstring>(value: T) -> CString { let string = value.into(); @@ -67,12 +69,24 @@ impl<'a> Drop for IRModule<'a> { } } +pub enum IRType { + I32, +} + +impl IRType { + fn in_context(&self, context: &mut IRContext) -> *mut LLVMType { + use IRType::*; + unsafe { + return match self { + I32 => LLVMInt32TypeInContext(context.context), + }; + } + } +} + +#[must_use = "asd"] pub struct IRFunction<'a, 'b> { module: &'b mut IRModule<'a>, - /// Signature of the function - return_type: *mut LLVMType, - /// Signature of the function - func_type: *mut LLVMType, /// The actual function value: *mut LLVMValue, } @@ -91,24 +105,66 @@ impl<'a, 'b> IRFunction<'a, 'b> { let function = LLVMAddFunction(module.module, into_cstring("testfunc").as_ptr(), func_type); - let blockref = LLVMCreateBasicBlockInContext( - module.context.context, - into_cstring("entryblock").as_ptr(), - ); - LLVMPositionBuilderAtEnd(module.context.builder, blockref); - - // What is the last 1 ? - let return_value = LLVMConstInt(return_type, mem::transmute(3 as i64), 1); - - LLVMAppendExistingBasicBlock(function, blockref); - LLVMBuildRet(module.context.builder, return_value); - IRFunction { module, - return_type, - func_type, value: function, } } } } + +pub struct IRBlock<'a, 'b, 'c> { + function: &'a mut IRFunction<'b, 'c>, + blockref: *mut LLVMBasicBlock, +} + +impl<'a, 'b, 'c> IRBlock<'a, 'b, 'c> { + pub fn new(function: &'a mut IRFunction<'b, 'c>) -> IRBlock<'a, 'b, 'c> { + unsafe { + let blockref = LLVMCreateBasicBlockInContext( + function.module.context.context, + into_cstring("entryblock").as_ptr(), + ); + LLVMPositionBuilderAtEnd(function.module.context.builder, blockref); + + IRBlock { function, blockref } + } + } + + pub fn add_return(self, value: Option) { + unsafe { + if let Some(value) = value { + LLVMBuildRet(self.function.module.context.builder, value.ir_value); + } else { + LLVMBuildRetVoid(self.function.module.context.builder); + } + } + } +} + +impl<'a, 'b, 'c> Drop for IRBlock<'a, 'b, 'c> { + fn drop(&mut self) { + unsafe { + LLVMAppendExistingBasicBlock(self.function.value, self.blockref); + } + } +} + +pub struct IRValue { + pub ir_type: IRType, + ir_value: *mut LLVMValue, +} + +impl IRValue { + pub fn const_i32(value: i32, block: &mut IRBlock) -> Self { + let ir_type = IRType::I32; + unsafe { + let ir_value = LLVMConstInt( + ir_type.in_context(block.function.module.context), + mem::transmute(3 as i64), + 1, + ); + return IRValue { ir_type, ir_value }; + } + } +} diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 1444795..d82c086 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1,6 +1,6 @@ mod llvm; -use llvm::{IRContext, IRFunction, IRModule}; +use llvm::{IRBlock, IRContext, IRFunction, IRModule, IRValue}; use crate::{ast::FunctionDefinition, TopLevelStatement}; @@ -34,6 +34,9 @@ impl TopLevelStatement { impl FunctionDefinition { fn codegen(&self, module: &mut IRModule) { - let function = IRFunction::new(module); + let mut function = IRFunction::new(module); + let mut block = IRBlock::new(&mut function); + let value = IRValue::const_i32(3, &mut block); + block.add_return(Some(value)) } }