authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-08 21:56:42-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-08 21:56:42-07:00
log91e1414b50beac41b8eee5e3a9f8ef7bdc67fdef
tree119d835c02ac9677406a718696446f50b3f2d73c
parent6d616d82572045a594d97cef298e8453aa1ee189

stage2: implement array access to a global array


3 files changed, 69 insertions(+), 29 deletions(-)

src/AstGen.zig+1-1
...@@ -2349,7 +2349,7 @@ fn arrayAccess(...@@ -2349,7 +2349,7 @@ fn arrayAccess(
2349 ),2349 ),
2350 else => return rvalue(gz, scope, rl, try gz.addBin(2350 else => return rvalue(gz, scope, rl, try gz.addBin(
2351 .elem_val,2351 .elem_val,
2352 try expr(gz, scope, .none, node_datas[node].lhs),2352 try expr(gz, scope, .none_or_ref, node_datas[node].lhs),
2353 try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs),2353 try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs),
2354 ), node),2354 ), node),
2355 }2355 }
src/Sema.zig+42-28
...@@ -1430,9 +1430,6 @@ fn zirDbgStmtNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE...@@ -1430,9 +1430,6 @@ fn zirDbgStmtNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE
1430}1430}
14311431
1432fn zirDeclRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {1432fn zirDeclRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1433 const tracy = trace(@src());
1434 defer tracy.end();
1435
1436 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;1433 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1437 const src = inst_data.src();1434 const src = inst_data.src();
1438 const decl = sema.owner_decl.dependencies.entries.items[inst_data.payload_index].key;1435 const decl = sema.owner_decl.dependencies.entries.items[inst_data.payload_index].key;
...@@ -1440,9 +1437,6 @@ fn zirDeclRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -1440,9 +1437,6 @@ fn zirDeclRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
1440}1437}
14411438
1442fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {1439fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1443 const tracy = trace(@src());
1444 defer tracy.end();
1445
1446 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;1440 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1447 const src = inst_data.src();1441 const src = inst_data.src();
1448 const decl = sema.owner_decl.dependencies.entries.items[inst_data.payload_index].key;1442 const decl = sema.owner_decl.dependencies.entries.items[inst_data.payload_index].key;
...@@ -2571,7 +2565,10 @@ fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError...@@ -2571,7 +2565,10 @@ fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
25712565
2572 const bin_inst = sema.code.instructions.items(.data)[inst].bin;2566 const bin_inst = sema.code.instructions.items(.data)[inst].bin;
2573 const array = try sema.resolveInst(bin_inst.lhs);2567 const array = try sema.resolveInst(bin_inst.lhs);
2574 const array_ptr = try sema.analyzeRef(block, sema.src, array);2568 const array_ptr = if (array.ty.zigTypeTag() == .Pointer)
2569 array
2570 else
2571 try sema.analyzeRef(block, sema.src, array);
2575 const elem_index = try sema.resolveInst(bin_inst.rhs);2572 const elem_index = try sema.resolveInst(bin_inst.rhs);
2576 const result_ptr = try sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src);2573 const result_ptr = try sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src);
2577 return sema.analyzeLoad(block, sema.src, result_ptr, sema.src);2574 return sema.analyzeLoad(block, sema.src, result_ptr, sema.src);
...@@ -2586,7 +2583,10 @@ fn zirElemValNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE...@@ -2586,7 +2583,10 @@ fn zirElemValNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE
2586 const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };2583 const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node };
2587 const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;2584 const extra = sema.code.extraData(zir.Inst.Bin, inst_data.payload_index).data;
2588 const array = try sema.resolveInst(extra.lhs);2585 const array = try sema.resolveInst(extra.lhs);
2589 const array_ptr = try sema.analyzeRef(block, src, array);2586 const array_ptr = if (array.ty.zigTypeTag() == .Pointer)
2587 array
2588 else
2589 try sema.analyzeRef(block, src, array);
2590 const elem_index = try sema.resolveInst(extra.rhs);2590 const elem_index = try sema.resolveInst(extra.rhs);
2591 const result_ptr = try sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src);2591 const result_ptr = try sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src);
2592 return sema.analyzeLoad(block, src, result_ptr, src);2592 return sema.analyzeLoad(block, src, result_ptr, src);
...@@ -4786,37 +4786,51 @@ fn elemPtr(...@@ -4786,37 +4786,51 @@ fn elemPtr(
4786 elem_index: *Inst,4786 elem_index: *Inst,
4787 elem_index_src: LazySrcLoc,4787 elem_index_src: LazySrcLoc,
4788) InnerError!*Inst {4788) InnerError!*Inst {
4789 const elem_ty = switch (array_ptr.ty.zigTypeTag()) {4789 const array_ty = switch (array_ptr.ty.zigTypeTag()) {
4790 .Pointer => array_ptr.ty.elemType(),4790 .Pointer => array_ptr.ty.elemType(),
4791 else => return sema.mod.fail(&block.base, array_ptr.src, "expected pointer, found '{}'", .{array_ptr.ty}),4791 else => return sema.mod.fail(&block.base, array_ptr.src, "expected pointer, found '{}'", .{array_ptr.ty}),
4792 };4792 };
4793 if (!elem_ty.isIndexable()) {4793 if (!array_ty.isIndexable()) {
4794 return sema.mod.fail(&block.base, src, "array access of non-array type '{}'", .{elem_ty});4794 return sema.mod.fail(&block.base, src, "array access of non-array type '{}'", .{array_ty});
4795 }4795 }
47964796 if (array_ty.isSinglePointer() and array_ty.elemType().zigTypeTag() == .Array) {
4797 if (elem_ty.isSinglePointer() and elem_ty.elemType().zigTypeTag() == .Array) {
4798 // we have to deref the ptr operand to get the actual array pointer4797 // we have to deref the ptr operand to get the actual array pointer
4799 const array_ptr_deref = try sema.analyzeLoad(block, src, array_ptr, array_ptr.src);4798 const array_ptr_deref = try sema.analyzeLoad(block, src, array_ptr, array_ptr.src);
4800 if (array_ptr_deref.value()) |array_ptr_val| {4799 return sema.elemPtrArray(block, src, array_ptr_deref, elem_index, elem_index_src);
4801 if (elem_index.value()) |index_val| {4800 }
4802 // Both array pointer and index are compile-time known.4801 if (array_ty.zigTypeTag() == .Array) {
4803 const index_u64 = index_val.toUnsignedInt();4802 return sema.elemPtrArray(block, src, array_ptr, elem_index, elem_index_src);
4804 // @intCast here because it would have been impossible to construct a value that
4805 // required a larger index.
4806 const elem_ptr = try array_ptr_val.elemPtr(sema.arena, @intCast(usize, index_u64));
4807 const pointee_type = elem_ty.elemType().elemType();
4808
4809 return sema.mod.constInst(sema.arena, src, .{
4810 .ty = try Type.Tag.single_const_pointer.create(sema.arena, pointee_type),
4811 .val = elem_ptr,
4812 });
4813 }
4814 }
4815 }4803 }
48164804
4817 return sema.mod.fail(&block.base, src, "TODO implement more analyze elemptr", .{});4805 return sema.mod.fail(&block.base, src, "TODO implement more analyze elemptr", .{});
4818}4806}
48194807
4808fn elemPtrArray(
4809 sema: *Sema,
4810 block: *Scope.Block,
4811 src: LazySrcLoc,
4812 array_ptr: *Inst,
4813 elem_index: *Inst,
4814 elem_index_src: LazySrcLoc,
4815) InnerError!*Inst {
4816 if (array_ptr.value()) |array_ptr_val| {
4817 if (elem_index.value()) |index_val| {
4818 // Both array pointer and index are compile-time known.
4819 const index_u64 = index_val.toUnsignedInt();
4820 // @intCast here because it would have been impossible to construct a value that
4821 // required a larger index.
4822 const elem_ptr = try array_ptr_val.elemPtr(sema.arena, @intCast(usize, index_u64));
4823 const pointee_type = array_ptr.ty.elemType().elemType();
4824
4825 return sema.mod.constInst(sema.arena, src, .{
4826 .ty = try Type.Tag.single_const_pointer.create(sema.arena, pointee_type),
4827 .val = elem_ptr,
4828 });
4829 }
4830 }
4831 return sema.mod.fail(&block.base, src, "TODO implement more analyze elemptr for arrays", .{});
4832}
4833
4820fn coerce(4834fn coerce(
4821 sema: *Sema,4835 sema: *Sema,
4822 block: *Scope.Block,4836 block: *Scope.Block,
test/stage2/test.zig+26
...@@ -941,6 +941,32 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -941,6 +941,32 @@ pub fn addCases(ctx: *TestContext) !void {
941 "",941 "",
942 );942 );
943943
944 // Array access to a global array.
945 case.addCompareOutput(
946 \\const hello = "hello".*;
947 \\export fn _start() noreturn {
948 \\ assert(hello[1] == 'e');
949 \\
950 \\ exit();
951 \\}
952 \\
953 \\pub fn assert(ok: bool) void {
954 \\ if (!ok) unreachable; // assertion failure
955 \\}
956 \\
957 \\fn exit() noreturn {
958 \\ asm volatile ("syscall"
959 \\ :
960 \\ : [number] "{rax}" (231),
961 \\ [arg1] "{rdi}" (0)
962 \\ : "rcx", "r11", "memory"
963 \\ );
964 \\ unreachable;
965 \\}
966 ,
967 "",
968 );
969
944 // 64bit set stack970 // 64bit set stack
945 case.addCompareOutput(971 case.addCompareOutput(
946 \\export fn _start() noreturn {972 \\export fn _start() noreturn {