authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-21 16:54:34+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-10-21 17:29:42+02:00
logfc034ca94f0682a06795616992f176f19ec9a83d
tree162caa58d75510d751b0da4807a8dbee0473a352
parent09c7d5aebc4f7fe96a89f93c0cf99cc03977ea5f

stage2: comptime elemVal and elemPtr for Many/C pointers


1 files changed, 57 insertions(+), 25 deletions(-)

src/Sema.zig+57-25
...@@ -351,6 +351,24 @@ pub const Block = struct {...@@ -351,6 +351,24 @@ pub const Block = struct {
351 });351 });
352 }352 }
353353
354 pub fn addPtrElemPtr(
355 block: *Block,
356 array_ptr: Air.Inst.Ref,
357 elem_index: Air.Inst.Ref,
358 elem_ptr_ty: Type,
359 ) !Air.Inst.Ref {
360 return block.addInst(.{
361 .tag = .ptr_elem_ptr,
362 .data = .{ .ty_pl = .{
363 .ty = try block.sema.addType(elem_ptr_ty),
364 .payload = try block.sema.addExtra(Air.Bin{
365 .lhs = array_ptr,
366 .rhs = elem_index,
367 }),
368 } },
369 });
370 }
371
354 pub fn addInst(block: *Block, inst: Air.Inst) error{OutOfMemory}!Air.Inst.Ref {372 pub fn addInst(block: *Block, inst: Air.Inst) error{OutOfMemory}!Air.Inst.Ref {
355 return Air.indexToRef(try block.addInstAsIndex(inst));373 return Air.indexToRef(try block.addInstAsIndex(inst));
356 }374 }
...@@ -11500,10 +11518,10 @@ fn elemPtr(...@@ -11500,10 +11518,10 @@ fn elemPtr(
11500 switch (array_ty.zigTypeTag()) {11518 switch (array_ty.zigTypeTag()) {
11501 .Pointer => {11519 .Pointer => {
11502 // In all below cases, we have to deref the ptr operand to get the actual array pointer.11520 // In all below cases, we have to deref the ptr operand to get the actual array pointer.
11503 const array = try sema.analyzeLoad(block, src, array_ptr, array_ptr_src);11521 const array = try sema.analyzeLoad(block, array_ptr_src, array_ptr, array_ptr_src);
11522 const result_ty = try array_ty.elemPtrType(sema.arena);
11504 switch (array_ty.ptrSize()) {11523 switch (array_ty.ptrSize()) {
11505 .Slice => {11524 .Slice => {
11506 const result_ty = try array_ty.elemPtrType(sema.arena);
11507 const maybe_slice_val = try sema.resolveDefinedValue(block, array_ptr_src, array);11525 const maybe_slice_val = try sema.resolveDefinedValue(block, array_ptr_src, array);
11508 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);11526 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
11509 const runtime_src = if (maybe_slice_val) |slice_val| rs: {11527 const runtime_src = if (maybe_slice_val) |slice_val| rs: {
...@@ -11516,14 +11534,28 @@ fn elemPtr(...@@ -11516,14 +11534,28 @@ fn elemPtr(
11516 try sema.requireRuntimeBlock(block, runtime_src);11534 try sema.requireRuntimeBlock(block, runtime_src);
11517 return block.addSliceElemPtr(array, elem_index, result_ty);11535 return block.addSliceElemPtr(array, elem_index, result_ty);
11518 },11536 },
11519 .Many, .C => return sema.fail(block, src, "TODO implement Sema for elemPtr for many/c pointer", .{}),11537 .Many, .C => {
11538 const maybe_ptr_val = try sema.resolveDefinedValue(block, array_ptr_src, array);
11539 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
11540
11541 const runtime_src = rs: {
11542 const ptr_val = maybe_ptr_val orelse break :rs array_ptr_src;
11543 const index_val = maybe_index_val orelse break :rs elem_index_src;
11544 const index = @intCast(usize, index_val.toUnsignedInt());
11545 const elem_ptr = try ptr_val.elemPtr(sema.arena, index);
11546 return sema.addConstant(result_ty, elem_ptr);
11547 };
11548
11549 try sema.requireRuntimeBlock(block, runtime_src);
11550 return block.addPtrElemPtr(array, elem_index, result_ty);
11551 },
11520 .One => {11552 .One => {
11521 assert(array_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable11553 assert(array_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable
11522 return sema.elemPtrArray(block, src, array, elem_index, elem_index_src);11554 return sema.elemPtrArray(block, array_ptr_src, array, elem_index, elem_index_src);
11523 },11555 },
11524 }11556 }
11525 },11557 },
11526 .Array => return sema.elemPtrArray(block, src, array_ptr, elem_index, elem_index_src),11558 .Array => return sema.elemPtrArray(block, array_ptr_src, array_ptr, elem_index, elem_index_src),
11527 .Vector => return sema.fail(block, src, "TODO implement Sema for elemPtr for vector", .{}),11559 .Vector => return sema.fail(block, src, "TODO implement Sema for elemPtr for vector", .{}),
11528 else => unreachable,11560 else => unreachable,
11529 }11561 }
...@@ -11560,21 +11592,30 @@ fn elemVal(...@@ -11560,21 +11592,30 @@ fn elemVal(
11560 return block.addBinOp(.slice_elem_val, array, elem_index);11592 return block.addBinOp(.slice_elem_val, array, elem_index);
11561 },11593 },
11562 .Many, .C => {11594 .Many, .C => {
11563 if (try sema.resolveDefinedValue(block, src, array)) |ptr_val| {11595 const maybe_ptr_val = try sema.resolveDefinedValue(block, array_src, array);
11564 _ = ptr_val;11596 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
11565 return sema.fail(block, src, "TODO implement Sema for elemVal for comptime known pointer", .{});11597
11566 }11598 const runtime_src = rs: {
11567 try sema.requireRuntimeBlock(block, src);11599 const ptr_val = maybe_ptr_val orelse break :rs array_src;
11600 const index_val = maybe_index_val orelse break :rs elem_index_src;
11601 const index = @intCast(usize, index_val.toUnsignedInt());
11602 const maybe_array_val = try ptr_val.pointerDeref(sema.arena);
11603 const array_val = maybe_array_val orelse break :rs array_src;
11604 const elem_val = try array_val.elemValue(sema.arena, index);
11605 return sema.addConstant(array_ty.elemType2(), elem_val);
11606 };
11607
11608 try sema.requireRuntimeBlock(block, runtime_src);
11568 return block.addBinOp(.ptr_elem_val, array, elem_index);11609 return block.addBinOp(.ptr_elem_val, array, elem_index);
11569 },11610 },
11570 .One => {11611 .One => {
11571 assert(array_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable11612 assert(array_ty.childType().zigTypeTag() == .Array); // Guaranteed by isIndexable
11572 const elem_ptr = try sema.elemPtr(block, src, array, elem_index, elem_index_src);11613 const elem_ptr = try sema.elemPtr(block, array_src, array, elem_index, elem_index_src);
11573 return sema.analyzeLoad(block, src, elem_ptr, elem_index_src);11614 return sema.analyzeLoad(block, array_src, elem_ptr, elem_index_src);
11574 },11615 },
11575 },11616 },
11576 .Array => {11617 .Array => {
11577 if (try sema.resolveMaybeUndefVal(block, src, array)) |array_val| {11618 if (try sema.resolveMaybeUndefVal(block, array_src, array)) |array_val| {
11578 const elem_ty = array_ty.childType();11619 const elem_ty = array_ty.childType();
11579 if (array_val.isUndef()) return sema.addConstUndef(elem_ty);11620 if (array_val.isUndef()) return sema.addConstUndef(elem_ty);
11580 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);11621 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
...@@ -11584,10 +11625,10 @@ fn elemVal(...@@ -11584,10 +11625,10 @@ fn elemVal(
11584 return sema.addConstant(elem_ty, elem_val);11625 return sema.addConstant(elem_ty, elem_val);
11585 }11626 }
11586 }11627 }
11587 try sema.requireRuntimeBlock(block, src);11628 try sema.requireRuntimeBlock(block, array_src);
11588 return block.addBinOp(.array_elem_val, array, elem_index);11629 return block.addBinOp(.array_elem_val, array, elem_index);
11589 },11630 },
11590 .Vector => return sema.fail(block, src, "TODO implement Sema for elemVal for vector", .{}),11631 .Vector => return sema.fail(block, array_src, "TODO implement Sema for elemVal for vector", .{}),
11591 else => unreachable,11632 else => unreachable,
11592 }11633 }
11593}11634}
...@@ -11615,16 +11656,7 @@ fn elemPtrArray(...@@ -11615,16 +11656,7 @@ fn elemPtrArray(
11615 }11656 }
11616 // TODO safety check for array bounds11657 // TODO safety check for array bounds
11617 try sema.requireRuntimeBlock(block, src);11658 try sema.requireRuntimeBlock(block, src);
11618 return block.addInst(.{11659 return block.addPtrElemPtr(array_ptr, elem_index, result_ty);
11619 .tag = .ptr_elem_ptr,
11620 .data = .{ .ty_pl = .{
11621 .ty = try sema.addType(result_ty),
11622 .payload = try sema.addExtra(Air.Bin{
11623 .lhs = array_ptr,
11624 .rhs = elem_index,
11625 }),
11626 } },
11627 });
11628}11660}
1162911661
11630fn coerce(11662fn coerce(