| ... | @@ -53,16 +53,30 @@ fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 { | ... | @@ -53,16 +53,30 @@ fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 { |
| 53 | fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 { | 53 | fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 { |
| 54 | const fields = std.meta.fields(@TypeOf(extra)); | 54 | const fields = std.meta.fields(@TypeOf(extra)); |
| 55 | const result = @intCast(u32, astgen.extra.items.len); | 55 | const result = @intCast(u32, astgen.extra.items.len); |
| | 56 | astgen.extra.items.len += fields.len; |
| | 57 | setExtra(astgen, result, extra); |
| | 58 | return result; |
| | 59 | } |
| | 60 | |
| | 61 | fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void { |
| | 62 | const fields = std.meta.fields(@TypeOf(extra)); |
| | 63 | var i = index; |
| 56 | inline for (fields) |field| { | 64 | inline for (fields) |field| { |
| 57 | astgen.extra.appendAssumeCapacity(switch (field.field_type) { | 65 | astgen.extra.items[i] = switch (field.field_type) { |
| 58 | u32 => @field(extra, field.name), | 66 | u32 => @field(extra, field.name), |
| 59 | Zir.Inst.Ref => @enumToInt(@field(extra, field.name)), | 67 | Zir.Inst.Ref => @enumToInt(@field(extra, field.name)), |
| 60 | i32 => @bitCast(u32, @field(extra, field.name)), | 68 | i32 => @bitCast(u32, @field(extra, field.name)), |
| 61 | Zir.Inst.Call.Flags => @bitCast(u32, @field(extra, field.name)), | 69 | Zir.Inst.Call.Flags => @bitCast(u32, @field(extra, field.name)), |
| 62 | Zir.Inst.SwitchBlock.Bits => @bitCast(u32, @field(extra, field.name)), | 70 | Zir.Inst.SwitchBlock.Bits => @bitCast(u32, @field(extra, field.name)), |
| 63 | else => @compileError("bad field type"), | 71 | else => @compileError("bad field type"), |
| 64 | }); | 72 | }; |
| | 73 | i += 1; |
| 65 | } | 74 | } |
| | 75 | } |
| | 76 | |
| | 77 | fn reserveExtra(astgen: *AstGen, size: usize) Allocator.Error!u32 { |
| | 78 | const result = @intCast(u32, astgen.extra.items.len); |
| | 79 | try astgen.extra.resize(astgen.gpa, result + size); |
| 66 | return result; | 80 | return result; |
| 67 | } | 81 | } |
| 68 | | 82 | |
| ... | @@ -1307,18 +1321,18 @@ fn arrayInitExprRlNone( | ... | @@ -1307,18 +1321,18 @@ fn arrayInitExprRlNone( |
| 1307 | tag: Zir.Inst.Tag, | 1321 | tag: Zir.Inst.Tag, |
| 1308 | ) InnerError!Zir.Inst.Ref { | 1322 | ) InnerError!Zir.Inst.Ref { |
| 1309 | const astgen = gz.astgen; | 1323 | const astgen = gz.astgen; |
| 1310 | const gpa = astgen.gpa; | | |
| 1311 | const elem_list = try gpa.alloc(Zir.Inst.Ref, elements.len); | | |
| 1312 | defer gpa.free(elem_list); | | |
| 1313 | | 1324 | |
| 1314 | for (elements) |elem_init, i| { | 1325 | const payload_index = try addExtra(astgen, Zir.Inst.MultiOp{ |
| 1315 | elem_list[i] = try expr(gz, scope, .none, elem_init); | 1326 | .operands_len = @intCast(u32, elements.len), |
| 1316 | } | | |
| 1317 | const init_inst = try gz.addPlNode(tag, node, Zir.Inst.MultiOp{ | | |
| 1318 | .operands_len = @intCast(u32, elem_list.len), | | |
| 1319 | }); | 1327 | }); |
| 1320 | try astgen.appendRefs(elem_list); | 1328 | var extra_index = try reserveExtra(astgen, elements.len); |
| 1321 | return init_inst; | 1329 | |
| | 1330 | for (elements) |elem_init| { |
| | 1331 | const elem_ref = try expr(gz, scope, .none, elem_init); |
| | 1332 | astgen.extra.items[extra_index] = @enumToInt(elem_ref); |
| | 1333 | extra_index += 1; |
| | 1334 | } |
| | 1335 | return try gz.addPlNodePayloadIndex(tag, node, payload_index); |
| 1322 | } | 1336 | } |
| 1323 | | 1337 | |
| 1324 | fn arrayInitExprRlTy( | 1338 | fn arrayInitExprRlTy( |
| ... | @@ -1330,21 +1344,19 @@ fn arrayInitExprRlTy( | ... | @@ -1330,21 +1344,19 @@ fn arrayInitExprRlTy( |
| 1330 | tag: Zir.Inst.Tag, | 1344 | tag: Zir.Inst.Tag, |
| 1331 | ) InnerError!Zir.Inst.Ref { | 1345 | ) InnerError!Zir.Inst.Ref { |
| 1332 | const astgen = gz.astgen; | 1346 | const astgen = gz.astgen; |
| 1333 | const gpa = astgen.gpa; | | |
| 1334 | | 1347 | |
| 1335 | const elem_list = try gpa.alloc(Zir.Inst.Ref, elements.len); | 1348 | const payload_index = try addExtra(astgen, Zir.Inst.MultiOp{ |
| 1336 | defer gpa.free(elem_list); | 1349 | .operands_len = @intCast(u32, elements.len), |
| | 1350 | }); |
| | 1351 | var extra_index = try reserveExtra(astgen, elements.len); |
| 1337 | | 1352 | |
| 1338 | const elem_rl: ResultLoc = .{ .ty = elem_ty_inst }; | 1353 | const elem_rl: ResultLoc = .{ .ty = elem_ty_inst }; |
| 1339 | | 1354 | for (elements) |elem_init| { |
| 1340 | for (elements) |elem_init, i| { | 1355 | const elem_ref = try expr(gz, scope, elem_rl, elem_init); |
| 1341 | elem_list[i] = try expr(gz, scope, elem_rl, elem_init); | 1356 | astgen.extra.items[extra_index] = @enumToInt(elem_ref); |
| | 1357 | extra_index += 1; |
| 1342 | } | 1358 | } |
| 1343 | const init_inst = try gz.addPlNode(tag, node, Zir.Inst.MultiOp{ | 1359 | return try gz.addPlNodePayloadIndex(tag, node, payload_index); |
| 1344 | .operands_len = @intCast(u32, elem_list.len), | | |
| 1345 | }); | | |
| 1346 | try astgen.appendRefs(elem_list); | | |
| 1347 | return init_inst; | | |
| 1348 | } | 1360 | } |
| 1349 | | 1361 | |
| 1350 | fn arrayInitExprRlPtr( | 1362 | fn arrayInitExprRlPtr( |
| ... | @@ -1375,23 +1387,22 @@ fn arrayInitExprRlPtrInner( | ... | @@ -1375,23 +1387,22 @@ fn arrayInitExprRlPtrInner( |
| 1375 | elements: []const Ast.Node.Index, | 1387 | elements: []const Ast.Node.Index, |
| 1376 | ) InnerError!Zir.Inst.Ref { | 1388 | ) InnerError!Zir.Inst.Ref { |
| 1377 | const astgen = gz.astgen; | 1389 | const astgen = gz.astgen; |
| 1378 | const gpa = astgen.gpa; | | |
| 1379 | | 1390 | |
| 1380 | const elem_ptr_list = try gpa.alloc(Zir.Inst.Index, elements.len); | 1391 | const payload_index = try addExtra(astgen, Zir.Inst.Block{ |
| 1381 | defer gpa.free(elem_ptr_list); | 1392 | .body_len = @intCast(u32, elements.len), |
| | 1393 | }); |
| | 1394 | var extra_index = try reserveExtra(astgen, elements.len); |
| 1382 | | 1395 | |
| 1383 | for (elements) |elem_init, i| { | 1396 | for (elements) |elem_init, i| { |
| 1384 | const elem_ptr = try gz.addPlNode(.elem_ptr_imm, elem_init, Zir.Inst.ElemPtrImm{ | 1397 | const elem_ptr = try gz.addPlNode(.elem_ptr_imm, elem_init, Zir.Inst.ElemPtrImm{ |
| 1385 | .ptr = result_ptr, | 1398 | .ptr = result_ptr, |
| 1386 | .index = @intCast(u32, i), | 1399 | .index = @intCast(u32, i), |
| 1387 | }); | 1400 | }); |
| 1388 | elem_ptr_list[i] = refToIndex(elem_ptr).?; | 1401 | astgen.extra.items[extra_index] = refToIndex(elem_ptr).?; |
| | 1402 | extra_index += 1; |
| 1389 | _ = try expr(gz, scope, .{ .ptr = elem_ptr }, elem_init); | 1403 | _ = try expr(gz, scope, .{ .ptr = elem_ptr }, elem_init); |
| 1390 | } | 1404 | } |
| 1391 | _ = try gz.addPlNode(.validate_array_init, node, Zir.Inst.Block{ | 1405 | _ = try gz.addPlNodePayloadIndex(.validate_array_init, node, payload_index); |
| 1392 | .body_len = @intCast(u32, elem_ptr_list.len), | | |
| 1393 | }); | | |
| 1394 | try astgen.extra.appendSlice(gpa, elem_ptr_list); | | |
| 1395 | return .void_value; | 1406 | return .void_value; |
| 1396 | } | 1407 | } |
| 1397 | | 1408 | |
| ... | @@ -1505,30 +1516,25 @@ fn structInitExprRlNone( | ... | @@ -1505,30 +1516,25 @@ fn structInitExprRlNone( |
| 1505 | tag: Zir.Inst.Tag, | 1516 | tag: Zir.Inst.Tag, |
| 1506 | ) InnerError!Zir.Inst.Ref { | 1517 | ) InnerError!Zir.Inst.Ref { |
| 1507 | const astgen = gz.astgen; | 1518 | const astgen = gz.astgen; |
| 1508 | const gpa = astgen.gpa; | | |
| 1509 | const tree = astgen.tree; | 1519 | const tree = astgen.tree; |
| 1510 | | 1520 | |
| 1511 | const fields_list = try gpa.alloc(Zir.Inst.StructInitAnon.Item, struct_init.ast.fields.len); | 1521 | const payload_index = try addExtra(astgen, Zir.Inst.StructInitAnon{ |
| 1512 | defer gpa.free(fields_list); | 1522 | .fields_len = @intCast(u32, struct_init.ast.fields.len), |
| | 1523 | }); |
| | 1524 | const field_size = @typeInfo(Zir.Inst.StructInitAnon.Item).Struct.fields.len; |
| | 1525 | var extra_index: usize = try reserveExtra(astgen, struct_init.ast.fields.len * field_size); |
| 1513 | | 1526 | |
| 1514 | for (struct_init.ast.fields) |field_init, i| { | 1527 | for (struct_init.ast.fields) |field_init| { |
| 1515 | const name_token = tree.firstToken(field_init) - 2; | 1528 | const name_token = tree.firstToken(field_init) - 2; |
| 1516 | const str_index = try astgen.identAsString(name_token); | 1529 | const str_index = try astgen.identAsString(name_token); |
| 1517 | | 1530 | setExtra(astgen, extra_index, Zir.Inst.StructInitAnon.Item{ |
| 1518 | fields_list[i] = .{ | | |
| 1519 | .field_name = str_index, | 1531 | .field_name = str_index, |
| 1520 | .init = try expr(gz, scope, .none, field_init), | 1532 | .init = try expr(gz, scope, .none, field_init), |
| 1521 | }; | 1533 | }); |
| 1522 | } | 1534 | extra_index += field_size; |
| 1523 | const init_inst = try gz.addPlNode(tag, node, Zir.Inst.StructInitAnon{ | | |
| 1524 | .fields_len = @intCast(u32, fields_list.len), | | |
| 1525 | }); | | |
| 1526 | try astgen.extra.ensureUnusedCapacity(gpa, fields_list.len * | | |
| 1527 | @typeInfo(Zir.Inst.StructInitAnon.Item).Struct.fields.len); | | |
| 1528 | for (fields_list) |field| { | | |
| 1529 | _ = gz.astgen.addExtraAssumeCapacity(field); | | |
| 1530 | } | 1535 | } |
| 1531 | return init_inst; | 1536 | |
| | 1537 | return try gz.addPlNodePayloadIndex(tag, node, payload_index); |
| 1532 | } | 1538 | } |
| 1533 | | 1539 | |
| 1534 | fn structInitExprRlPtr( | 1540 | fn structInitExprRlPtr( |
| ... | @@ -1559,26 +1565,26 @@ fn structInitExprRlPtrInner( | ... | @@ -1559,26 +1565,26 @@ fn structInitExprRlPtrInner( |
| 1559 | result_ptr: Zir.Inst.Ref, | 1565 | result_ptr: Zir.Inst.Ref, |
| 1560 | ) InnerError!Zir.Inst.Ref { | 1566 | ) InnerError!Zir.Inst.Ref { |
| 1561 | const astgen = gz.astgen; | 1567 | const astgen = gz.astgen; |
| 1562 | const gpa = astgen.gpa; | | |
| 1563 | const tree = astgen.tree; | 1568 | const tree = astgen.tree; |
| 1564 | | 1569 | |
| 1565 | const field_ptr_list = try gpa.alloc(Zir.Inst.Index, struct_init.ast.fields.len); | 1570 | const payload_index = try addExtra(astgen, Zir.Inst.Block{ |
| 1566 | defer gpa.free(field_ptr_list); | 1571 | .body_len = @intCast(u32, struct_init.ast.fields.len), |
| | 1572 | }); |
| | 1573 | var extra_index = try reserveExtra(astgen, struct_init.ast.fields.len); |
| 1567 | | 1574 | |
| 1568 | for (struct_init.ast.fields) |field_init, i| { | 1575 | for (struct_init.ast.fields) |field_init| { |
| 1569 | const name_token = tree.firstToken(field_init) - 2; | 1576 | const name_token = tree.firstToken(field_init) - 2; |
| 1570 | const str_index = try astgen.identAsString(name_token); | 1577 | const str_index = try astgen.identAsString(name_token); |
| 1571 | const field_ptr = try gz.addPlNode(.field_ptr, field_init, Zir.Inst.Field{ | 1578 | const field_ptr = try gz.addPlNode(.field_ptr, field_init, Zir.Inst.Field{ |
| 1572 | .lhs = result_ptr, | 1579 | .lhs = result_ptr, |
| 1573 | .field_name_start = str_index, | 1580 | .field_name_start = str_index, |
| 1574 | }); | 1581 | }); |
| 1575 | field_ptr_list[i] = refToIndex(field_ptr).?; | 1582 | astgen.extra.items[extra_index] = refToIndex(field_ptr).?; |
| | 1583 | extra_index += 1; |
| 1576 | _ = try expr(gz, scope, .{ .ptr = field_ptr }, field_init); | 1584 | _ = try expr(gz, scope, .{ .ptr = field_ptr }, field_init); |
| 1577 | } | 1585 | } |
| 1578 | _ = try gz.addPlNode(.validate_struct_init, node, Zir.Inst.Block{ | 1586 | |
| 1579 | .body_len = @intCast(u32, field_ptr_list.len), | 1587 | _ = try gz.addPlNodePayloadIndex(.validate_struct_init, node, payload_index); |
| 1580 | }); | | |
| 1581 | try astgen.extra.appendSlice(gpa, field_ptr_list); | | |
| 1582 | return Zir.Inst.Ref.void_value; | 1588 | return Zir.Inst.Ref.void_value; |
| 1583 | } | 1589 | } |
| 1584 | | 1590 | |
| ... | @@ -1591,34 +1597,29 @@ fn structInitExprRlTy( | ... | @@ -1591,34 +1597,29 @@ fn structInitExprRlTy( |
| 1591 | tag: Zir.Inst.Tag, | 1597 | tag: Zir.Inst.Tag, |
| 1592 | ) InnerError!Zir.Inst.Ref { | 1598 | ) InnerError!Zir.Inst.Ref { |
| 1593 | const astgen = gz.astgen; | 1599 | const astgen = gz.astgen; |
| 1594 | const gpa = astgen.gpa; | | |
| 1595 | const tree = astgen.tree; | 1600 | const tree = astgen.tree; |
| 1596 | | 1601 | |
| 1597 | const fields_list = try gpa.alloc(Zir.Inst.StructInit.Item, struct_init.ast.fields.len); | 1602 | const payload_index = try addExtra(astgen, Zir.Inst.StructInit{ |
| 1598 | defer gpa.free(fields_list); | 1603 | .fields_len = @intCast(u32, struct_init.ast.fields.len), |
| | 1604 | }); |
| | 1605 | const field_size = @typeInfo(Zir.Inst.StructInit.Item).Struct.fields.len; |
| | 1606 | var extra_index: usize = try reserveExtra(astgen, struct_init.ast.fields.len * field_size); |
| 1599 | | 1607 | |
| 1600 | for (struct_init.ast.fields) |field_init, i| { | 1608 | for (struct_init.ast.fields) |field_init| { |
| 1601 | const name_token = tree.firstToken(field_init) - 2; | 1609 | const name_token = tree.firstToken(field_init) - 2; |
| 1602 | const str_index = try astgen.identAsString(name_token); | 1610 | const str_index = try astgen.identAsString(name_token); |
| 1603 | | | |
| 1604 | const field_ty_inst = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{ | 1611 | const field_ty_inst = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{ |
| 1605 | .container_type = ty_inst, | 1612 | .container_type = ty_inst, |
| 1606 | .name_start = str_index, | 1613 | .name_start = str_index, |
| 1607 | }); | 1614 | }); |
| 1608 | fields_list[i] = .{ | 1615 | setExtra(astgen, extra_index, Zir.Inst.StructInit.Item{ |
| 1609 | .field_type = refToIndex(field_ty_inst).?, | 1616 | .field_type = refToIndex(field_ty_inst).?, |
| 1610 | .init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init), | 1617 | .init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init), |
| 1611 | }; | 1618 | }); |
| 1612 | } | 1619 | extra_index += field_size; |
| 1613 | const init_inst = try gz.addPlNode(tag, node, Zir.Inst.StructInit{ | | |
| 1614 | .fields_len = @intCast(u32, fields_list.len), | | |
| 1615 | }); | | |
| 1616 | try astgen.extra.ensureUnusedCapacity(gpa, fields_list.len * | | |
| 1617 | @typeInfo(Zir.Inst.StructInit.Item).Struct.fields.len); | | |
| 1618 | for (fields_list) |field| { | | |
| 1619 | _ = gz.astgen.addExtraAssumeCapacity(field); | | |
| 1620 | } | 1620 | } |
| 1621 | return init_inst; | 1621 | |
| | 1622 | return try gz.addPlNodePayloadIndex(tag, node, payload_index); |
| 1622 | } | 1623 | } |
| 1623 | | 1624 | |
| 1624 | /// This calls expr in a comptime scope, and is intended to be called as a helper function. | 1625 | /// This calls expr in a comptime scope, and is intended to be called as a helper function. |
| ... | @@ -4851,20 +4852,18 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir | ... | @@ -4851,20 +4852,18 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir |
| 4851 | const main_tokens = tree.nodes.items(.main_token); | 4852 | const main_tokens = tree.nodes.items(.main_token); |
| 4852 | const token_tags = tree.tokens.items(.tag); | 4853 | const token_tags = tree.tokens.items(.tag); |
| 4853 | | 4854 | |
| 4854 | var field_names: std.ArrayListUnmanaged(u32) = .{}; | 4855 | const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).Struct.fields.len); |
| 4855 | defer field_names.deinit(gpa); | 4856 | var fields_len: usize = 0; |
| 4856 | | | |
| 4857 | { | 4857 | { |
| 4858 | const error_token = main_tokens[node]; | 4858 | const error_token = main_tokens[node]; |
| 4859 | var tok_i = error_token + 2; | 4859 | var tok_i = error_token + 2; |
| 4860 | var field_i: usize = 0; | | |
| 4861 | while (true) : (tok_i += 1) { | 4860 | while (true) : (tok_i += 1) { |
| 4862 | switch (token_tags[tok_i]) { | 4861 | switch (token_tags[tok_i]) { |
| 4863 | .doc_comment, .comma => {}, | 4862 | .doc_comment, .comma => {}, |
| 4864 | .identifier => { | 4863 | .identifier => { |
| 4865 | const str_index = try astgen.identAsString(tok_i); | 4864 | const str_index = try astgen.identAsString(tok_i); |
| 4866 | try field_names.append(gpa, str_index); | 4865 | try astgen.extra.append(gpa, str_index); |
| 4867 | field_i += 1; | 4866 | fields_len += 1; |
| 4868 | }, | 4867 | }, |
| 4869 | .r_brace => break, | 4868 | .r_brace => break, |
| 4870 | else => unreachable, | 4869 | else => unreachable, |
| ... | @@ -4872,10 +4871,10 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir | ... | @@ -4872,10 +4871,10 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir |
| 4872 | } | 4871 | } |
| 4873 | } | 4872 | } |
| 4874 | | 4873 | |
| 4875 | const result = try gz.addPlNode(.error_set_decl, node, Zir.Inst.ErrorSetDecl{ | 4874 | setExtra(astgen, payload_index, Zir.Inst.ErrorSetDecl{ |
| 4876 | .fields_len = @intCast(u32, field_names.items.len), | 4875 | .fields_len = @intCast(u32, fields_len), |
| 4877 | }); | 4876 | }); |
| 4878 | try astgen.extra.appendSlice(gpa, field_names.items); | 4877 | const result = try gz.addPlNodePayloadIndex(.error_set_decl, node, payload_index); |
| 4879 | return rvalue(gz, rl, result, node); | 4878 | return rvalue(gz, rl, result, node); |
| 4880 | } | 4879 | } |
| 4881 | | 4880 | |
| ... | @@ -7196,13 +7195,18 @@ fn typeOf( | ... | @@ -7196,13 +7195,18 @@ fn typeOf( |
| 7196 | const result = try gz.addUnNode(.typeof, expr_result, node); | 7195 | const result = try gz.addUnNode(.typeof, expr_result, node); |
| 7197 | return rvalue(gz, rl, result, node); | 7196 | return rvalue(gz, rl, result, node); |
| 7198 | } | 7197 | } |
| 7199 | const arena = gz.astgen.arena; | 7198 | |
| 7200 | var items = try arena.alloc(Zir.Inst.Ref, params.len); | 7199 | const payload_index = try addExtra(gz.astgen, Zir.Inst.NodeMultiOp{ |
| 7201 | for (params) |param, param_i| { | 7200 | .src_node = gz.nodeIndexToRelative(node), |
| 7202 | items[param_i] = try reachableExpr(gz, scope, .none, param, node); | 7201 | }); |
| | 7202 | var extra_index = try reserveExtra(gz.astgen, params.len); |
| | 7203 | for (params) |param| { |
| | 7204 | const param_ref = try reachableExpr(gz, scope, .none, param, node); |
| | 7205 | gz.astgen.extra.items[extra_index] = @enumToInt(param_ref); |
| | 7206 | extra_index += 1; |
| 7203 | } | 7207 | } |
| 7204 | | 7208 | |
| 7205 | const result = try gz.addExtendedMultiOp(.typeof_peer, node, items); | 7209 | const result = try gz.addExtendedMultiOpPayloadIndex(.typeof_peer, payload_index, params.len); |
| 7206 | return rvalue(gz, rl, result, node); | 7210 | return rvalue(gz, rl, result, node); |
| 7207 | } | 7211 | } |
| 7208 | | 7212 | |
| ... | @@ -7259,12 +7263,16 @@ fn builtinCall( | ... | @@ -7259,12 +7263,16 @@ fn builtinCall( |
| 7259 | return rvalue(gz, rl, result, node); | 7263 | return rvalue(gz, rl, result, node); |
| 7260 | }, | 7264 | }, |
| 7261 | .compile_log => { | 7265 | .compile_log => { |
| 7262 | const arg_refs = try astgen.gpa.alloc(Zir.Inst.Ref, params.len); | 7266 | const payload_index = try addExtra(gz.astgen, Zir.Inst.NodeMultiOp{ |
| 7263 | defer astgen.gpa.free(arg_refs); | 7267 | .src_node = gz.nodeIndexToRelative(node), |
| 7264 | | 7268 | }); |
| 7265 | for (params) |param, i| arg_refs[i] = try expr(gz, scope, .none, param); | 7269 | var extra_index = try reserveExtra(gz.astgen, params.len); |
| 7266 | | 7270 | for (params) |param| { |
| 7267 | const result = try gz.addExtendedMultiOp(.compile_log, node, arg_refs); | 7271 | const param_ref = try expr(gz, scope, .none, param); |
| | 7272 | astgen.extra.items[extra_index] = @enumToInt(param_ref); |
| | 7273 | extra_index += 1; |
| | 7274 | } |
| | 7275 | const result = try gz.addExtendedMultiOpPayloadIndex(.compile_log,payload_index, params.len); |
| 7268 | return rvalue(gz, rl, result, node); | 7276 | return rvalue(gz, rl, result, node); |
| 7269 | }, | 7277 | }, |
| 7270 | .field => { | 7278 | .field => { |
| ... | @@ -7974,22 +7982,6 @@ fn callExpr( | ... | @@ -7974,22 +7982,6 @@ fn callExpr( |
| 7974 | const astgen = gz.astgen; | 7982 | const astgen = gz.astgen; |
| 7975 | | 7983 | |
| 7976 | const callee = try calleeExpr(gz, scope, call.ast.fn_expr); | 7984 | const callee = try calleeExpr(gz, scope, call.ast.fn_expr); |
| 7977 | | | |
| 7978 | // A large proportion of calls have 5 or less arguments, due to this preventing allocations | | |
| 7979 | // for calls with few arguments has a sizeable effect on the aggregated runtime of this function | | |
| 7980 | var arg_buffer: [5]Zir.Inst.Ref = undefined; | | |
| 7981 | const args: []Zir.Inst.Ref = if (call.ast.params.len <= arg_buffer.len) | | |
| 7982 | arg_buffer[0..call.ast.params.len] | | |
| 7983 | else | | |
| 7984 | try astgen.gpa.alloc(Zir.Inst.Ref, call.ast.params.len); | | |
| 7985 | defer if (call.ast.params.len > arg_buffer.len) astgen.gpa.free(args); | | |
| 7986 | | | |
| 7987 | for (call.ast.params) |param_node, i| { | | |
| 7988 | // Parameters are always temporary values, they have no | | |
| 7989 | // meaningful result location. Sema will coerce them. | | |
| 7990 | args[i] = try expr(gz, scope, .none, param_node); | | |
| 7991 | } | | |
| 7992 | | | |
| 7993 | const modifier: std.builtin.CallOptions.Modifier = blk: { | 7985 | const modifier: std.builtin.CallOptions.Modifier = blk: { |
| 7994 | if (gz.force_comptime) { | 7986 | if (gz.force_comptime) { |
| 7995 | break :blk .compile_time; | 7987 | break :blk .compile_time; |
| ... | @@ -8002,7 +7994,28 @@ fn callExpr( | ... | @@ -8002,7 +7994,28 @@ fn callExpr( |
| 8002 | } | 7994 | } |
| 8003 | break :blk .auto; | 7995 | break :blk .auto; |
| 8004 | }; | 7996 | }; |
| 8005 | const call_inst = try gz.addCall(modifier, callee, args, node); | 7997 | |
| | 7998 | assert(callee != .none); |
| | 7999 | assert(node != 0); |
| | 8000 | |
| | 8001 | const payload_index = try addExtra(astgen, Zir.Inst.Call{ |
| | 8002 | .callee = callee, |
| | 8003 | .flags = .{ |
| | 8004 | .packed_modifier = @intCast(Zir.Inst.Call.Flags.PackedModifier, @enumToInt(modifier)), |
| | 8005 | .args_len = @intCast(Zir.Inst.Call.Flags.PackedArgsLen, call.ast.params.len), |
| | 8006 | }, |
| | 8007 | }); |
| | 8008 | var extra_index = try reserveExtra(astgen, call.ast.params.len); |
| | 8009 | |
| | 8010 | for (call.ast.params) |param_node| { |
| | 8011 | // Parameters are always temporary values, they have no |
| | 8012 | // meaningful result location. Sema will coerce them. |
| | 8013 | const arg_ref = try expr(gz, scope, .none, param_node); |
| | 8014 | astgen.extra.items[extra_index] = @enumToInt(arg_ref); |
| | 8015 | extra_index += 1; |
| | 8016 | } |
| | 8017 | |
| | 8018 | const call_inst = try gz.addPlNodePayloadIndex(.call, node, payload_index); |
| 8006 | return rvalue(gz, rl, call_inst, node); // TODO function call with result location | 8019 | return rvalue(gz, rl, call_inst, node); // TODO function call with result location |
| 8007 | } | 8020 | } |
| 8008 | | 8021 | |
| ... | @@ -9765,44 +9778,6 @@ const GenZir = struct { | ... | @@ -9765,44 +9778,6 @@ const GenZir = struct { |
| 9765 | return indexToRef(new_index); | 9778 | return indexToRef(new_index); |
| 9766 | } | 9779 | } |
| 9767 | | 9780 | |
| 9768 | fn addCall( | | |
| 9769 | gz: *GenZir, | | |
| 9770 | modifier: std.builtin.CallOptions.Modifier, | | |
| 9771 | callee: Zir.Inst.Ref, | | |
| 9772 | args: []const Zir.Inst.Ref, | | |
| 9773 | /// Absolute node index. This function does the conversion to offset from Decl. | | |
| 9774 | src_node: Ast.Node.Index, | | |
| 9775 | ) !Zir.Inst.Ref { | | |
| 9776 | assert(callee != .none); | | |
| 9777 | assert(src_node != 0); | | |
| 9778 | const gpa = gz.astgen.gpa; | | |
| 9779 | const Call = Zir.Inst.Call; | | |
| 9780 | try gz.instructions.ensureUnusedCapacity(gpa, 1); | | |
| 9781 | try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); | | |
| 9782 | try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Call).Struct.fields.len + | | |
| 9783 | args.len); | | |
| 9784 | | | |
| 9785 | const payload_index = gz.astgen.addExtraAssumeCapacity(Call{ | | |
| 9786 | .callee = callee, | | |
| 9787 | .flags = .{ | | |
| 9788 | .packed_modifier = @intCast(Call.Flags.PackedModifier, @enumToInt(modifier)), | | |
| 9789 | .args_len = @intCast(Call.Flags.PackedArgsLen, args.len), | | |
| 9790 | }, | | |
| 9791 | }); | | |
| 9792 | gz.astgen.appendRefsAssumeCapacity(args); | | |
| 9793 | | | |
| 9794 | const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); | | |
| 9795 | gz.astgen.instructions.appendAssumeCapacity(.{ | | |
| 9796 | .tag = .call, | | |
| 9797 | .data = .{ .pl_node = .{ | | |
| 9798 | .src_node = gz.nodeIndexToRelative(src_node), | | |
| 9799 | .payload_index = payload_index, | | |
| 9800 | } }, | | |
| 9801 | }); | | |
| 9802 | gz.instructions.appendAssumeCapacity(new_index); | | |
| 9803 | return indexToRef(new_index); | | |
| 9804 | } | | |
| 9805 | | | |
| 9806 | /// Note that this returns a `Zir.Inst.Index` not a ref. | 9781 | /// Note that this returns a `Zir.Inst.Index` not a ref. |
| 9807 | /// Leaves the `payload_index` field undefined. | 9782 | /// Leaves the `payload_index` field undefined. |
| 9808 | fn addBoolBr( | 9783 | fn addBoolBr( |
| ... | @@ -9902,6 +9877,22 @@ const GenZir = struct { | ... | @@ -9902,6 +9877,22 @@ const GenZir = struct { |
| 9902 | return indexToRef(new_index); | 9877 | return indexToRef(new_index); |
| 9903 | } | 9878 | } |
| 9904 | | 9879 | |
| | 9880 | fn addPlNodePayloadIndex( |
| | 9881 | gz: *GenZir, |
| | 9882 | tag: Zir.Inst.Tag, |
| | 9883 | /// Absolute node index. This function does the conversion to offset from Decl. |
| | 9884 | src_node: Ast.Node.Index, |
| | 9885 | payload_index: u32, |
| | 9886 | ) !Zir.Inst.Ref { |
| | 9887 | return try gz.add(.{ |
| | 9888 | .tag = tag, |
| | 9889 | .data = .{ .pl_node = .{ |
| | 9890 | .src_node = gz.nodeIndexToRelative(src_node), |
| | 9891 | .payload_index = payload_index, |
| | 9892 | } }, |
| | 9893 | }); |
| | 9894 | } |
| | 9895 | |
| 9905 | fn addParam( | 9896 | fn addParam( |
| 9906 | gz: *GenZir, | 9897 | gz: *GenZir, |
| 9907 | tag: Zir.Inst.Tag, | 9898 | tag: Zir.Inst.Tag, |
| ... | @@ -9991,6 +9982,30 @@ const GenZir = struct { | ... | @@ -9991,6 +9982,30 @@ const GenZir = struct { |
| 9991 | return indexToRef(new_index); | 9982 | return indexToRef(new_index); |
| 9992 | } | 9983 | } |
| 9993 | | 9984 | |
| | 9985 | fn addExtendedMultiOpPayloadIndex( |
| | 9986 | gz: *GenZir, |
| | 9987 | opcode: Zir.Inst.Extended, |
| | 9988 | payload_index: u32, |
| | 9989 | trailing_len: usize, |
| | 9990 | ) !Zir.Inst.Ref { |
| | 9991 | const astgen = gz.astgen; |
| | 9992 | const gpa = astgen.gpa; |
| | 9993 | |
| | 9994 | try gz.instructions.ensureUnusedCapacity(gpa, 1); |
| | 9995 | try astgen.instructions.ensureUnusedCapacity(gpa, 1); |
| | 9996 | const new_index = @intCast(Zir.Inst.Index, astgen.instructions.len); |
| | 9997 | astgen.instructions.appendAssumeCapacity(.{ |
| | 9998 | .tag = .extended, |
| | 9999 | .data = .{ .extended = .{ |
| | 10000 | .opcode = opcode, |
| | 10001 | .small = @intCast(u16, trailing_len), |
| | 10002 | .operand = payload_index, |
| | 10003 | } }, |
| | 10004 | }); |
| | 10005 | gz.instructions.appendAssumeCapacity(new_index); |
| | 10006 | return indexToRef(new_index); |
| | 10007 | } |
| | 10008 | |
| 9994 | fn addUnTok( | 10009 | fn addUnTok( |
| 9995 | gz: *GenZir, | 10010 | gz: *GenZir, |
| 9996 | tag: Zir.Inst.Tag, | 10011 | tag: Zir.Inst.Tag, |