Add intrinsic malloc, use that in alloca
This commit is contained in:
parent
beaba4e7de
commit
5026013df3
@ -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();
|
||||||
|
@ -290,6 +290,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::alloca(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::alloca((*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::alloca(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::alloca((*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 {
|
||||||
|
@ -33,8 +33,25 @@ const FLOATS: [TypeKind; 7] = [
|
|||||||
TypeKind::F128PPC,
|
TypeKind::F128PPC,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const MALLOC_IDENT: &str = "reid.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
|
||||||
}
|
}
|
||||||
@ -62,7 +79,7 @@ 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,
|
source: None,
|
||||||
}),
|
}),
|
||||||
"null" => Some(FunctionDefinition {
|
"null" => Some(FunctionDefinition {
|
||||||
@ -353,13 +370,14 @@ impl IntrinsicFunction for IntrinsicSizeOf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[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 function = scope.block.find_function(&"malloc".to_owned()).unwrap();
|
||||||
let instr = scope
|
let instr = scope
|
||||||
.block
|
.block
|
||||||
.build(Instr::ArrayAlloca(self.0.get_type(scope.type_values), amount.instr()))
|
.build(Instr::FunctionCall(function, vec![amount.instr()]))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(StackValue(StackValueKind::Literal(instr), self.0.clone()))
|
Ok(StackValue(StackValueKind::Literal(instr), self.0.clone()))
|
||||||
}
|
}
|
||||||
|
@ -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(),
|
||||||
|
Loading…
Reference in New Issue
Block a user