From 1a8535516c39536d406b4e4324af1bc206531492 Mon Sep 17 00:00:00 2001 From: sofia Date: Thu, 7 Aug 2025 21:32:30 +0300 Subject: [PATCH] Add nullptr comparison --- examples/nullptr_comparison.reid | 4 ++++ examples/triple_import_main.reid | 6 ------ examples/triple_import_ship.reid | 17 ----------------- examples/triple_import_vec2.reid | 6 ------ reid-llvm-lib/src/builder.rs | 11 +++++++++++ reid-llvm-lib/src/compile.rs | 4 ++++ reid-llvm-lib/src/fmt.rs | 1 + reid-llvm-lib/src/lib.rs | 4 ++++ reid/src/codegen/intrinsics.rs | 26 ++++++++++++++++++++++++++ 9 files changed, 50 insertions(+), 29 deletions(-) create mode 100644 examples/nullptr_comparison.reid delete mode 100644 examples/triple_import_main.reid delete mode 100644 examples/triple_import_ship.reid delete mode 100644 examples/triple_import_vec2.reid diff --git a/examples/nullptr_comparison.reid b/examples/nullptr_comparison.reid new file mode 100644 index 0000000..a0b2337 --- /dev/null +++ b/examples/nullptr_comparison.reid @@ -0,0 +1,4 @@ +fn main() -> bool { + let ptr = i32::null(); + return i32::is_null(ptr); +} \ No newline at end of file diff --git a/examples/triple_import_main.reid b/examples/triple_import_main.reid deleted file mode 100644 index fab276f..0000000 --- a/examples/triple_import_main.reid +++ /dev/null @@ -1,6 +0,0 @@ -import triple_import_vec2::Vec2; -import triple_import_ship::Ship; - -fn main() -> i32 { - return 0; -} \ No newline at end of file diff --git a/examples/triple_import_ship.reid b/examples/triple_import_ship.reid deleted file mode 100644 index 2b36bcf..0000000 --- a/examples/triple_import_ship.reid +++ /dev/null @@ -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(), - }; - } -} \ No newline at end of file diff --git a/examples/triple_import_vec2.reid b/examples/triple_import_vec2.reid deleted file mode 100644 index 9d430fb..0000000 --- a/examples/triple_import_vec2.reid +++ /dev/null @@ -1,6 +0,0 @@ - -struct Vec2 { x: f32, y: f32 } - -impl Vec2 { - pub fn zero() -> Vec2 { Vec2 { x: 0.0, y: 0.0 } } -} diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index b4f9583..6f015ed 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -3,6 +3,8 @@ use std::{cell::RefCell, rc::Rc}; +use llvm_sys::core::LLVMBuildIsNull; + use crate::{ Block, BlockData, CompileResult, ConstValueKind, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData, ModuleData, NamedStruct, TerminatorKind, Type, TypeCategory, TypeData, @@ -614,6 +616,14 @@ impl Builder { Instr::ShiftRightArithmetic(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()), Instr::ShiftLeft(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()), 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); Ok(kind.get_type()) } + IsNull(_) => Ok(Type::Bool), } } } diff --git a/reid-llvm-lib/src/compile.rs b/reid-llvm-lib/src/compile.rs index 80572a5..ff60150 100644 --- a/reid-llvm-lib/src/compile.rs +++ b/reid-llvm-lib/src/compile.rs @@ -1051,6 +1051,10 @@ impl InstructionHolder { LLVMBuildShl(module.builder_ref, lhs_val, rhs_val, name.as_ptr()) } 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 { diff --git a/reid-llvm-lib/src/fmt.rs b/reid-llvm-lib/src/fmt.rs index 0c9d585..c9f77a9 100644 --- a/reid-llvm-lib/src/fmt.rs +++ b/reid-llvm-lib/src/fmt.rs @@ -393,6 +393,7 @@ impl Debug for Instr { Instr::ShiftRightArithmetic(lhs, rhs) => fmt_binop(f, lhs, &">>a", rhs), Instr::ShiftLeft(lhs, rhs) => fmt_binop(f, lhs, &"<<", rhs), Instr::GetGlobal(global_value) => write!(f, "global {:?}", global_value), + Instr::IsNull(_) => write!(f, "is_null"), } } } diff --git a/reid-llvm-lib/src/lib.rs b/reid-llvm-lib/src/lib.rs index 16ddd28..d612fbb 100644 --- a/reid-llvm-lib/src/lib.rs +++ b/reid-llvm-lib/src/lib.rs @@ -298,6 +298,7 @@ impl Instr { Instr::ShiftRightArithmetic(..) => "ashr", Instr::ShiftLeft(..) => "shl", Instr::GetGlobal(..) => "global", + Instr::IsNull(..) => "is_null", } } } @@ -491,6 +492,9 @@ pub enum Instr { /// no-op cast because no bits change with this conversion. BitCast(InstructionValue, Type), + /// Check if the given instruction value is a null pointer + IsNull(InstructionValue), + FunctionCall(FunctionValue, Vec), } diff --git a/reid/src/codegen/intrinsics.rs b/reid/src/codegen/intrinsics.rs index 8d42abe..fb608fe 100644 --- a/reid/src/codegen/intrinsics.rs +++ b/reid/src/codegen/intrinsics.rs @@ -388,6 +388,22 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec { 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 } @@ -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 { + 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)] pub struct IntrinsicConst(u64); impl IntrinsicFunction for IntrinsicConst {