Add nullptr comparison
This commit is contained in:
		
							parent
							
								
									e1ac019ecd
								
							
						
					
					
						commit
						1a8535516c
					
				
							
								
								
									
										4
									
								
								examples/nullptr_comparison.reid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								examples/nullptr_comparison.reid
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | |||||||
|  | fn main() -> bool { | ||||||
|  |     let ptr = i32::null(); | ||||||
|  |     return i32::is_null(ptr); | ||||||
|  | } | ||||||
| @ -1,6 +0,0 @@ | |||||||
| import triple_import_vec2::Vec2; |  | ||||||
| import triple_import_ship::Ship; |  | ||||||
| 
 |  | ||||||
| fn main() -> i32 {  |  | ||||||
|     return 0;  |  | ||||||
| } |  | ||||||
| @ -1,17 +0,0 @@ | |||||||
| //asd |  | ||||||
| import triple_import_vec2::Vec2; |  | ||||||
| 
 |  | ||||||
| struct Ship { |  | ||||||
|     position: Vec2, |  | ||||||
|     velocity: Vec2, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| impl Ship { |  | ||||||
|     pub fn foo(&self, vec: Vec2) { |  | ||||||
|         let b: Ship = Ship { |  | ||||||
|             position: Vec2::zero(), |  | ||||||
|             velocity: Vec2::zero(), |  | ||||||
|         }; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,6 +0,0 @@ | |||||||
| 
 |  | ||||||
| struct Vec2 { x: f32, y: f32 } |  | ||||||
| 
 |  | ||||||
| impl Vec2 { |  | ||||||
|     pub fn zero() -> Vec2 { Vec2 { x: 0.0, y: 0.0 } } |  | ||||||
| } |  | ||||||
| @ -3,6 +3,8 @@ | |||||||
| 
 | 
 | ||||||
| use std::{cell::RefCell, rc::Rc}; | use std::{cell::RefCell, rc::Rc}; | ||||||
| 
 | 
 | ||||||
|  | use llvm_sys::core::LLVMBuildIsNull; | ||||||
|  | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     Block, BlockData, CompileResult, ConstValueKind, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData, |     Block, BlockData, CompileResult, ConstValueKind, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData, | ||||||
|     ModuleData, NamedStruct, TerminatorKind, Type, TypeCategory, TypeData, |     ModuleData, NamedStruct, TerminatorKind, Type, TypeCategory, TypeData, | ||||||
| @ -614,6 +616,14 @@ impl Builder { | |||||||
|                 Instr::ShiftRightArithmetic(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()), |                 Instr::ShiftRightArithmetic(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()), | ||||||
|                 Instr::ShiftLeft(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()), |                 Instr::ShiftLeft(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()), | ||||||
|                 Instr::GetGlobal(_) => Ok(()), |                 Instr::GetGlobal(_) => Ok(()), | ||||||
|  |                 Instr::IsNull(val) => { | ||||||
|  |                     let val_ty = val.get_type(&self)?; | ||||||
|  |                     if let Type::Ptr(_) = val_ty { | ||||||
|  |                         Ok(()) | ||||||
|  |                     } else { | ||||||
|  |                         Err(ErrorKind::Null) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -770,6 +780,7 @@ impl InstructionValue { | |||||||
|                     let kind = builder.get_const_kind(constant); |                     let kind = builder.get_const_kind(constant); | ||||||
|                     Ok(kind.get_type()) |                     Ok(kind.get_type()) | ||||||
|                 } |                 } | ||||||
|  |                 IsNull(_) => Ok(Type::Bool), | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -1051,6 +1051,10 @@ impl InstructionHolder { | |||||||
|                     LLVMBuildShl(module.builder_ref, lhs_val, rhs_val, name.as_ptr()) |                     LLVMBuildShl(module.builder_ref, lhs_val, rhs_val, name.as_ptr()) | ||||||
|                 } |                 } | ||||||
|                 GetGlobal(global_value) => module.globals.get(global_value).unwrap().clone(), |                 GetGlobal(global_value) => module.globals.get(global_value).unwrap().clone(), | ||||||
|  |                 IsNull(instruction_value) => { | ||||||
|  |                     let val = module.values.get(&*instruction_value).unwrap().value_ref; | ||||||
|  |                     LLVMBuildIsNull(module.builder_ref, val, name.as_ptr()) | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         }; |         }; | ||||||
|         if let Some(record) = &self.record { |         if let Some(record) = &self.record { | ||||||
|  | |||||||
| @ -393,6 +393,7 @@ impl Debug for Instr { | |||||||
|             Instr::ShiftRightArithmetic(lhs, rhs) => fmt_binop(f, lhs, &">>a", rhs), |             Instr::ShiftRightArithmetic(lhs, rhs) => fmt_binop(f, lhs, &">>a", rhs), | ||||||
|             Instr::ShiftLeft(lhs, rhs) => fmt_binop(f, lhs, &"<<", rhs), |             Instr::ShiftLeft(lhs, rhs) => fmt_binop(f, lhs, &"<<", rhs), | ||||||
|             Instr::GetGlobal(global_value) => write!(f, "global {:?}", global_value), |             Instr::GetGlobal(global_value) => write!(f, "global {:?}", global_value), | ||||||
|  |             Instr::IsNull(_) => write!(f, "is_null"), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -298,6 +298,7 @@ impl Instr { | |||||||
|             Instr::ShiftRightArithmetic(..) => "ashr", |             Instr::ShiftRightArithmetic(..) => "ashr", | ||||||
|             Instr::ShiftLeft(..) => "shl", |             Instr::ShiftLeft(..) => "shl", | ||||||
|             Instr::GetGlobal(..) => "global", |             Instr::GetGlobal(..) => "global", | ||||||
|  |             Instr::IsNull(..) => "is_null", | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -491,6 +492,9 @@ pub enum Instr { | |||||||
|     /// no-op cast because no bits change with this conversion.
 |     /// no-op cast because no bits change with this conversion.
 | ||||||
|     BitCast(InstructionValue, Type), |     BitCast(InstructionValue, Type), | ||||||
| 
 | 
 | ||||||
|  |     /// Check if the given instruction value is a null pointer
 | ||||||
|  |     IsNull(InstructionValue), | ||||||
|  | 
 | ||||||
|     FunctionCall(FunctionValue, Vec<InstructionValue>), |     FunctionCall(FunctionValue, Vec<InstructionValue>), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -388,6 +388,22 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> { | |||||||
|         signature_meta: Default::default(), |         signature_meta: Default::default(), | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|  |     intrinsics.push(FunctionDefinition { | ||||||
|  |         name: "is_null".to_owned(), | ||||||
|  |         linkage_name: None, | ||||||
|  |         is_pub: true, | ||||||
|  |         is_imported: false, | ||||||
|  |         return_type: TypeKind::Bool, | ||||||
|  |         parameters: vec![FunctionParam { | ||||||
|  |             name: "value".to_string(), | ||||||
|  |             ty: TypeKind::UserPtr(Box::new(ty.clone())), | ||||||
|  |             meta: Default::default(), | ||||||
|  |         }], | ||||||
|  |         kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicIsNull)), | ||||||
|  |         source: None, | ||||||
|  |         signature_meta: Default::default(), | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|     intrinsics |     intrinsics | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -755,6 +771,16 @@ impl IntrinsicFunction for IntrinsicNullPtr { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[derive(Clone, Debug)] | ||||||
|  | pub struct IntrinsicIsNull; | ||||||
|  | impl IntrinsicFunction for IntrinsicIsNull { | ||||||
|  |     fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, params: &[StackValue]) -> Result<StackValue, ErrorKind> { | ||||||
|  |         let val = params.get(0).unwrap().instr(); | ||||||
|  |         let instr = scope.block.build(Instr::IsNull(val)).unwrap(); | ||||||
|  |         Ok(StackValue(StackValueKind::Literal(instr), TypeKind::Bool)) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| #[derive(Clone, Debug)] | #[derive(Clone, Debug)] | ||||||
| pub struct IntrinsicConst(u64); | pub struct IntrinsicConst(u64); | ||||||
| impl IntrinsicFunction for IntrinsicConst { | impl IntrinsicFunction for IntrinsicConst { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user