Compare commits
6 Commits
e14efa2ea7
...
5adc1eef04
Author | SHA1 | Date | |
---|---|---|---|
5adc1eef04 | |||
014ba2f638 | |||
89850d7b4f | |||
13be3e9c02 | |||
5026013df3 | |||
beaba4e7de |
@ -7,14 +7,24 @@ pre-existing binary-operators, but also some regular functions and associated
|
|||||||
functions (that every type has by-default). This document lists them all (except
|
functions (that every type has by-default). This document lists them all (except
|
||||||
for the binary operators, because there are hundreds of those).
|
for the binary operators, because there are hundreds of those).
|
||||||
|
|
||||||
|
### Global Intrinsics
|
||||||
|
|
||||||
|
#### `malloc(size: u64) -> *u8`
|
||||||
|
|
||||||
|
Allocates `size` bytes and returns a pointer of `u8` of length `size`.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
i32::malloc(40); // Reserves 40 bytes
|
||||||
|
```
|
||||||
|
|
||||||
### Associated Intrinsics
|
### Associated Intrinsics
|
||||||
|
|
||||||
#### `<T>::sizeof() -> u64`
|
#### `<T>::sizeof() -> u64`
|
||||||
|
|
||||||
Simply returns the size of type `T` in bits.
|
Simply returns the size of type `T` in bytes.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
i32::sizeof(); // Returns 32
|
i32::sizeof(); // Returns 4
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `<T>::null() -> *T`
|
#### `<T>::null() -> *T`
|
||||||
@ -25,9 +35,9 @@ Returns a null-pointer of type `T`.
|
|||||||
i32::null(); // Returns *i32 (null-ptr)
|
i32::null(); // Returns *i32 (null-ptr)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `<T>::alloca(size: u64) -> *T`
|
#### `<T>::malloc(size: u64) -> *T`
|
||||||
|
|
||||||
Allocates `T::sizeof() * size` bits and returns a pointer to `T`.
|
Allocates `T::sizeof() * size` bytes and returns a pointer to `T`.
|
||||||
|
|
||||||
**Note:** This does not seem to work correctly currently.
|
**Note:** This does not seem to work correctly currently.
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ fn main() -> u32 {
|
|||||||
print(from_str("sizeof i32: ") + i32::sizeof());
|
print(from_str("sizeof i32: ") + i32::sizeof());
|
||||||
|
|
||||||
let nullptr = i32::null();
|
let nullptr = i32::null();
|
||||||
let mut list = u64::alloca(15);
|
let mut list = u64::malloc(15);
|
||||||
list[4] = 17;
|
list[4] = 17;
|
||||||
|
|
||||||
print(from_str("value: ") + list[4]);
|
print(from_str("value: ") + list[4]);
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
// Arithmetic, function calls and imports!
|
// Arithmetic, function calls and imports!
|
||||||
|
|
||||||
import std::allocate;
|
|
||||||
|
|
||||||
fn main() -> u8 {
|
fn main() -> u8 {
|
||||||
let mut ptr = allocate(4);
|
let mut ptr = u8::alloca(4);
|
||||||
|
|
||||||
ptr[0] = 5;
|
ptr[0] = 5;
|
||||||
|
|
||||||
|
@ -8,23 +8,16 @@ fn main() {
|
|||||||
|
|
||||||
let module = context.module("test", true);
|
let module = context.module("test", true);
|
||||||
|
|
||||||
let main = module.function("main", Type::I32, Vec::new(), FunctionFlags::default());
|
let main = module.function("main", None, Type::I32, Vec::new(), FunctionFlags::default());
|
||||||
let mut m_entry = main.block("entry");
|
let mut m_entry = main.block("entry");
|
||||||
|
|
||||||
let fibonacci = module.function(
|
let fibonacci = module.function("fibonacci", None, Type::I32, vec![Type::I32], FunctionFlags::default());
|
||||||
"fibonacci",
|
|
||||||
Type::I32,
|
|
||||||
vec![Type::I32],
|
|
||||||
FunctionFlags::default(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let arg = m_entry.build_named("const", Constant(I32(5))).unwrap();
|
let arg = m_entry.build_named("const", Constant(I32(5))).unwrap();
|
||||||
let fibonacci_call = m_entry
|
let fibonacci_call = m_entry
|
||||||
.build_named("const", FunctionCall(fibonacci.value(), vec![arg]))
|
.build_named("const", FunctionCall(fibonacci.value(), vec![arg]))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
m_entry
|
m_entry.terminate(TerminatorKind::Ret(fibonacci_call)).unwrap();
|
||||||
.terminate(TerminatorKind::Ret(fibonacci_call))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut f_entry = fibonacci.block("entry");
|
let mut f_entry = fibonacci.block("entry");
|
||||||
|
|
||||||
|
@ -168,6 +168,15 @@ impl Builder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) unsafe fn find_function(&self, module: ModuleValue, name: &String) -> Option<FunctionValue> {
|
||||||
|
unsafe {
|
||||||
|
let mut modules = self.modules.borrow_mut();
|
||||||
|
let module = modules.get_unchecked_mut(module.0);
|
||||||
|
dbg!(module.functions.iter().map(|f| f.data.name.clone()).collect::<Vec<_>>());
|
||||||
|
module.functions.iter().find(|f| f.data.name == *name).map(|f| f.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) unsafe fn add_instruction_location(&self, value: &InstructionValue, location: DebugLocationValue) {
|
pub(crate) unsafe fn add_instruction_location(&self, value: &InstructionValue, location: DebugLocationValue) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut modules = self.modules.borrow_mut();
|
let mut modules = self.modules.borrow_mut();
|
||||||
|
@ -587,9 +587,15 @@ impl FunctionHolder {
|
|||||||
let param_ptr = param_types.as_mut_ptr();
|
let param_ptr = param_types.as_mut_ptr();
|
||||||
let param_len = param_types.len();
|
let param_len = param_types.len();
|
||||||
|
|
||||||
|
let name = if self.data.flags.is_main {
|
||||||
|
c"main"
|
||||||
|
} else {
|
||||||
|
&into_cstring(&self.data.linkage_name.clone().unwrap_or(self.data.name.clone()))
|
||||||
|
};
|
||||||
|
|
||||||
let fn_type = LLVMFunctionType(ret_type, param_ptr, param_len as u32, 0);
|
let fn_type = LLVMFunctionType(ret_type, param_ptr, param_len as u32, 0);
|
||||||
|
|
||||||
let function_ref = LLVMAddFunction(module_ref, into_cstring(&self.data.name).as_ptr(), fn_type);
|
let function_ref = LLVMAddFunction(module_ref, name.as_ptr(), fn_type);
|
||||||
|
|
||||||
if self.data.flags.inline {
|
if self.data.flags.inline {
|
||||||
let attribute = LLVMCreateEnumAttribute(context.context_ref, LLVMEnumAttribute::AlwaysInline as u32, 0);
|
let attribute = LLVMCreateEnumAttribute(context.context_ref, LLVMEnumAttribute::AlwaysInline as u32, 0);
|
||||||
@ -599,7 +605,6 @@ impl FunctionHolder {
|
|||||||
let metadata = if let Some(debug) = debug {
|
let metadata = if let Some(debug) = debug {
|
||||||
if let Some(scope_value) = &self.debug_info {
|
if let Some(scope_value) = &self.debug_info {
|
||||||
let scope_data = debug.info.get_scope_data(scope_value).unwrap();
|
let scope_data = debug.info.get_scope_data(scope_value).unwrap();
|
||||||
dbg!(&debug.info.get_scope());
|
|
||||||
|
|
||||||
let mangled_length_ptr = &mut 0;
|
let mangled_length_ptr = &mut 0;
|
||||||
let mangled_name = LLVMGetValueName2(function_ref, mangled_length_ptr);
|
let mangled_name = LLVMGetValueName2(function_ref, mangled_length_ptr);
|
||||||
|
@ -66,7 +66,14 @@ pub struct Module<'ctx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> Module<'ctx> {
|
impl<'ctx> Module<'ctx> {
|
||||||
pub fn function(&self, name: &str, ret: Type, params: Vec<Type>, flags: FunctionFlags) -> Function<'ctx> {
|
pub fn function(
|
||||||
|
&self,
|
||||||
|
name: &str,
|
||||||
|
linkage: Option<String>,
|
||||||
|
ret: Type,
|
||||||
|
params: Vec<Type>,
|
||||||
|
flags: FunctionFlags,
|
||||||
|
) -> Function<'ctx> {
|
||||||
unsafe {
|
unsafe {
|
||||||
Function {
|
Function {
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
@ -75,6 +82,7 @@ impl<'ctx> Module<'ctx> {
|
|||||||
&self.value,
|
&self.value,
|
||||||
FunctionData {
|
FunctionData {
|
||||||
name: name.to_owned(),
|
name: name.to_owned(),
|
||||||
|
linkage_name: linkage,
|
||||||
ret,
|
ret,
|
||||||
params,
|
params,
|
||||||
flags,
|
flags,
|
||||||
@ -126,6 +134,7 @@ impl<'ctx> Drop for Module<'ctx> {
|
|||||||
#[derive(Debug, Clone, Hash)]
|
#[derive(Debug, Clone, Hash)]
|
||||||
pub struct FunctionData {
|
pub struct FunctionData {
|
||||||
name: String,
|
name: String,
|
||||||
|
linkage_name: Option<String>,
|
||||||
ret: Type,
|
ret: Type,
|
||||||
params: Vec<Type>,
|
params: Vec<Type>,
|
||||||
flags: FunctionFlags,
|
flags: FunctionFlags,
|
||||||
@ -290,6 +299,10 @@ impl<'builder> Block<'builder> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_function(&mut self, name: &String) -> Option<FunctionValue> {
|
||||||
|
unsafe { self.builder.find_function(self.value.0.0, name) }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_instr_location(&self, instruction: InstructionValue, location: DebugLocationValue) {
|
pub fn set_instr_location(&self, instruction: InstructionValue, location: DebugLocationValue) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.builder.add_instruction_location(&instruction, location);
|
self.builder.add_instruction_location(&instruction, location);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
extern fn puts(message: *char) -> i32;
|
extern fn puts(message: *char) -> i32;
|
||||||
extern fn malloc(size: u64) -> *u8;
|
|
||||||
extern fn free(ptr: *u8);
|
extern fn free(ptr: *u8);
|
||||||
extern fn div(numerator: i32, denominator: i32) -> div_t;
|
extern fn div(numerator: i32, denominator: i32) -> div_t;
|
||||||
|
|
||||||
@ -14,7 +13,7 @@ struct String {
|
|||||||
impl String {
|
impl String {
|
||||||
pub fn new() -> String {
|
pub fn new() -> String {
|
||||||
String {
|
String {
|
||||||
inner: allocate(0),
|
inner: char::malloc(0),
|
||||||
length: 0,
|
length: 0,
|
||||||
max_length: 0,
|
max_length: 0,
|
||||||
must_be_freed: true,
|
must_be_freed: true,
|
||||||
@ -42,7 +41,7 @@ impl String {
|
|||||||
|
|
||||||
pub fn add_char(&mut self, c: char) {
|
pub fn add_char(&mut self, c: char) {
|
||||||
if ((*self).length + 1) >= (*self).max_length {
|
if ((*self).length + 1) >= (*self).max_length {
|
||||||
let new = allocate((*self).max_length + 4) as *char;
|
let new = char::malloc((*self).max_length + 4);
|
||||||
copy_bits((*self).inner, new, (*self).max_length);
|
copy_bits((*self).inner, new, (*self).max_length);
|
||||||
|
|
||||||
if (*self).must_be_freed == true {
|
if (*self).must_be_freed == true {
|
||||||
@ -120,13 +119,9 @@ pub fn int_div(numerator: i32, denominator: i32) -> div_t {
|
|||||||
return div(numerator, denominator);
|
return div(numerator, denominator);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn allocate(size: u64) -> *u8 {
|
|
||||||
malloc(size)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_string() -> String {
|
pub fn new_string() -> String {
|
||||||
String {
|
String {
|
||||||
inner: allocate(0),
|
inner: char::malloc(0),
|
||||||
length: 0,
|
length: 0,
|
||||||
max_length: 0,
|
max_length: 0,
|
||||||
must_be_freed: true,
|
must_be_freed: true,
|
||||||
@ -148,7 +143,7 @@ pub fn from_str(str: *char) -> String {
|
|||||||
|
|
||||||
pub fn add_char(string: &mut String, c: char) {
|
pub fn add_char(string: &mut String, c: char) {
|
||||||
if ((*string).length + 1) >= (*string).max_length {
|
if ((*string).length + 1) >= (*string).max_length {
|
||||||
let new = allocate((*string).max_length + 4) as *char;
|
let new = char::malloc((*string).max_length + 4);
|
||||||
copy_bits((*string).inner, new, (*string).max_length);
|
copy_bits((*string).inner, new, (*string).max_length);
|
||||||
|
|
||||||
if (*string).must_be_freed == true {
|
if (*string).must_be_freed == true {
|
||||||
|
@ -55,6 +55,7 @@ impl ast::Module {
|
|||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
kind: mir::FunctionDefinitionKind::Extern(false),
|
kind: mir::FunctionDefinitionKind::Extern(false),
|
||||||
|
source: Some(module_id),
|
||||||
};
|
};
|
||||||
functions.push(def);
|
functions.push(def);
|
||||||
}
|
}
|
||||||
@ -176,6 +177,7 @@ impl ast::FunctionDefinition {
|
|||||||
.unwrap_or(mir::TypeKind::Void),
|
.unwrap_or(mir::TypeKind::Void),
|
||||||
parameters: params,
|
parameters: params,
|
||||||
kind: mir::FunctionDefinitionKind::Local(block.into_mir(module_id), (range).as_meta(module_id)),
|
kind: mir::FunctionDefinitionKind::Local(block.into_mir(module_id), (range).as_meta(module_id)),
|
||||||
|
source: Some(module_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,26 @@ const FLOATS: [TypeKind; 7] = [
|
|||||||
TypeKind::F128PPC,
|
TypeKind::F128PPC,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const INTRINSIC_IDENT: &str = "reid.intrinsic";
|
||||||
|
const MALLOC_IDENT: &str = "malloc";
|
||||||
|
|
||||||
pub fn form_intrinsics() -> Vec<FunctionDefinition> {
|
pub fn form_intrinsics() -> Vec<FunctionDefinition> {
|
||||||
let intrinsics = Vec::new();
|
let mut intrinsics = Vec::new();
|
||||||
|
|
||||||
|
intrinsics.push(FunctionDefinition {
|
||||||
|
name: MALLOC_IDENT.to_owned(),
|
||||||
|
linkage_name: Some("malloc".to_owned()),
|
||||||
|
is_pub: false,
|
||||||
|
is_imported: true,
|
||||||
|
return_type: TypeKind::UserPtr(Box::new(TypeKind::U8)),
|
||||||
|
parameters: vec![FunctionParam {
|
||||||
|
name: "size".to_owned(),
|
||||||
|
ty: TypeKind::U64,
|
||||||
|
meta: Default::default(),
|
||||||
|
}],
|
||||||
|
kind: FunctionDefinitionKind::Extern(false),
|
||||||
|
source: None,
|
||||||
|
});
|
||||||
|
|
||||||
intrinsics
|
intrinsics
|
||||||
}
|
}
|
||||||
@ -49,9 +67,10 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDef
|
|||||||
return_type: TypeKind::U64,
|
return_type: TypeKind::U64,
|
||||||
parameters: Vec::new(),
|
parameters: Vec::new(),
|
||||||
kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSizeOf(ty.clone()))),
|
kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSizeOf(ty.clone()))),
|
||||||
|
source: None,
|
||||||
}),
|
}),
|
||||||
"alloca" => Some(FunctionDefinition {
|
"malloc" => Some(FunctionDefinition {
|
||||||
name: "alloca".to_owned(),
|
name: "malloc".to_owned(),
|
||||||
linkage_name: None,
|
linkage_name: None,
|
||||||
is_pub: true,
|
is_pub: true,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -61,7 +80,8 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDef
|
|||||||
ty: TypeKind::U64,
|
ty: TypeKind::U64,
|
||||||
meta: Default::default(),
|
meta: Default::default(),
|
||||||
}],
|
}],
|
||||||
kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicAlloca(ty.clone()))),
|
kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicMalloc(ty.clone()))),
|
||||||
|
source: None,
|
||||||
}),
|
}),
|
||||||
"null" => Some(FunctionDefinition {
|
"null" => Some(FunctionDefinition {
|
||||||
name: "null".to_owned(),
|
name: "null".to_owned(),
|
||||||
@ -71,6 +91,7 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDef
|
|||||||
return_type: TypeKind::UserPtr(Box::new(ty.clone())),
|
return_type: TypeKind::UserPtr(Box::new(ty.clone())),
|
||||||
parameters: Vec::new(),
|
parameters: Vec::new(),
|
||||||
kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicNullPtr(ty.clone()))),
|
kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicNullPtr(ty.clone()))),
|
||||||
|
source: None,
|
||||||
}),
|
}),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@ -343,21 +364,28 @@ impl IntrinsicFunction for IntrinsicSizeOf {
|
|||||||
fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> {
|
fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, _: &[StackValue]) -> Result<StackValue, ErrorKind> {
|
||||||
let instr = scope
|
let instr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::Constant(reid_lib::ConstValue::U64(self.0.size_of())))
|
.build(Instr::Constant(reid_lib::ConstValue::U64(self.0.size_of() / 8)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(StackValue(StackValueKind::Literal(instr), self.0.clone()))
|
Ok(StackValue(StackValueKind::Literal(instr), self.0.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct IntrinsicAlloca(TypeKind);
|
pub struct IntrinsicMalloc(TypeKind);
|
||||||
impl IntrinsicFunction for IntrinsicAlloca {
|
impl IntrinsicFunction for IntrinsicMalloc {
|
||||||
fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, params: &[StackValue]) -> Result<StackValue, ErrorKind> {
|
fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, params: &[StackValue]) -> Result<StackValue, ErrorKind> {
|
||||||
let amount = params.get(0).unwrap();
|
let amount = params.get(0).unwrap();
|
||||||
let instr = scope
|
let function = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::ArrayAlloca(self.0.get_type(scope.type_values), amount.instr()))
|
.find_function(&format!("{}.{}", INTRINSIC_IDENT, MALLOC_IDENT))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let sizeof = scope
|
||||||
|
.block
|
||||||
|
.build(Instr::Constant(ConstValue::U64(self.0.size_of() / 8)))
|
||||||
|
.unwrap();
|
||||||
|
let bytes = scope.block.build(Instr::Mul(sizeof, amount.instr())).unwrap();
|
||||||
|
let instr = scope.block.build(Instr::FunctionCall(function, vec![bytes])).unwrap();
|
||||||
Ok(StackValue(StackValueKind::Literal(instr), self.0.clone()))
|
Ok(StackValue(StackValueKind::Literal(instr), self.0.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ impl mir::Context {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct ModuleCodegen<'ctx> {
|
struct ModuleCodegen<'ctx> {
|
||||||
|
name: String,
|
||||||
module: Module<'ctx>,
|
module: Module<'ctx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,9 +187,27 @@ impl mir::Module {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let is_main = self.is_main && function.name == "main";
|
let is_main = self.is_main && function.name == "main";
|
||||||
|
|
||||||
|
let module_prefix = if let Some(module) = function.source {
|
||||||
|
if module == self.module_id {
|
||||||
|
format!("reid.{}.", self.name)
|
||||||
|
} else {
|
||||||
|
format!("reid.{}.", modules.get(&module).unwrap().name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
format!("reid.intrinsic.")
|
||||||
|
};
|
||||||
|
let linkage_name = function.linkage_name.clone().unwrap_or(function.name.clone());
|
||||||
|
let full_name = format!(
|
||||||
|
"{}{}",
|
||||||
|
module_prefix,
|
||||||
|
function.linkage_name.clone().unwrap_or(function.name.clone())
|
||||||
|
);
|
||||||
|
|
||||||
let func = match &function.kind {
|
let func = match &function.kind {
|
||||||
mir::FunctionDefinitionKind::Local(_, _) => Some(module.function(
|
mir::FunctionDefinitionKind::Local(_, _) => Some(module.function(
|
||||||
&function.linkage_name.clone().unwrap_or(function.name.clone()),
|
&full_name,
|
||||||
|
None,
|
||||||
function.return_type.get_type(&type_values),
|
function.return_type.get_type(&type_values),
|
||||||
param_types,
|
param_types,
|
||||||
FunctionFlags {
|
FunctionFlags {
|
||||||
@ -199,7 +218,16 @@ impl mir::Module {
|
|||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
mir::FunctionDefinitionKind::Extern(imported) => Some(module.function(
|
mir::FunctionDefinitionKind::Extern(imported) => Some(module.function(
|
||||||
&function.linkage_name.clone().unwrap_or(function.name.clone()),
|
&full_name,
|
||||||
|
if function.source == None {
|
||||||
|
Some(function.linkage_name.clone().unwrap())
|
||||||
|
} else {
|
||||||
|
if !*imported {
|
||||||
|
Some(linkage_name.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
},
|
||||||
function.return_type.get_type(&type_values),
|
function.return_type.get_type(&type_values),
|
||||||
param_types,
|
param_types,
|
||||||
FunctionFlags {
|
FunctionFlags {
|
||||||
@ -226,9 +254,19 @@ impl mir::Module {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let is_main = self.is_main && function.name == "main";
|
let is_main = self.is_main && function.name == "main";
|
||||||
|
let module_name = if let Some(module) = function.source {
|
||||||
|
if module == self.module_id {
|
||||||
|
format!("reid.{}", self.name)
|
||||||
|
} else {
|
||||||
|
format!("reid.{}", modules.get(&module).unwrap().name)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
format!("reid.intrinsic")
|
||||||
|
};
|
||||||
let func = match &function.kind {
|
let func = match &function.kind {
|
||||||
mir::FunctionDefinitionKind::Local(_, _) => Some(module.function(
|
mir::FunctionDefinitionKind::Local(_, _) => Some(module.function(
|
||||||
&format!("{}::{}", ty, function.name),
|
&format!("{}.{}.{}", module_name, ty, function.name),
|
||||||
|
None,
|
||||||
function.return_type.get_type(&type_values),
|
function.return_type.get_type(&type_values),
|
||||||
param_types,
|
param_types,
|
||||||
FunctionFlags {
|
FunctionFlags {
|
||||||
@ -240,6 +278,7 @@ impl mir::Module {
|
|||||||
)),
|
)),
|
||||||
mir::FunctionDefinitionKind::Extern(imported) => Some(module.function(
|
mir::FunctionDefinitionKind::Extern(imported) => Some(module.function(
|
||||||
&function.linkage_name.clone().unwrap_or(function.name.clone()),
|
&function.linkage_name.clone().unwrap_or(function.name.clone()),
|
||||||
|
None,
|
||||||
function.return_type.get_type(&type_values),
|
function.return_type.get_type(&type_values),
|
||||||
param_types,
|
param_types,
|
||||||
FunctionFlags {
|
FunctionFlags {
|
||||||
@ -277,6 +316,7 @@ impl mir::Module {
|
|||||||
FunctionDefinitionKind::Local(..) => {
|
FunctionDefinitionKind::Local(..) => {
|
||||||
let ir_function = module.function(
|
let ir_function = module.function(
|
||||||
&binop_fn_name,
|
&binop_fn_name,
|
||||||
|
None,
|
||||||
binop.return_type.get_type(&type_values),
|
binop.return_type.get_type(&type_values),
|
||||||
vec![binop.lhs.ty.get_type(&type_values), binop.rhs.ty.get_type(&type_values)],
|
vec![binop.lhs.ty.get_type(&type_values), binop.rhs.ty.get_type(&type_values)],
|
||||||
FunctionFlags {
|
FunctionFlags {
|
||||||
@ -342,6 +382,7 @@ impl mir::Module {
|
|||||||
}
|
}
|
||||||
FunctionDefinitionKind::Extern(imported) => ScopeFunctionKind::UserGenerated(module.function(
|
FunctionDefinitionKind::Extern(imported) => ScopeFunctionKind::UserGenerated(module.function(
|
||||||
&binop_fn_name,
|
&binop_fn_name,
|
||||||
|
None,
|
||||||
binop.return_type.get_type(&type_values),
|
binop.return_type.get_type(&type_values),
|
||||||
vec![binop.lhs.ty.get_type(&type_values), binop.rhs.ty.get_type(&type_values)],
|
vec![binop.lhs.ty.get_type(&type_values), binop.rhs.ty.get_type(&type_values)],
|
||||||
FunctionFlags {
|
FunctionFlags {
|
||||||
@ -475,7 +516,10 @@ impl mir::Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ModuleCodegen { module })
|
Ok(ModuleCodegen {
|
||||||
|
name: self.name.clone(),
|
||||||
|
module,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,6 +125,21 @@ pub fn perform_all_passes<'map>(
|
|||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
dbg!(&context);
|
dbg!(&context);
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
println!("{:#}", &context);
|
||||||
|
|
||||||
|
let state = context.pass(&mut LinkerPass {
|
||||||
|
module_map,
|
||||||
|
is_lib: true,
|
||||||
|
})?;
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
println!("{:-^100}", "LINKER OUTPUT");
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
println!("{:#}", &context);
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
dbg!(&state);
|
||||||
|
|
||||||
let mut binops = BinopMap::default();
|
let mut binops = BinopMap::default();
|
||||||
for module in &mut context.modules {
|
for module in &mut context.modules {
|
||||||
for intrinsic in form_intrinsic_binops() {
|
for intrinsic in form_intrinsic_binops() {
|
||||||
@ -151,21 +166,6 @@ pub fn perform_all_passes<'map>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
println!("{:#}", &context);
|
|
||||||
|
|
||||||
let state = context.pass(&mut LinkerPass {
|
|
||||||
module_map,
|
|
||||||
is_lib: true,
|
|
||||||
})?;
|
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
println!("{:-^100}", "LINKER OUTPUT");
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
println!("{:#}", &context);
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
dbg!(&state);
|
|
||||||
|
|
||||||
if !state.errors.is_empty() {
|
if !state.errors.is_empty() {
|
||||||
return Err(ReidError::from_kind(
|
return Err(ReidError::from_kind(
|
||||||
state.errors.iter().map(|e| e.clone().into()).collect(),
|
state.errors.iter().map(|e| e.clone().into()).collect(),
|
||||||
|
@ -186,6 +186,7 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
.borrow_mut();
|
.borrow_mut();
|
||||||
|
|
||||||
let import_name = unsafe { path.get_unchecked(1) };
|
let import_name = unsafe { path.get_unchecked(1) };
|
||||||
|
let import_id = imported.module_id;
|
||||||
|
|
||||||
let mut imported_types = Vec::new();
|
let mut imported_types = Vec::new();
|
||||||
|
|
||||||
@ -234,6 +235,7 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
return_type,
|
return_type,
|
||||||
parameters: param_tys,
|
parameters: param_tys,
|
||||||
kind: super::FunctionDefinitionKind::Extern(true),
|
kind: super::FunctionDefinitionKind::Extern(true),
|
||||||
|
source: Some(imported.module_id),
|
||||||
});
|
});
|
||||||
} else if let Some(ty) = imported.typedefs.iter_mut().find(|f| f.name == *import_name) {
|
} else if let Some(ty) = imported.typedefs.iter_mut().find(|f| f.name == *import_name) {
|
||||||
let external_key = CustomTypeKey(ty.name.clone(), ty.source_module);
|
let external_key = CustomTypeKey(ty.name.clone(), ty.source_module);
|
||||||
@ -319,12 +321,13 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
ty.clone(),
|
ty.clone(),
|
||||||
FunctionDefinition {
|
FunctionDefinition {
|
||||||
name: func_name.clone(),
|
name: func_name.clone(),
|
||||||
linkage_name: Some(format!("{}::{}", ty, func_name)),
|
linkage_name: Some(format!("{}.{}", ty, func_name)),
|
||||||
is_pub: false,
|
is_pub: false,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
return_type,
|
return_type,
|
||||||
parameters: param_tys,
|
parameters: param_tys,
|
||||||
kind: super::FunctionDefinitionKind::Extern(true),
|
kind: super::FunctionDefinitionKind::Extern(true),
|
||||||
|
source: Some(import_id),
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -298,6 +298,7 @@ pub struct FunctionDefinition {
|
|||||||
pub return_type: TypeKind,
|
pub return_type: TypeKind,
|
||||||
pub parameters: Vec<FunctionParam>,
|
pub parameters: Vec<FunctionParam>,
|
||||||
pub kind: FunctionDefinitionKind,
|
pub kind: FunctionDefinitionKind,
|
||||||
|
pub source: Option<SourceModuleId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
||||||
|
Loading…
Reference in New Issue
Block a user