| author | |
| committer | |
| log | 76335bc7badd41af0ebb7dd196e1550d7e99d8e7 |
| tree | 4057c1def983d9ea39d67e617e52820fed61331f |
| parent | 601ac82041653adc2acbcfd947a54286944df9df |
New ZIR instruction: elem_ptr_imm
This saves some memory for array literals since the element indexes are
communicated as immediate values rather than as references to other ZIR
instructions.6 files changed, 94 insertions(+), 41 deletions(-)
src/AstGen.zig+8-8| ... | @@ -1352,15 +1352,14 @@ fn arrayInitExprRlPtr( | ... | @@ -1352,15 +1352,14 @@ fn arrayInitExprRlPtr( |
| 1352 | defer gpa.free(elem_ptr_list); | 1352 | defer gpa.free(elem_ptr_list); |
| 1353 | 1353 | ||
| 1354 | for (elements) |elem_init, i| { | 1354 | for (elements) |elem_init, i| { |
| 1355 | const index_inst = try gz.addInt(i); | 1355 | const elem_ptr = try gz.addPlNode(.elem_ptr_imm, elem_init, Zir.Inst.ElemPtrImm{ |
| 1356 | const elem_ptr = try gz.addPlNode(.elem_ptr_node, elem_init, Zir.Inst.Bin{ | 1356 | .ptr = result_ptr, |
| 1357 | .lhs = result_ptr, | 1357 | .index = @intCast(u32, i), |
| 1358 | .rhs = index_inst, | ||
| 1359 | }); | 1358 | }); |
| 1360 | elem_ptr_list[i] = refToIndex(elem_ptr).?; | 1359 | elem_ptr_list[i] = refToIndex(elem_ptr).?; |
| 1361 | _ = try expr(gz, scope, .{ .ptr = elem_ptr }, elem_init); | 1360 | _ = try expr(gz, scope, .{ .ptr = elem_ptr }, elem_init); |
| 1362 | } | 1361 | } |
| 1363 | _ = try gz.addPlNode(.validate_array_init_ptr, node, Zir.Inst.Block{ | 1362 | _ = try gz.addPlNode(.validate_array_init, node, Zir.Inst.Block{ |
| 1364 | .body_len = @intCast(u32, elem_ptr_list.len), | 1363 | .body_len = @intCast(u32, elem_ptr_list.len), |
| 1365 | }); | 1364 | }); |
| 1366 | try astgen.extra.appendSlice(gpa, elem_ptr_list); | 1365 | try astgen.extra.appendSlice(gpa, elem_ptr_list); |
| ... | @@ -1539,7 +1538,7 @@ fn structInitExprRlPtrInner( | ... | @@ -1539,7 +1538,7 @@ fn structInitExprRlPtrInner( |
| 1539 | field_ptr_list[i] = refToIndex(field_ptr).?; | 1538 | field_ptr_list[i] = refToIndex(field_ptr).?; |
| 1540 | _ = try expr(gz, scope, .{ .ptr = field_ptr }, field_init); | 1539 | _ = try expr(gz, scope, .{ .ptr = field_ptr }, field_init); |
| 1541 | } | 1540 | } |
| 1542 | _ = try gz.addPlNode(.validate_struct_init_ptr, node, Zir.Inst.Block{ | 1541 | _ = try gz.addPlNode(.validate_struct_init, node, Zir.Inst.Block{ |
| 1543 | .body_len = @intCast(u32, field_ptr_list.len), | 1542 | .body_len = @intCast(u32, field_ptr_list.len), |
| 1544 | }); | 1543 | }); |
| 1545 | try astgen.extra.appendSlice(gpa, field_ptr_list); | 1544 | try astgen.extra.appendSlice(gpa, field_ptr_list); |
| ... | @@ -2040,6 +2039,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner | ... | @@ -2040,6 +2039,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner |
| 2040 | .elem_ptr, | 2039 | .elem_ptr, |
| 2041 | .elem_val, | 2040 | .elem_val, |
| 2042 | .elem_ptr_node, | 2041 | .elem_ptr_node, |
| 2042 | .elem_ptr_imm, | ||
| 2043 | .elem_val_node, | 2043 | .elem_val_node, |
| 2044 | .field_ptr, | 2044 | .field_ptr, |
| 2045 | .field_val, | 2045 | .field_val, |
| ... | @@ -2246,8 +2246,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner | ... | @@ -2246,8 +2246,8 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner |
| 2246 | .store_to_block_ptr, | 2246 | .store_to_block_ptr, |
| 2247 | .store_to_inferred_ptr, | 2247 | .store_to_inferred_ptr, |
| 2248 | .resolve_inferred_alloc, | 2248 | .resolve_inferred_alloc, |
| 2249 | .validate_struct_init_ptr, | 2249 | .validate_struct_init, |
| 2250 | .validate_array_init_ptr, | 2250 | .validate_array_init, |
| 2251 | .set_align_stack, | 2251 | .set_align_stack, |
| 2252 | .set_cold, | 2252 | .set_cold, |
| 2253 | .set_float_mode, | 2253 | .set_float_mode, |
src/Sema.zig+39-14| ... | @@ -479,6 +479,7 @@ pub fn analyzeBody( | ... | @@ -479,6 +479,7 @@ pub fn analyzeBody( |
| 479 | .load => try sema.zirLoad(block, inst), | 479 | .load => try sema.zirLoad(block, inst), |
| 480 | .elem_ptr => try sema.zirElemPtr(block, inst), | 480 | .elem_ptr => try sema.zirElemPtr(block, inst), |
| 481 | .elem_ptr_node => try sema.zirElemPtrNode(block, inst), | 481 | .elem_ptr_node => try sema.zirElemPtrNode(block, inst), |
| 482 | .elem_ptr_imm => try sema.zirElemPtrImm(block, inst), | ||
| 482 | .elem_val => try sema.zirElemVal(block, inst), | 483 | .elem_val => try sema.zirElemVal(block, inst), |
| 483 | .elem_val_node => try sema.zirElemValNode(block, inst), | 484 | .elem_val_node => try sema.zirElemValNode(block, inst), |
| 484 | .elem_type => try sema.zirElemType(block, inst), | 485 | .elem_type => try sema.zirElemType(block, inst), |
| ... | @@ -741,13 +742,13 @@ pub fn analyzeBody( | ... | @@ -741,13 +742,13 @@ pub fn analyzeBody( |
| 741 | i += 1; | 742 | i += 1; |
| 742 | continue; | 743 | continue; |
| 743 | }, | 744 | }, |
| 744 | .validate_struct_init_ptr => { | 745 | .validate_struct_init => { |
| 745 | try sema.zirValidateStructInitPtr(block, inst); | 746 | try sema.zirValidateStructInit(block, inst); |
| 746 | i += 1; | 747 | i += 1; |
| 747 | continue; | 748 | continue; |
| 748 | }, | 749 | }, |
| 749 | .validate_array_init_ptr => { | 750 | .validate_array_init => { |
| 750 | try sema.zirValidateArrayInitPtr(block, inst); | 751 | try sema.zirValidateArrayInit(block, inst); |
| 751 | i += 1; | 752 | i += 1; |
| 752 | continue; | 753 | continue; |
| 753 | }, | 754 | }, |
| ... | @@ -2106,7 +2107,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -2106,7 +2107,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 2106 | } | 2107 | } |
| 2107 | } | 2108 | } |
| 2108 | 2109 | ||
| 2109 | fn zirValidateStructInitPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 2110 | fn zirValidateStructInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 2110 | const tracy = trace(@src()); | 2111 | const tracy = trace(@src()); |
| 2111 | defer tracy.end(); | 2112 | defer tracy.end(); |
| 2112 | 2113 | ||
| ... | @@ -2117,15 +2118,15 @@ fn zirValidateStructInitPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Co | ... | @@ -2117,15 +2118,15 @@ fn zirValidateStructInitPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Co |
| 2117 | const field_ptr_data = sema.code.instructions.items(.data)[instrs[0]].pl_node; | 2118 | const field_ptr_data = sema.code.instructions.items(.data)[instrs[0]].pl_node; |
| 2118 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; | 2119 | const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; |
| 2119 | const object_ptr = sema.resolveInst(field_ptr_extra.lhs); | 2120 | const object_ptr = sema.resolveInst(field_ptr_extra.lhs); |
| 2120 | const agg_ty = sema.typeOf(object_ptr).elemType(); | 2121 | const agg_ty = sema.typeOf(object_ptr).childType(); |
| 2121 | switch (agg_ty.zigTypeTag()) { | 2122 | switch (agg_ty.zigTypeTag()) { |
| 2122 | .Struct => return sema.validateStructInitPtr( | 2123 | .Struct => return sema.validateStructInit( |
| 2123 | block, | 2124 | block, |
| 2124 | agg_ty.castTag(.@"struct").?.data, | 2125 | agg_ty.castTag(.@"struct").?.data, |
| 2125 | init_src, | 2126 | init_src, |
| 2126 | instrs, | 2127 | instrs, |
| 2127 | ), | 2128 | ), |
| 2128 | .Union => return sema.validateUnionInitPtr( | 2129 | .Union => return sema.validateUnionInit( |
| 2129 | block, | 2130 | block, |
| 2130 | agg_ty.cast(Type.Payload.Union).?.data, | 2131 | agg_ty.cast(Type.Payload.Union).?.data, |
| 2131 | init_src, | 2132 | init_src, |
| ... | @@ -2136,7 +2137,7 @@ fn zirValidateStructInitPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Co | ... | @@ -2136,7 +2137,7 @@ fn zirValidateStructInitPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Co |
| 2136 | } | 2137 | } |
| 2137 | } | 2138 | } |
| 2138 | 2139 | ||
| 2139 | fn validateUnionInitPtr( | 2140 | fn validateUnionInit( |
| 2140 | sema: *Sema, | 2141 | sema: *Sema, |
| 2141 | block: *Block, | 2142 | block: *Block, |
| 2142 | union_obj: *Module.Union, | 2143 | union_obj: *Module.Union, |
| ... | @@ -2175,7 +2176,7 @@ fn validateUnionInitPtr( | ... | @@ -2175,7 +2176,7 @@ fn validateUnionInitPtr( |
| 2175 | _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag); | 2176 | _ = try block.addBinOp(.set_union_tag, union_ptr, new_tag); |
| 2176 | } | 2177 | } |
| 2177 | 2178 | ||
| 2178 | fn validateStructInitPtr( | 2179 | fn validateStructInit( |
| 2179 | sema: *Sema, | 2180 | sema: *Sema, |
| 2180 | block: *Block, | 2181 | block: *Block, |
| 2181 | struct_obj: *Module.Struct, | 2182 | struct_obj: *Module.Struct, |
| ... | @@ -2239,10 +2240,22 @@ fn validateStructInitPtr( | ... | @@ -2239,10 +2240,22 @@ fn validateStructInitPtr( |
| 2239 | } | 2240 | } |
| 2240 | } | 2241 | } |
| 2241 | 2242 | ||
| 2242 | fn zirValidateArrayInitPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 2243 | fn zirValidateArrayInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 2243 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 2244 | const validate_inst = sema.code.instructions.items(.data)[inst].pl_node; |
| 2244 | const src = inst_data.src(); | 2245 | const init_src = validate_inst.src(); |
| 2245 | return sema.fail(block, src, "TODO implement Sema.zirValidateArrayInitPtr", .{}); | 2246 | const validate_extra = sema.code.extraData(Zir.Inst.Block, validate_inst.payload_index); |
| 2247 | const instrs = sema.code.extra[validate_extra.end..][0..validate_extra.data.body_len]; | ||
| 2248 | const elem_ptr_data = sema.code.instructions.items(.data)[instrs[0]].pl_node; | ||
| 2249 | const elem_ptr_extra = sema.code.extraData(Zir.Inst.ElemPtrImm, elem_ptr_data.payload_index).data; | ||
| 2250 | const array_ptr = sema.resolveInst(elem_ptr_extra.ptr); | ||
| 2251 | const array_ty = sema.typeOf(array_ptr).childType(); | ||
| 2252 | const array_len = array_ty.arrayLen(); | ||
| 2253 | |||
| 2254 | if (instrs.len != array_len) { | ||
| 2255 | return sema.fail(block, init_src, "expected {d} array elements; found {d}", .{ | ||
| 2256 | array_len, instrs.len, | ||
| 2257 | }); | ||
| 2258 | } | ||
| 2246 | } | 2259 | } |
| 2247 | 2260 | ||
| 2248 | fn failWithBadFieldAccess( | 2261 | fn failWithBadFieldAccess( |
| ... | @@ -5169,6 +5182,18 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -5169,6 +5182,18 @@ fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 5169 | return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src); | 5182 | return sema.elemPtr(block, src, array_ptr, elem_index, elem_index_src); |
| 5170 | } | 5183 | } |
| 5171 | 5184 | ||
| 5185 | fn zirElemPtrImm(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | ||
| 5186 | const tracy = trace(@src()); | ||
| 5187 | defer tracy.end(); | ||
| 5188 | |||
| 5189 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | ||
| 5190 | const src = inst_data.src(); | ||
| 5191 | const extra = sema.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data; | ||
| 5192 | const array_ptr = sema.resolveInst(extra.ptr); | ||
| 5193 | const elem_index = try sema.addIntUnsigned(Type.usize, extra.index); | ||
| 5194 | return sema.elemPtr(block, src, array_ptr, elem_index, src); | ||
| 5195 | } | ||
| 5196 | |||
| 5172 | fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5197 | fn zirSliceStart(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 5173 | const tracy = trace(@src()); | 5198 | const tracy = trace(@src()); |
| 5174 | defer tracy.end(); | 5199 | defer tracy.end(); |
src/Zir.zig+20-8| ... | @@ -344,6 +344,11 @@ pub const Inst = struct { | ... | @@ -344,6 +344,11 @@ pub const Inst = struct { |
| 344 | /// Same as `elem_ptr` except also stores a source location node. | 344 | /// Same as `elem_ptr` except also stores a source location node. |
| 345 | /// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`. | 345 | /// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`. |
| 346 | elem_ptr_node, | 346 | elem_ptr_node, |
| 347 | /// Same as `elem_ptr_node` except the index is stored immediately rather than | ||
| 348 | /// as a reference to another ZIR instruction. | ||
| 349 | /// Uses the `pl_node` union field. AST node is an element inside array initialization | ||
| 350 | /// syntax. Payload is `ElemPtrImm`. | ||
| 351 | elem_ptr_imm, | ||
| 347 | /// Given an array, slice, or pointer, returns the element at the provided index. | 352 | /// Given an array, slice, or pointer, returns the element at the provided index. |
| 348 | /// Uses the `bin` union field. Source location is implied to be the same | 353 | /// Uses the `bin` union field. Source location is implied to be the same |
| 349 | /// as the previous instruction. | 354 | /// as the previous instruction. |
| ... | @@ -675,14 +680,14 @@ pub const Inst = struct { | ... | @@ -675,14 +680,14 @@ pub const Inst = struct { |
| 675 | /// This instruction asserts that there is at least one field_ptr instruction, | 680 | /// This instruction asserts that there is at least one field_ptr instruction, |
| 676 | /// because it must use one of them to find out the struct type. | 681 | /// because it must use one of them to find out the struct type. |
| 677 | /// Uses the `pl_node` field. Payload is `Block`. | 682 | /// Uses the `pl_node` field. Payload is `Block`. |
| 678 | validate_struct_init_ptr, | 683 | validate_struct_init, |
| 679 | /// Given a set of `elem_ptr_node` instructions, assumes they are all part of an | 684 | /// Given a set of `elem_ptr_imm` instructions, assumes they are all part of an |
| 680 | /// array initialization expression, and emits a compile error if the number of | 685 | /// array initialization expression, and emits a compile error if the number of |
| 681 | /// elements does not match the array type. | 686 | /// elements does not match the array type. |
| 682 | /// This instruction asserts that there is at least one elem_ptr_node instruction, | 687 | /// This instruction asserts that there is at least one `elem_ptr_imm` instruction, |
| 683 | /// because it must use one of them to find out the array type. | 688 | /// because it must use one of them to find out the array type. |
| 684 | /// Uses the `pl_node` field. Payload is `Block`. | 689 | /// Uses the `pl_node` field. Payload is `Block`. |
| 685 | validate_array_init_ptr, | 690 | validate_array_init, |
| 686 | /// A struct literal with a specified type, with no fields. | 691 | /// A struct literal with a specified type, with no fields. |
| 687 | /// Uses the `un_node` field. | 692 | /// Uses the `un_node` field. |
| 688 | struct_init_empty, | 693 | struct_init_empty, |
| ... | @@ -1023,6 +1028,7 @@ pub const Inst = struct { | ... | @@ -1023,6 +1028,7 @@ pub const Inst = struct { |
| 1023 | .elem_ptr, | 1028 | .elem_ptr, |
| 1024 | .elem_val, | 1029 | .elem_val, |
| 1025 | .elem_ptr_node, | 1030 | .elem_ptr_node, |
| 1031 | .elem_ptr_imm, | ||
| 1026 | .elem_val_node, | 1032 | .elem_val_node, |
| 1027 | .ensure_result_used, | 1033 | .ensure_result_used, |
| 1028 | .ensure_result_non_error, | 1034 | .ensure_result_non_error, |
| ... | @@ -1114,8 +1120,8 @@ pub const Inst = struct { | ... | @@ -1114,8 +1120,8 @@ pub const Inst = struct { |
| 1114 | .switch_block_ref_else_multi, | 1120 | .switch_block_ref_else_multi, |
| 1115 | .switch_block_ref_under, | 1121 | .switch_block_ref_under, |
| 1116 | .switch_block_ref_under_multi, | 1122 | .switch_block_ref_under_multi, |
| 1117 | .validate_struct_init_ptr, | 1123 | .validate_struct_init, |
| 1118 | .validate_array_init_ptr, | 1124 | .validate_array_init, |
| 1119 | .struct_init_empty, | 1125 | .struct_init_empty, |
| 1120 | .struct_init, | 1126 | .struct_init, |
| 1121 | .struct_init_ref, | 1127 | .struct_init_ref, |
| ... | @@ -1291,6 +1297,7 @@ pub const Inst = struct { | ... | @@ -1291,6 +1297,7 @@ pub const Inst = struct { |
| 1291 | .div = .pl_node, | 1297 | .div = .pl_node, |
| 1292 | .elem_ptr = .bin, | 1298 | .elem_ptr = .bin, |
| 1293 | .elem_ptr_node = .pl_node, | 1299 | .elem_ptr_node = .pl_node, |
| 1300 | .elem_ptr_imm = .pl_node, | ||
| 1294 | .elem_val = .bin, | 1301 | .elem_val = .bin, |
| 1295 | .elem_val_node = .pl_node, | 1302 | .elem_val_node = .pl_node, |
| 1296 | .ensure_result_used = .un_node, | 1303 | .ensure_result_used = .un_node, |
| ... | @@ -1377,8 +1384,8 @@ pub const Inst = struct { | ... | @@ -1377,8 +1384,8 @@ pub const Inst = struct { |
| 1377 | .switch_capture_multi_ref = .switch_capture, | 1384 | .switch_capture_multi_ref = .switch_capture, |
| 1378 | .switch_capture_else = .switch_capture, | 1385 | .switch_capture_else = .switch_capture, |
| 1379 | .switch_capture_else_ref = .switch_capture, | 1386 | .switch_capture_else_ref = .switch_capture, |
| 1380 | .validate_struct_init_ptr = .pl_node, | 1387 | .validate_struct_init = .pl_node, |
| 1381 | .validate_array_init_ptr = .pl_node, | 1388 | .validate_array_init = .pl_node, |
| 1382 | .struct_init_empty = .un_node, | 1389 | .struct_init_empty = .un_node, |
| 1383 | .field_type = .pl_node, | 1390 | .field_type = .pl_node, |
| 1384 | .field_type_ref = .pl_node, | 1391 | .field_type_ref = .pl_node, |
| ... | @@ -2459,6 +2466,11 @@ pub const Inst = struct { | ... | @@ -2459,6 +2466,11 @@ pub const Inst = struct { |
| 2459 | operand: Ref, | 2466 | operand: Ref, |
| 2460 | }; | 2467 | }; |
| 2461 | 2468 | ||
| 2469 | pub const ElemPtrImm = struct { | ||
| 2470 | ptr: Ref, | ||
| 2471 | index: u32, | ||
| 2472 | }; | ||
| 2473 | |||
| 2462 | /// This form is supported when there are no ranges, and exactly 1 item per block. | 2474 | /// This form is supported when there are no ranges, and exactly 1 item per block. |
| 2463 | /// Depending on zir tag and len fields, extra fields trail | 2475 | /// Depending on zir tag and len fields, extra fields trail |
| 2464 | /// this one in the extra array. | 2476 | /// this one in the extra array. |
src/print_zir.zig+13-2| ... | @@ -355,6 +355,8 @@ const Writer = struct { | ... | @@ -355,6 +355,8 @@ const Writer = struct { |
| 355 | .elem_val_node, | 355 | .elem_val_node, |
| 356 | => try self.writePlNodeBin(stream, inst), | 356 | => try self.writePlNodeBin(stream, inst), |
| 357 | 357 | ||
| 358 | .elem_ptr_imm => try self.writeElemPtrImm(stream, inst), | ||
| 359 | |||
| 358 | .@"export" => try self.writePlNodeExport(stream, inst), | 360 | .@"export" => try self.writePlNodeExport(stream, inst), |
| 359 | .export_value => try self.writePlNodeExportValue(stream, inst), | 361 | .export_value => try self.writePlNodeExportValue(stream, inst), |
| 360 | 362 | ||
| ... | @@ -364,8 +366,8 @@ const Writer = struct { | ... | @@ -364,8 +366,8 @@ const Writer = struct { |
| 364 | .block_inline, | 366 | .block_inline, |
| 365 | .suspend_block, | 367 | .suspend_block, |
| 366 | .loop, | 368 | .loop, |
| 367 | .validate_struct_init_ptr, | 369 | .validate_struct_init, |
| 368 | .validate_array_init_ptr, | 370 | .validate_array_init, |
| 369 | .c_import, | 371 | .c_import, |
| 370 | => try self.writePlNodeBlock(stream, inst), | 372 | => try self.writePlNodeBlock(stream, inst), |
| 371 | 373 | ||
| ... | @@ -809,6 +811,15 @@ const Writer = struct { | ... | @@ -809,6 +811,15 @@ const Writer = struct { |
| 809 | try self.writeSrc(stream, inst_data.src()); | 811 | try self.writeSrc(stream, inst_data.src()); |
| 810 | } | 812 | } |
| 811 | 813 | ||
| 814 | fn writeElemPtrImm(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { | ||
| 815 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | ||
| 816 | const extra = self.code.extraData(Zir.Inst.ElemPtrImm, inst_data.payload_index).data; | ||
| 817 | |||
| 818 | try self.writeInstRef(stream, extra.ptr); | ||
| 819 | try stream.print(", {d}) ", .{extra.index}); | ||
| 820 | try self.writeSrc(stream, inst_data.src()); | ||
| 821 | } | ||
| 822 | |||
| 812 | fn writePlNodeExport(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { | 823 | fn writePlNodeExport(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { |
| 813 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; | 824 | const inst_data = self.code.instructions.items(.data)[inst].pl_node; |
| 814 | const extra = self.code.extraData(Zir.Inst.Export, inst_data.payload_index).data; | 825 | const extra = self.code.extraData(Zir.Inst.Export, inst_data.payload_index).data; |
test/behavior/array.zig+7-2| ... | @@ -33,8 +33,13 @@ test "array init with mult" { | ... | @@ -33,8 +33,13 @@ test "array init with mult" { |
| 33 | var i: [8]u8 = [2]u8{ a, 'b' } ** 4; | 33 | var i: [8]u8 = [2]u8{ a, 'b' } ** 4; |
| 34 | try expect(std.mem.eql(u8, &i, "abababab")); | 34 | try expect(std.mem.eql(u8, &i, "abababab")); |
| 35 | 35 | ||
| 36 | // this should cause a Value.repeated to be emitted in AIR. | ||
| 37 | // TODO: find a way to test that this is actually getting emmited | ||
| 38 | var j: [4]u8 = [1]u8{'a'} ** 4; | 36 | var j: [4]u8 = [1]u8{'a'} ** 4; |
| 39 | try expect(std.mem.eql(u8, &j, "aaaa")); | 37 | try expect(std.mem.eql(u8, &j, "aaaa")); |
| 40 | } | 38 | } |
| 39 | |||
| 40 | test "array literal with explicit type" { | ||
| 41 | const hex_mult: [4]u16 = .{ 4096, 256, 16, 1 }; | ||
| 42 | |||
| 43 | try expect(hex_mult.len == 4); | ||
| 44 | try expect(hex_mult[1] == 256); | ||
| 45 | } |
test/behavior/array_stage1.zig+7-7| ... | @@ -4,6 +4,13 @@ const mem = std.mem; | ... | @@ -4,6 +4,13 @@ const mem = std.mem; |
| 4 | const expect = testing.expect; | 4 | const expect = testing.expect; |
| 5 | const expectEqual = testing.expectEqual; | 5 | const expectEqual = testing.expectEqual; |
| 6 | 6 | ||
| 7 | test "array literal with inferred length" { | ||
| 8 | const hex_mult = [_]u16{ 4096, 256, 16, 1 }; | ||
| 9 | |||
| 10 | try expect(hex_mult.len == 4); | ||
| 11 | try expect(hex_mult[1] == 256); | ||
| 12 | } | ||
| 13 | |||
| 7 | test "array with sentinels" { | 14 | test "array with sentinels" { |
| 8 | const S = struct { | 15 | const S = struct { |
| 9 | fn doTheTest(is_ct: bool) !void { | 16 | fn doTheTest(is_ct: bool) !void { |
| ... | @@ -39,13 +46,6 @@ test "void arrays" { | ... | @@ -39,13 +46,6 @@ test "void arrays" { |
| 39 | try expect(array.len == 4); | 46 | try expect(array.len == 4); |
| 40 | } | 47 | } |
| 41 | 48 | ||
| 42 | test "array literal" { | ||
| 43 | const hex_mult = [_]u16{ 4096, 256, 16, 1 }; | ||
| 44 | |||
| 45 | try expect(hex_mult.len == 4); | ||
| 46 | try expect(hex_mult[1] == 256); | ||
| 47 | } | ||
| 48 | |||
| 49 | test "array dot len const expr" { | 49 | test "array dot len const expr" { |
| 50 | try expect(comptime x: { | 50 | try expect(comptime x: { |
| 51 | break :x some_array.len == 4; | 51 | break :x some_array.len == 4; |