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