authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-26 00:51:46+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-26 01:24:14+02:00
log21bf3b80666c14c9b2a2e1ec984a6b4bb23a5bb7
tree36e906cf5c4a40a715ed53f058feaccacf73ab8a
parent4eb7b28700b23d8465a36e364e60394b2a1da41b

stage2: runtime c pointer null comparison


2 files changed, 11 insertions(+), 6 deletions(-)

src/codegen/llvm.zig+6-5
...@@ -2450,6 +2450,12 @@ pub const FuncGen = struct {...@@ -2450,6 +2450,12 @@ pub const FuncGen = struct {
2450 const operand = try self.resolveInst(un_op);2450 const operand = try self.resolveInst(un_op);
2451 const operand_ty = self.air.typeOf(un_op);2451 const operand_ty = self.air.typeOf(un_op);
2452 const optional_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;2452 const optional_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
2453 if (optional_ty.isPtrLikeOptional()) {
2454 const optional_llvm_ty = try self.dg.llvmType(optional_ty);
2455 const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand;
2456 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");
2457 }
2458
2453 var buf: Type.Payload.ElemType = undefined;2459 var buf: Type.Payload.ElemType = undefined;
2454 const payload_ty = optional_ty.optionalChild(&buf);2460 const payload_ty = optional_ty.optionalChild(&buf);
2455 if (!payload_ty.hasCodeGenBits()) {2461 if (!payload_ty.hasCodeGenBits()) {
...@@ -2459,11 +2465,6 @@ pub const FuncGen = struct {...@@ -2459,11 +2465,6 @@ pub const FuncGen = struct {
2459 return operand;2465 return operand;
2460 }2466 }
2461 }2467 }
2462 if (optional_ty.isPtrLikeOptional()) {
2463 const optional_llvm_ty = try self.dg.llvmType(optional_ty);
2464 const loaded = if (operand_is_ptr) self.builder.buildLoad(operand, "") else operand;
2465 return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");
2466 }
24672468
2468 if (operand_is_ptr or isByRef(optional_ty)) {2469 if (operand_is_ptr or isByRef(optional_ty)) {
2469 const index_type = self.context.intType(32);2470 const index_type = self.context.intType(32);
src/type.zig+5-1
...@@ -2347,11 +2347,13 @@ pub const Type = extern union {...@@ -2347,11 +2347,13 @@ pub const Type = extern union {
2347 }2347 }
2348 }2348 }
23492349
2350 /// Asserts that the type is an optional2350 /// Asserts that the type is an optional or a pointer that can be null.
2351 pub fn isPtrLikeOptional(self: Type) bool {2351 pub fn isPtrLikeOptional(self: Type) bool {
2352 switch (self.tag()) {2352 switch (self.tag()) {
2353 .optional_single_const_pointer,2353 .optional_single_const_pointer,
2354 .optional_single_mut_pointer,2354 .optional_single_mut_pointer,
2355 .c_const_pointer,
2356 .c_mut_pointer,
2355 => return true,2357 => return true,
23562358
2357 .optional => {2359 .optional => {
...@@ -2367,6 +2369,8 @@ pub const Type = extern union {...@@ -2367,6 +2369,8 @@ pub const Type = extern union {
2367 .Many, .One => return !info.@"allowzero",2369 .Many, .One => return !info.@"allowzero",
2368 }2370 }
2369 },2371 },
2372
2373 .pointer => return self.castTag(.pointer).?.data.size == .C,
2370 else => unreachable,2374 else => unreachable,
2371 }2375 }
2372 }2376 }