Misc changes

This commit is contained in:
Sofia 2025-06-27 20:37:31 +03:00
parent 922afaa672
commit 54f25481f4
3 changed files with 87 additions and 63 deletions

View File

@ -10,7 +10,7 @@ cargo run --example libtest && \
# clang++ main.cpp hello.o -o main && \
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
-o main /usr/lib/crt1.o hello.o -lc && \
./main ; echo $?
./main ; echo "Return value: ""$?"
## Command from: clang -v hello.o -o test

View File

@ -1,5 +1,4 @@
use std::ffi::{CStr, CString};
use std::marker::PhantomData;
use std::ptr::null_mut;
use llvm_sys::analysis::LLVMVerifyModule;
@ -14,55 +13,14 @@ use llvm_sys::target_machine::{
use llvm_sys::{
LLVMBasicBlock, LLVMBuilder, LLVMContext, LLVMModule, LLVMType, LLVMValue, core::*, prelude::*,
};
use primitives::IRType;
use util::{ErrorMessageHolder, from_cstring, into_cstring};
pub use primitives::{IRValue, OpaqueIRValue};
mod primitives;
mod util;
pub trait IRType {
const SIGNED: LLVMBool;
unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef;
}
impl IRType for bool {
const SIGNED: LLVMBool = 0;
unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef {
unsafe { LLVMInt1TypeInContext(context.context) }
}
}
impl IRType for i32 {
const SIGNED: LLVMBool = 1;
unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef {
unsafe { LLVMInt32TypeInContext(context.context) }
}
}
pub struct IROpaqueValue(LLVMTypeRef, LLVMValueRef);
pub struct IRValue<T: IRType>(PhantomData<T>, IROpaqueValue);
impl<T: IRType> IRValue<T> {
unsafe fn from_runtime(t: LLVMTypeRef, value: LLVMValueRef) -> IRValue<T> {
IRValue(PhantomData, IROpaqueValue(t, value))
}
}
impl<T: IRType + Into<i64>> IRValue<T> {
pub fn from_const(context: &IRContext, value: T) -> Self {
unsafe {
let t = T::llvm_type(context);
let value = LLVMConstInt(t, value.into() as u64, T::SIGNED);
IRValue(PhantomData, IROpaqueValue(t, value))
}
}
}
impl<T: IRType> From<IRValue<T>> for IROpaqueValue {
fn from(value: IRValue<T>) -> Self {
value.1
}
}
pub struct IRContext {
context: *mut LLVMContext,
builder: *mut LLVMBuilder,
@ -117,11 +75,7 @@ impl<'a> IRModule<'a> {
let mut target: _ = null_mut();
let mut err = ErrorMessageHolder::null();
LLVMGetTargetFromTriple(
c"x86_64-unknown-linux-gnu".as_ptr(),
&mut target,
err.borrow_mut(),
);
LLVMGetTargetFromTriple(triple, &mut target, err.borrow_mut());
println!("{:?}, {:?}", from_cstring(triple), target);
err.into_result().unwrap();
@ -193,7 +147,7 @@ impl<'a> IRFunction<'a> {
pub fn new(module: &'a IRModule<'a>, name: &String) -> IRFunction<'a> {
unsafe {
// TODO, fix later!
let return_type = LLVMInt32TypeInContext(module.context.context);
let return_type = LLVMInt8TypeInContext(module.context.context);
let mut argts = [];
let func_type =
LLVMFunctionType(return_type, argts.as_mut_ptr(), argts.len() as u32, 0);
@ -234,7 +188,7 @@ impl<'a> IRBlock<'a> {
}
}
pub fn call(&self, function: &IRFunction) -> IROpaqueValue {
pub fn call(&self, function: &IRFunction) -> OpaqueIRValue {
unsafe {
let builder = self.context.builder;
LLVMPositionBuilderAtEnd(builder, self.blockref);
@ -250,13 +204,13 @@ impl<'a> IRBlock<'a> {
args.len() as u32,
into_cstring(&function.name).as_ptr(),
);
IROpaqueValue(i32::llvm_type(&self.context), value)
OpaqueIRValue(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;
pub fn add(&self, lhs: OpaqueIRValue, rhs: OpaqueIRValue) -> Result<OpaqueIRValue, ()> {
let OpaqueIRValue(t1, lhs) = lhs;
let OpaqueIRValue(t2, rhs) = rhs;
if t1 != t2 {
Err(())
} else {
@ -264,14 +218,14 @@ impl<'a> IRBlock<'a> {
let builder = self.context.builder;
LLVMPositionBuilderAtEnd(builder, self.blockref);
let value = LLVMBuildAdd(builder, lhs, rhs, c"add".as_ptr());
Ok(IROpaqueValue(t1, value))
Ok(OpaqueIRValue(t1, value))
}
}
}
pub fn less_than(&self, lhs: IROpaqueValue, rhs: IROpaqueValue) -> Result<IRValue<bool>, ()> {
let IROpaqueValue(t1, lhs) = lhs;
let IROpaqueValue(t2, rhs) = rhs;
pub fn less_than(&self, lhs: OpaqueIRValue, rhs: OpaqueIRValue) -> Result<IRValue<bool>, ()> {
let OpaqueIRValue(t1, lhs) = lhs;
let OpaqueIRValue(t2, rhs) = rhs;
if t1 != t2 {
Err(())
@ -307,7 +261,7 @@ impl<'a> IRBlock<'a> {
}
}
pub fn ret(self, function: &IRFunction, value: IROpaqueValue) {
pub fn ret(self, function: &IRFunction, value: OpaqueIRValue) {
unsafe {
let builder = self.context.builder;
LLVMPositionBuilderAtEnd(builder, self.blockref);

View File

@ -0,0 +1,70 @@
use std::marker::PhantomData;
use llvm_sys::{
core::{
LLVMConstAdd, LLVMConstInt, LLVMInt1TypeInContext, LLVMInt8Type, LLVMInt8TypeInContext,
LLVMInt16TypeInContext, LLVMInt32TypeInContext, LLVMIntTypeInContext,
},
prelude::{LLVMBool, LLVMTypeRef, LLVMValueRef},
};
use crate::IRContext;
pub trait IRType {
const SIGNED: LLVMBool;
unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef;
}
impl IRType for bool {
const SIGNED: LLVMBool = 0;
unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef {
unsafe { LLVMInt1TypeInContext(context.context) }
}
}
impl IRType for i32 {
const SIGNED: LLVMBool = 1;
unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef {
unsafe { LLVMInt8TypeInContext(context.context) }
}
}
impl IRType for u32 {
const SIGNED: LLVMBool = 0;
unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef {
unsafe { LLVMInt32TypeInContext(context.context) }
}
}
impl IRType for u16 {
const SIGNED: LLVMBool = 0;
unsafe fn llvm_type(context: &IRContext) -> LLVMTypeRef {
unsafe { LLVMInt16TypeInContext(context.context) }
}
}
pub struct OpaqueIRValue(pub(crate) LLVMTypeRef, pub(crate) LLVMValueRef);
pub struct IRValue<T: IRType>(PhantomData<T>, pub(crate) OpaqueIRValue);
impl<T: IRType> IRValue<T> {
pub(crate) unsafe fn from_runtime(t: LLVMTypeRef, value: LLVMValueRef) -> IRValue<T> {
IRValue(PhantomData, OpaqueIRValue(t, value))
}
}
impl<T: IRType + Into<i64>> IRValue<T> {
pub fn from_const(context: &IRContext, value: T) -> Self {
unsafe {
let t = T::llvm_type(context);
let value = LLVMConstInt(t, value.into() as u64, T::SIGNED);
IRValue(PhantomData, OpaqueIRValue(t, value))
}
}
}
impl<T: IRType> From<IRValue<T>> for OpaqueIRValue {
fn from(value: IRValue<T>) -> Self {
value.1
}
}