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