| ... | @@ -6111,35 +6111,36 @@ fn zirArrayCat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -6111,35 +6111,36 @@ fn zirArrayCat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 6111 | if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| { | 6111 | if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| { |
| 6112 | if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val| { | 6112 | if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val| { |
| 6113 | const final_len = lhs_info.len + rhs_info.len; | 6113 | const final_len = lhs_info.len + rhs_info.len; |
| 6114 | if (lhs_ty.zigTypeTag() == .Pointer) { | 6114 | const is_pointer = lhs_ty.zigTypeTag() == .Pointer; |
| 6115 | var anon_decl = try block.startAnonDecl(); | 6115 | var anon_decl = try block.startAnonDecl(); |
| 6116 | defer anon_decl.deinit(); | 6116 | defer anon_decl.deinit(); |
| 6117 | | 6117 | |
| 6118 | const lhs_sub_val = (try lhs_val.pointerDeref(anon_decl.arena())).?; | 6118 | const lhs_sub_val = if (is_pointer) (try lhs_val.pointerDeref(anon_decl.arena())).? else lhs_val; |
| 6119 | const rhs_sub_val = (try rhs_val.pointerDeref(anon_decl.arena())).?; | 6119 | const rhs_sub_val = if (is_pointer) (try rhs_val.pointerDeref(anon_decl.arena())).? else rhs_val; |
| 6120 | const buf = try anon_decl.arena().alloc(Value, final_len); | 6120 | const buf = try anon_decl.arena().alloc(Value, final_len); |
| 6121 | { | 6121 | { |
| 6122 | var i: u64 = 0; | 6122 | var i: u64 = 0; |
| 6123 | while (i < lhs_info.len) : (i += 1) { | 6123 | while (i < lhs_info.len) : (i += 1) { |
| 6124 | const val = try lhs_sub_val.elemValue(sema.arena, i); | 6124 | const val = try lhs_sub_val.elemValue(sema.arena, i); |
| 6125 | buf[i] = try val.copy(anon_decl.arena()); | 6125 | buf[i] = try val.copy(anon_decl.arena()); |
| 6126 | } | | |
| 6127 | } | 6126 | } |
| 6128 | { | 6127 | } |
| 6129 | var i: u64 = 0; | 6128 | { |
| 6130 | while (i < rhs_info.len) : (i += 1) { | 6129 | var i: u64 = 0; |
| 6131 | const val = try rhs_sub_val.elemValue(sema.arena, i); | 6130 | while (i < rhs_info.len) : (i += 1) { |
| 6132 | buf[lhs_info.len + i] = try val.copy(anon_decl.arena()); | 6131 | const val = try rhs_sub_val.elemValue(sema.arena, i); |
| 6133 | } | 6132 | buf[lhs_info.len + i] = try val.copy(anon_decl.arena()); |
| 6134 | } | 6133 | } |
| 6135 | const ty = if (res_sent) |rs| | | |
| 6136 | try Type.Tag.array_sentinel.create(anon_decl.arena(), .{ .len = final_len, .elem_type = lhs_info.elem_type, .sentinel = rs }) | | |
| 6137 | else | | |
| 6138 | try Type.Tag.array.create(anon_decl.arena(), .{ .len = final_len, .elem_type = lhs_info.elem_type }); | | |
| 6139 | const val = try Value.Tag.array.create(anon_decl.arena(), buf); | | |
| 6140 | return sema.analyzeDeclRef(try anon_decl.finish(ty, val)); | | |
| 6141 | } | 6134 | } |
| 6142 | return sema.mod.fail(&block.base, lhs_src, "TODO array_cat more types of Values", .{}); | 6135 | const ty = if (res_sent) |rs| |
| | 6136 | try Type.Tag.array_sentinel.create(anon_decl.arena(), .{ .len = final_len, .elem_type = lhs_info.elem_type, .sentinel = rs }) |
| | 6137 | else |
| | 6138 | try Type.Tag.array.create(anon_decl.arena(), .{ .len = final_len, .elem_type = lhs_info.elem_type }); |
| | 6139 | const val = try Value.Tag.array.create(anon_decl.arena(), buf); |
| | 6140 | return if (is_pointer) |
| | 6141 | sema.analyzeDeclRef(try anon_decl.finish(ty, val)) |
| | 6142 | else |
| | 6143 | sema.analyzeDeclVal(block, .unneeded, try anon_decl.finish(ty, val)); |
| 6143 | } else { | 6144 | } else { |
| 6144 | return sema.mod.fail(&block.base, lhs_src, "TODO runtime array_cat", .{}); | 6145 | return sema.mod.fail(&block.base, lhs_src, "TODO runtime array_cat", .{}); |
| 6145 | } | 6146 | } |
| ... | @@ -6179,29 +6180,30 @@ fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -6179,29 +6180,30 @@ fn zirArrayMul(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 6179 | | 6180 | |
| 6180 | const final_len = std.math.mul(u64, mulinfo.len, tomulby) catch return sema.mod.fail(&block.base, rhs_src, "operation results in overflow", .{}); | 6181 | const final_len = std.math.mul(u64, mulinfo.len, tomulby) catch return sema.mod.fail(&block.base, rhs_src, "operation results in overflow", .{}); |
| 6181 | if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| { | 6182 | if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| { |
| 6182 | if (lhs_ty.zigTypeTag() == .Pointer) { | 6183 | var anon_decl = try block.startAnonDecl(); |
| 6183 | var anon_decl = try block.startAnonDecl(); | 6184 | defer anon_decl.deinit(); |
| 6184 | defer anon_decl.deinit(); | 6185 | const lhs_sub_val = if (lhs_ty.zigTypeTag() == .Pointer) (try lhs_val.pointerDeref(anon_decl.arena())).? else lhs_val; |
| 6185 | const lhs_sub_val = (try lhs_val.pointerDeref(anon_decl.arena())).?; | 6186 | const final_ty = if (mulinfo.sentinel) |sent| |
| 6186 | | 6187 | try Type.Tag.array_sentinel.create(anon_decl.arena(), .{ .len = final_len, .elem_type = mulinfo.elem_type, .sentinel = sent }) |
| 6187 | const final_ty = if (mulinfo.sentinel) |sent| | 6188 | else |
| 6188 | try Type.Tag.array_sentinel.create(anon_decl.arena(), .{ .len = final_len, .elem_type = mulinfo.elem_type, .sentinel = sent }) | 6189 | try Type.Tag.array.create(anon_decl.arena(), .{ .len = final_len, .elem_type = mulinfo.elem_type }); |
| 6189 | else | 6190 | const buf = try anon_decl.arena().alloc(Value, final_len); |
| 6190 | try Type.Tag.array.create(anon_decl.arena(), .{ .len = final_len, .elem_type = mulinfo.elem_type }); | 6191 | |
| 6191 | | 6192 | // the actual loop |
| 6192 | const buf = try anon_decl.arena().alloc(Value, final_len); | 6193 | var i: u64 = 0; |
| 6193 | var i: u64 = 0; | 6194 | while (i < tomulby) : (i += 1) { |
| 6194 | while (i < tomulby) : (i += 1) { | 6195 | var j: u64 = 0; |
| 6195 | var j: u64 = 0; | 6196 | while (j < mulinfo.len) : (j += 1) { |
| 6196 | while (j < mulinfo.len) : (j += 1) { | 6197 | const val = try lhs_sub_val.elemValue(sema.arena, j); |
| 6197 | const val = try lhs_sub_val.elemValue(sema.arena, j); | 6198 | buf[mulinfo.len * i + j] = try val.copy(anon_decl.arena()); |
| 6198 | buf[mulinfo.len * i + j] = try val.copy(anon_decl.arena()); | | |
| 6199 | } | | |
| 6200 | } | 6199 | } |
| 6201 | const val = try Value.Tag.array.create(anon_decl.arena(), buf); | 6200 | } |
| | 6201 | const val = try Value.Tag.array.create(anon_decl.arena(), buf); |
| | 6202 | if (lhs_ty.zigTypeTag() == .Pointer) { |
| 6202 | return sema.analyzeDeclRef(try anon_decl.finish(final_ty, val)); | 6203 | return sema.analyzeDeclRef(try anon_decl.finish(final_ty, val)); |
| | 6204 | } else { |
| | 6205 | return sema.analyzeDeclVal(block, .unneeded, try anon_decl.finish(final_ty, val)); |
| 6203 | } | 6206 | } |
| 6204 | return sema.mod.fail(&block.base, lhs_src, "TODO array_mul more types of Values", .{}); | | |
| 6205 | } | 6207 | } |
| 6206 | return sema.mod.fail(&block.base, lhs_src, "TODO runtime array_mul", .{}); | 6208 | return sema.mod.fail(&block.base, lhs_src, "TODO runtime array_mul", .{}); |
| 6207 | } | 6209 | } |
| ... | @@ -8227,8 +8229,49 @@ fn zirArrayInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: | ... | @@ -8227,8 +8229,49 @@ fn zirArrayInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: |
| 8227 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 8229 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 8228 | const src = inst_data.src(); | 8230 | const src = inst_data.src(); |
| 8229 | | 8231 | |
| 8230 | _ = is_ref; | 8232 | const extra = sema.code.extraData(Zir.Inst.MultiOp, inst_data.payload_index); |
| 8231 | return sema.mod.fail(&block.base, src, "TODO: Sema.zirArrayInit", .{}); | 8233 | const args = sema.code.refSlice(extra.end, extra.data.operands_len); |
| | 8234 | |
| | 8235 | var resolved_args = try sema.mod.gpa.alloc(Air.Inst.Ref, args.len); |
| | 8236 | for (args) |arg, i| resolved_args[i] = sema.resolveInst(arg); |
| | 8237 | |
| | 8238 | var all_args_comptime = for (resolved_args) |arg| { |
| | 8239 | if ((try sema.resolveMaybeUndefVal(block, src, arg)) == null) break false; |
| | 8240 | } else true; |
| | 8241 | |
| | 8242 | if (all_args_comptime) { |
| | 8243 | var anon_decl = try block.startAnonDecl(); |
| | 8244 | defer anon_decl.deinit(); |
| | 8245 | assert(!(resolved_args.len == 0)); |
| | 8246 | const final_ty = try Type.Tag.array.create(anon_decl.arena(), .{ .len = resolved_args.len, .elem_type = sema.typeOf(resolved_args[0]) }); |
| | 8247 | const buf = try anon_decl.arena().alloc(Value, resolved_args.len); |
| | 8248 | for (resolved_args) |arg, i| { |
| | 8249 | buf[i] = (try sema.resolveMaybeUndefVal(block, src, arg)).?; |
| | 8250 | } |
| | 8251 | |
| | 8252 | const val = try Value.Tag.array.create(anon_decl.arena(), buf); |
| | 8253 | if (is_ref) |
| | 8254 | return sema.analyzeDeclRef(try anon_decl.finish(final_ty, val)) |
| | 8255 | else |
| | 8256 | return sema.analyzeDeclVal(block, .unneeded, try anon_decl.finish(final_ty, val)); |
| | 8257 | } |
| | 8258 | |
| | 8259 | assert(!(resolved_args.len == 0)); |
| | 8260 | const array_ty = try Type.Tag.array.create(sema.arena, .{ .len = resolved_args.len, .elem_type = sema.typeOf(resolved_args[0]) }); |
| | 8261 | const final_ty = try Type.ptr(sema.arena, .{ |
| | 8262 | .pointee_type = array_ty, |
| | 8263 | .@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local), |
| | 8264 | }); |
| | 8265 | const alloc = try block.addTy(.alloc, final_ty); |
| | 8266 | |
| | 8267 | for (resolved_args) |arg, i| { |
| | 8268 | const pointer_to_array_at_index = try block.addBinOp(.ptr_elem_ptr, alloc, try sema.addIntUnsigned(Type.initTag(.u64), i)); |
| | 8269 | _ = try block.addBinOp(.store, pointer_to_array_at_index, arg); |
| | 8270 | } |
| | 8271 | return if (is_ref) |
| | 8272 | alloc |
| | 8273 | else |
| | 8274 | try sema.analyzeLoad(block, .unneeded, alloc, .unneeded); |
| 8232 | } | 8275 | } |
| 8233 | | 8276 | |
| 8234 | fn zirArrayInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { | 8277 | fn zirArrayInitAnon(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: bool) CompileError!Air.Inst.Ref { |