| ... | ... | @@ -53,16 +53,30 @@ fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 { |
| 53 | 53 | fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 { |
| 54 | 54 | const fields = std.meta.fields(@TypeOf(extra)); |
| 55 | 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 | 64 | inline for (fields) |field| { |
| 57 | | astgen.extra.appendAssumeCapacity(switch (field.field_type) { |
| 65 | astgen.extra.items[i] = switch (field.field_type) { |
| 58 | 66 | u32 => @field(extra, field.name), |
| 59 | 67 | Zir.Inst.Ref => @enumToInt(@field(extra, field.name)), |
| 60 | 68 | i32 => @bitCast(u32, @field(extra, field.name)), |
| 61 | 69 | Zir.Inst.Call.Flags => @bitCast(u32, @field(extra, field.name)), |
| 62 | 70 | Zir.Inst.SwitchBlock.Bits => @bitCast(u32, @field(extra, field.name)), |
| 63 | 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 | 80 | return result; |
| 67 | 81 | } |
| 68 | 82 | |
| ... | ... | @@ -1307,18 +1321,18 @@ fn arrayInitExprRlNone( |
| 1307 | 1321 | tag: Zir.Inst.Tag, |
| 1308 | 1322 | ) InnerError!Zir.Inst.Ref { |
| 1309 | 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| { |
| 1315 | | elem_list[i] = try expr(gz, scope, .none, elem_init); |
| 1316 | | } |
| 1317 | | const init_inst = try gz.addPlNode(tag, node, Zir.Inst.MultiOp{ |
| 1318 | | .operands_len = @intCast(u32, elem_list.len), |
| 1325 | const payload_index = try addExtra(astgen, Zir.Inst.MultiOp{ |
| 1326 | .operands_len = @intCast(u32, elements.len), |
| 1319 | 1327 | }); |
| 1320 | | try astgen.appendRefs(elem_list); |
| 1321 | | return init_inst; |
| 1328 | var extra_index = try reserveExtra(astgen, elements.len); |
| 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 | 1338 | fn arrayInitExprRlTy( |
| ... | ... | @@ -1330,21 +1344,19 @@ fn arrayInitExprRlTy( |
| 1330 | 1344 | tag: Zir.Inst.Tag, |
| 1331 | 1345 | ) InnerError!Zir.Inst.Ref { |
| 1332 | 1346 | const astgen = gz.astgen; |
| 1333 | | const gpa = astgen.gpa; |
| 1334 | 1347 | |
| 1335 | | const elem_list = try gpa.alloc(Zir.Inst.Ref, elements.len); |
| 1336 | | defer gpa.free(elem_list); |
| 1348 | const payload_index = try addExtra(astgen, Zir.Inst.MultiOp{ |
| 1349 | .operands_len = @intCast(u32, elements.len), |
| 1350 | }); |
| 1351 | var extra_index = try reserveExtra(astgen, elements.len); |
| 1337 | 1352 | |
| 1338 | 1353 | const elem_rl: ResultLoc = .{ .ty = elem_ty_inst }; |
| 1339 | | |
| 1340 | | for (elements) |elem_init, i| { |
| 1341 | | elem_list[i] = try expr(gz, scope, elem_rl, elem_init); |
| 1354 | for (elements) |elem_init| { |
| 1355 | const elem_ref = 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{ |
| 1344 | | .operands_len = @intCast(u32, elem_list.len), |
| 1345 | | }); |
| 1346 | | try astgen.appendRefs(elem_list); |
| 1347 | | return init_inst; |
| 1359 | return try gz.addPlNodePayloadIndex(tag, node, payload_index); |
| 1348 | 1360 | } |
| 1349 | 1361 | |
| 1350 | 1362 | fn arrayInitExprRlPtr( |
| ... | ... | @@ -1375,23 +1387,22 @@ fn arrayInitExprRlPtrInner( |
| 1375 | 1387 | elements: []const Ast.Node.Index, |
| 1376 | 1388 | ) InnerError!Zir.Inst.Ref { |
| 1377 | 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); |
| 1381 | | defer gpa.free(elem_ptr_list); |
| 1391 | const payload_index = try addExtra(astgen, Zir.Inst.Block{ |
| 1392 | .body_len = @intCast(u32, elements.len), |
| 1393 | }); |
| 1394 | var extra_index = try reserveExtra(astgen, elements.len); |
| 1382 | 1395 | |
| 1383 | 1396 | for (elements) |elem_init, i| { |
| 1384 | 1397 | const elem_ptr = try gz.addPlNode(.elem_ptr_imm, elem_init, Zir.Inst.ElemPtrImm{ |
| 1385 | 1398 | .ptr = result_ptr, |
| 1386 | 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 | 1403 | _ = try expr(gz, scope, .{ .ptr = elem_ptr }, elem_init); |
| 1390 | 1404 | } |
| 1391 | | _ = try gz.addPlNode(.validate_array_init, node, Zir.Inst.Block{ |
| 1392 | | .body_len = @intCast(u32, elem_ptr_list.len), |
| 1393 | | }); |
| 1394 | | try astgen.extra.appendSlice(gpa, elem_ptr_list); |
| 1405 | _ = try gz.addPlNodePayloadIndex(.validate_array_init, node, payload_index); |
| 1395 | 1406 | return .void_value; |
| 1396 | 1407 | } |
| 1397 | 1408 | |
| ... | ... | @@ -1505,30 +1516,25 @@ fn structInitExprRlNone( |
| 1505 | 1516 | tag: Zir.Inst.Tag, |
| 1506 | 1517 | ) InnerError!Zir.Inst.Ref { |
| 1507 | 1518 | const astgen = gz.astgen; |
| 1508 | | const gpa = astgen.gpa; |
| 1509 | 1519 | const tree = astgen.tree; |
| 1510 | 1520 | |
| 1511 | | const fields_list = try gpa.alloc(Zir.Inst.StructInitAnon.Item, struct_init.ast.fields.len); |
| 1512 | | defer gpa.free(fields_list); |
| 1521 | const payload_index = try addExtra(astgen, Zir.Inst.StructInitAnon{ |
| 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 | 1528 | const name_token = tree.firstToken(field_init) - 2; |
| 1516 | 1529 | const str_index = try astgen.identAsString(name_token); |
| 1517 | | |
| 1518 | | fields_list[i] = .{ |
| 1530 | setExtra(astgen, extra_index, Zir.Inst.StructInitAnon.Item{ |
| 1519 | 1531 | .field_name = str_index, |
| 1520 | 1532 | .init = try expr(gz, scope, .none, field_init), |
| 1521 | | }; |
| 1522 | | } |
| 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); |
| 1533 | }); |
| 1534 | extra_index += field_size; |
| 1530 | 1535 | } |
| 1531 | | return init_inst; |
| 1536 | |
| 1537 | return try gz.addPlNodePayloadIndex(tag, node, payload_index); |
| 1532 | 1538 | } |
| 1533 | 1539 | |
| 1534 | 1540 | fn structInitExprRlPtr( |
| ... | ... | @@ -1559,26 +1565,26 @@ fn structInitExprRlPtrInner( |
| 1559 | 1565 | result_ptr: Zir.Inst.Ref, |
| 1560 | 1566 | ) InnerError!Zir.Inst.Ref { |
| 1561 | 1567 | const astgen = gz.astgen; |
| 1562 | | const gpa = astgen.gpa; |
| 1563 | 1568 | const tree = astgen.tree; |
| 1564 | 1569 | |
| 1565 | | const field_ptr_list = try gpa.alloc(Zir.Inst.Index, struct_init.ast.fields.len); |
| 1566 | | defer gpa.free(field_ptr_list); |
| 1570 | const payload_index = try addExtra(astgen, Zir.Inst.Block{ |
| 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 | 1576 | const name_token = tree.firstToken(field_init) - 2; |
| 1570 | 1577 | const str_index = try astgen.identAsString(name_token); |
| 1571 | 1578 | const field_ptr = try gz.addPlNode(.field_ptr, field_init, Zir.Inst.Field{ |
| 1572 | 1579 | .lhs = result_ptr, |
| 1573 | 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 | 1584 | _ = try expr(gz, scope, .{ .ptr = field_ptr }, field_init); |
| 1577 | 1585 | } |
| 1578 | | _ = try gz.addPlNode(.validate_struct_init, node, Zir.Inst.Block{ |
| 1579 | | .body_len = @intCast(u32, field_ptr_list.len), |
| 1580 | | }); |
| 1581 | | try astgen.extra.appendSlice(gpa, field_ptr_list); |
| 1586 | |
| 1587 | _ = try gz.addPlNodePayloadIndex(.validate_struct_init, node, payload_index); |
| 1582 | 1588 | return Zir.Inst.Ref.void_value; |
| 1583 | 1589 | } |
| 1584 | 1590 | |
| ... | ... | @@ -1591,34 +1597,29 @@ fn structInitExprRlTy( |
| 1591 | 1597 | tag: Zir.Inst.Tag, |
| 1592 | 1598 | ) InnerError!Zir.Inst.Ref { |
| 1593 | 1599 | const astgen = gz.astgen; |
| 1594 | | const gpa = astgen.gpa; |
| 1595 | 1600 | const tree = astgen.tree; |
| 1596 | 1601 | |
| 1597 | | const fields_list = try gpa.alloc(Zir.Inst.StructInit.Item, struct_init.ast.fields.len); |
| 1598 | | defer gpa.free(fields_list); |
| 1602 | const payload_index = try addExtra(astgen, Zir.Inst.StructInit{ |
| 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 | 1609 | const name_token = tree.firstToken(field_init) - 2; |
| 1602 | 1610 | const str_index = try astgen.identAsString(name_token); |
| 1603 | | |
| 1604 | 1611 | const field_ty_inst = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{ |
| 1605 | 1612 | .container_type = ty_inst, |
| 1606 | 1613 | .name_start = str_index, |
| 1607 | 1614 | }); |
| 1608 | | fields_list[i] = .{ |
| 1615 | setExtra(astgen, extra_index, Zir.Inst.StructInit.Item{ |
| 1609 | 1616 | .field_type = refToIndex(field_ty_inst).?, |
| 1610 | 1617 | .init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init), |
| 1611 | | }; |
| 1612 | | } |
| 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); |
| 1618 | }); |
| 1619 | extra_index += field_size; |
| 1620 | 1620 | } |
| 1621 | | return init_inst; |
| 1621 | |
| 1622 | return try gz.addPlNodePayloadIndex(tag, node, payload_index); |
| 1622 | 1623 | } |
| 1623 | 1624 | |
| 1624 | 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 | 4852 | const main_tokens = tree.nodes.items(.main_token); |
| 4852 | 4853 | const token_tags = tree.tokens.items(.tag); |
| 4853 | 4854 | |
| 4854 | | var field_names: std.ArrayListUnmanaged(u32) = .{}; |
| 4855 | | defer field_names.deinit(gpa); |
| 4856 | | |
| 4855 | const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).Struct.fields.len); |
| 4856 | var fields_len: usize = 0; |
| 4857 | 4857 | { |
| 4858 | 4858 | const error_token = main_tokens[node]; |
| 4859 | 4859 | var tok_i = error_token + 2; |
| 4860 | | var field_i: usize = 0; |
| 4861 | 4860 | while (true) : (tok_i += 1) { |
| 4862 | 4861 | switch (token_tags[tok_i]) { |
| 4863 | 4862 | .doc_comment, .comma => {}, |
| 4864 | 4863 | .identifier => { |
| 4865 | 4864 | const str_index = try astgen.identAsString(tok_i); |
| 4866 | | try field_names.append(gpa, str_index); |
| 4867 | | field_i += 1; |
| 4865 | try astgen.extra.append(gpa, str_index); |
| 4866 | fields_len += 1; |
| 4868 | 4867 | }, |
| 4869 | 4868 | .r_brace => break, |
| 4870 | 4869 | else => unreachable, |
| ... | ... | @@ -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{ |
| 4876 | | .fields_len = @intCast(u32, field_names.items.len), |
| 4874 | setExtra(astgen, payload_index, Zir.Inst.ErrorSetDecl{ |
| 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 | 4878 | return rvalue(gz, rl, result, node); |
| 4880 | 4879 | } |
| 4881 | 4880 | |
| ... | ... | @@ -7196,13 +7195,18 @@ fn typeOf( |
| 7196 | 7195 | const result = try gz.addUnNode(.typeof, expr_result, node); |
| 7197 | 7196 | return rvalue(gz, rl, result, node); |
| 7198 | 7197 | } |
| 7199 | | const arena = gz.astgen.arena; |
| 7200 | | var items = try arena.alloc(Zir.Inst.Ref, params.len); |
| 7201 | | for (params) |param, param_i| { |
| 7202 | | items[param_i] = try reachableExpr(gz, scope, .none, param, node); |
| 7198 | |
| 7199 | const payload_index = try addExtra(gz.astgen, Zir.Inst.NodeMultiOp{ |
| 7200 | .src_node = gz.nodeIndexToRelative(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 | 7210 | return rvalue(gz, rl, result, node); |
| 7207 | 7211 | } |
| 7208 | 7212 | |
| ... | ... | @@ -7259,12 +7263,16 @@ fn builtinCall( |
| 7259 | 7263 | return rvalue(gz, rl, result, node); |
| 7260 | 7264 | }, |
| 7261 | 7265 | .compile_log => { |
| 7262 | | const arg_refs = try astgen.gpa.alloc(Zir.Inst.Ref, params.len); |
| 7263 | | defer astgen.gpa.free(arg_refs); |
| 7264 | | |
| 7265 | | for (params) |param, i| arg_refs[i] = try expr(gz, scope, .none, param); |
| 7266 | | |
| 7267 | | const result = try gz.addExtendedMultiOp(.compile_log, node, arg_refs); |
| 7266 | const payload_index = try addExtra(gz.astgen, Zir.Inst.NodeMultiOp{ |
| 7267 | .src_node = gz.nodeIndexToRelative(node), |
| 7268 | }); |
| 7269 | var extra_index = try reserveExtra(gz.astgen, params.len); |
| 7270 | for (params) |param| { |
| 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 | 7276 | return rvalue(gz, rl, result, node); |
| 7269 | 7277 | }, |
| 7270 | 7278 | .field => { |
| ... | ... | @@ -7974,22 +7982,6 @@ fn callExpr( |
| 7974 | 7982 | const astgen = gz.astgen; |
| 7975 | 7983 | |
| 7976 | 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 | 7985 | const modifier: std.builtin.CallOptions.Modifier = blk: { |
| 7994 | 7986 | if (gz.force_comptime) { |
| 7995 | 7987 | break :blk .compile_time; |
| ... | ... | @@ -8002,7 +7994,28 @@ fn callExpr( |
| 8002 | 7994 | } |
| 8003 | 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 | 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 | 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 | 9781 | /// Note that this returns a `Zir.Inst.Index` not a ref. |
| 9807 | 9782 | /// Leaves the `payload_index` field undefined. |
| 9808 | 9783 | fn addBoolBr( |
| ... | ... | @@ -9902,6 +9877,22 @@ const GenZir = struct { |
| 9902 | 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 | 9896 | fn addParam( |
| 9906 | 9897 | gz: *GenZir, |
| 9907 | 9898 | tag: Zir.Inst.Tag, |
| ... | ... | @@ -9991,6 +9982,30 @@ const GenZir = struct { |
| 9991 | 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 | 10009 | fn addUnTok( |
| 9995 | 10010 | gz: *GenZir, |
| 9996 | 10011 | tag: Zir.Inst.Tag, |