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) { | ||||
|         unsafe { | ||||
|             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) { | ||||
|         unsafe { | ||||
|             self.builder.add_instruction_location(&instruction, location); | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| 
 | ||||
| extern fn puts(message: *char) -> i32; | ||||
| extern fn malloc(size: u64) -> *u8; | ||||
| extern fn free(ptr: *u8); | ||||
| extern fn div(numerator: i32, denominator: i32) -> div_t; | ||||
| 
 | ||||
| @ -14,7 +13,7 @@ struct String { | ||||
| impl String { | ||||
|     pub fn new() -> String { | ||||
|         String { | ||||
|             inner: allocate(0), | ||||
|             inner: char::alloca(0), | ||||
|             length: 0, | ||||
|             max_length: 0, | ||||
|             must_be_freed: true, | ||||
| @ -42,7 +41,7 @@ impl String { | ||||
| 
 | ||||
|     pub fn add_char(&mut self, c: char) { | ||||
|         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); | ||||
| 
 | ||||
|             if (*self).must_be_freed == true { | ||||
| @ -120,13 +119,9 @@ pub fn int_div(numerator: i32, denominator: i32) -> div_t { | ||||
|     return div(numerator, denominator); | ||||
| } | ||||
| 
 | ||||
| pub fn allocate(size: u64) -> *u8 { | ||||
|     malloc(size) | ||||
| } | ||||
| 
 | ||||
| pub fn new_string() -> String { | ||||
|     String { | ||||
|         inner: allocate(0), | ||||
|         inner: char::alloca(0), | ||||
|         length: 0, | ||||
|         max_length: 0, | ||||
|         must_be_freed: true, | ||||
| @ -148,7 +143,7 @@ pub fn from_str(str: *char) -> String { | ||||
| 
 | ||||
| pub fn add_char(string: &mut String, c: char) { | ||||
|     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); | ||||
| 
 | ||||
|         if (*string).must_be_freed == true { | ||||
|  | ||||
| @ -33,8 +33,25 @@ const FLOATS: [TypeKind; 7] = [ | ||||
|     TypeKind::F128PPC, | ||||
| ]; | ||||
| 
 | ||||
| const MALLOC_IDENT: &str = "reid.malloc"; | ||||
| 
 | ||||
| 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 | ||||
| } | ||||
| @ -62,7 +79,7 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDef | ||||
|                 ty: TypeKind::U64, | ||||
|                 meta: Default::default(), | ||||
|             }], | ||||
|             kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicAlloca(ty.clone()))), | ||||
|             kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicMalloc(ty.clone()))), | ||||
|             source: None, | ||||
|         }), | ||||
|         "null" => Some(FunctionDefinition { | ||||
| @ -353,13 +370,14 @@ impl IntrinsicFunction for IntrinsicSizeOf { | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug)] | ||||
| pub struct IntrinsicAlloca(TypeKind); | ||||
| impl IntrinsicFunction for IntrinsicAlloca { | ||||
| pub struct IntrinsicMalloc(TypeKind); | ||||
| impl IntrinsicFunction for IntrinsicMalloc { | ||||
|     fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, params: &[StackValue]) -> Result<StackValue, ErrorKind> { | ||||
|         let amount = params.get(0).unwrap(); | ||||
|         let function = scope.block.find_function(&"malloc".to_owned()).unwrap(); | ||||
|         let instr = scope | ||||
|             .block | ||||
|             .build(Instr::ArrayAlloca(self.0.get_type(scope.type_values), amount.instr())) | ||||
|             .build(Instr::FunctionCall(function, vec![amount.instr()])) | ||||
|             .unwrap(); | ||||
|         Ok(StackValue(StackValueKind::Literal(instr), self.0.clone())) | ||||
|     } | ||||
|  | ||||
| @ -125,6 +125,21 @@ pub fn perform_all_passes<'map>( | ||||
|     #[cfg(debug_assertions)] | ||||
|     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(); | ||||
|     for module in &mut context.modules { | ||||
|         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() { | ||||
|         return Err(ReidError::from_kind( | ||||
|             state.errors.iter().map(|e| e.clone().into()).collect(), | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user