| author | |
| committer | |
| log | 72bcdb639f24ae08022935453ea2aec95a2113ca |
| tree | 4c329fca390853f7f017ee74eed2a98de7ca1faf |
| parent | 4cfd5f6a300a97778ec515319656c6f1c0ca6ec5 |
| signature | Commit is signed but in an unrecognized format. |
2 files changed, 87 insertions(+), 63 deletions(-)
src/Module.zig+46-6| ... | @@ -1045,10 +1045,10 @@ pub const Scope = struct { | ... | @@ -1045,10 +1045,10 @@ pub const Scope = struct { |
| 1045 | try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len + | 1045 | try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len + |
| 1046 | @typeInfo(zir.Inst.FnTypeCc).Struct.fields.len + args.param_types.len); | 1046 | @typeInfo(zir.Inst.FnTypeCc).Struct.fields.len + args.param_types.len); |
| 1047 | 1047 | ||
| 1048 | const payload_index = gz.zir_code.addExtra(zir.Inst.FnTypeCc{ | 1048 | const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.FnTypeCc{ |
| 1049 | .cc = args.cc, | 1049 | .cc = args.cc, |
| 1050 | .param_types_len = @intCast(u32, args.param_types.len), | 1050 | .param_types_len = @intCast(u32, args.param_types.len), |
| 1051 | }) catch unreachable; // Capacity is ensured above. | 1051 | }); |
| 1052 | gz.zir_code.extra.appendSliceAssumeCapacity(args.param_types); | 1052 | gz.zir_code.extra.appendSliceAssumeCapacity(args.param_types); |
| 1053 | 1053 | ||
| 1054 | const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); | 1054 | const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); |
| ... | @@ -1076,9 +1076,9 @@ pub const Scope = struct { | ... | @@ -1076,9 +1076,9 @@ pub const Scope = struct { |
| 1076 | try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len + | 1076 | try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len + |
| 1077 | @typeInfo(zir.Inst.FnType).Struct.fields.len + param_types.len); | 1077 | @typeInfo(zir.Inst.FnType).Struct.fields.len + param_types.len); |
| 1078 | 1078 | ||
| 1079 | const payload_index = gz.zir_code.addExtra(zir.Inst.FnType{ | 1079 | const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.FnType{ |
| 1080 | .param_types_len = @intCast(u32, param_types.len), | 1080 | .param_types_len = @intCast(u32, param_types.len), |
| 1081 | }) catch unreachable; // Capacity is ensured above. | 1081 | }); |
| 1082 | gz.zir_code.extra.appendSliceAssumeCapacity(param_types); | 1082 | gz.zir_code.extra.appendSliceAssumeCapacity(param_types); |
| 1083 | 1083 | ||
| 1084 | const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); | 1084 | const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); |
| ... | @@ -1093,6 +1093,41 @@ pub const Scope = struct { | ... | @@ -1093,6 +1093,41 @@ pub const Scope = struct { |
| 1093 | return new_index + gz.zir_code.ref_start_index; | 1093 | return new_index + gz.zir_code.ref_start_index; |
| 1094 | } | 1094 | } |
| 1095 | 1095 | ||
| 1096 | pub fn addCondBr( | ||
| 1097 | gz: *GenZir, | ||
| 1098 | condition: zir.Inst.Ref, | ||
| 1099 | then_body: []const zir.Inst.Ref, | ||
| 1100 | else_body: []const zir.Inst.Ref, | ||
| 1101 | /// Absolute node index. This function does the conversion to offset from Decl. | ||
| 1102 | abs_node_index: ast.Node.Index, | ||
| 1103 | ) !zir.Inst.Ref { | ||
| 1104 | const gpa = gz.zir_code.gpa; | ||
| 1105 | try gz.instructions.ensureCapacity(gpa, gz.instructions.items.len + 1); | ||
| 1106 | try gz.zir_code.instructions.ensureCapacity(gpa, gz.zir_code.instructions.len + 1); | ||
| 1107 | try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len + | ||
| 1108 | @typeInfo(zir.Inst.CondBr).Struct.fields.len + then_body.len + else_body.len); | ||
| 1109 | |||
| 1110 | const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.CondBr{ | ||
| 1111 | .condition = condition, | ||
| 1112 | .then_body_len = @intCast(u32, then_body.len), | ||
| 1113 | .else_body_len = @intCast(u32, else_body.len), | ||
| 1114 | }); | ||
| 1115 | gz.zir_code.extra.appendSliceAssumeCapacity(then_body); | ||
| 1116 | gz.zir_code.extra.appendSliceAssumeCapacity(else_body); | ||
| 1117 | |||
| 1118 | const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); | ||
| 1119 | gz.zir_code.instructions.appendAssumeCapacity(.{ | ||
| 1120 | .tag = .condbr, | ||
| 1121 | .data = .{ .pl_node = .{ | ||
| 1122 | .src_node = gz.zir_code.decl.nodeIndexToRelative(abs_node_index), | ||
| 1123 | .payload_index = payload_index, | ||
| 1124 | } }, | ||
| 1125 | }); | ||
| 1126 | gz.instructions.appendAssumeCapacity(new_index); | ||
| 1127 | |||
| 1128 | return new_index + gz.zir_code.ref_start_index; | ||
| 1129 | } | ||
| 1130 | |||
| 1096 | pub fn addCall( | 1131 | pub fn addCall( |
| 1097 | gz: *GenZir, | 1132 | gz: *GenZir, |
| 1098 | tag: zir.Inst.Tag, | 1133 | tag: zir.Inst.Tag, |
| ... | @@ -1109,10 +1144,10 @@ pub const Scope = struct { | ... | @@ -1109,10 +1144,10 @@ pub const Scope = struct { |
| 1109 | try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len + | 1144 | try gz.zir_code.extra.ensureCapacity(gpa, gz.zir_code.extra.items.len + |
| 1110 | @typeInfo(zir.Inst.Call).Struct.fields.len + args.len); | 1145 | @typeInfo(zir.Inst.Call).Struct.fields.len + args.len); |
| 1111 | 1146 | ||
| 1112 | const payload_index = gz.zir_code.addExtra(zir.Inst.Call{ | 1147 | const payload_index = gz.zir_code.addExtraAssumeCapacity(zir.Inst.Call{ |
| 1113 | .callee = callee, | 1148 | .callee = callee, |
| 1114 | .args_len = @intCast(u32, args.len), | 1149 | .args_len = @intCast(u32, args.len), |
| 1115 | }) catch unreachable; // Capacity is ensured above. | 1150 | }); |
| 1116 | gz.zir_code.extra.appendSliceAssumeCapacity(args); | 1151 | gz.zir_code.extra.appendSliceAssumeCapacity(args); |
| 1117 | 1152 | ||
| 1118 | const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); | 1153 | const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); |
| ... | @@ -1356,6 +1391,11 @@ pub const WipZirCode = struct { | ... | @@ -1356,6 +1391,11 @@ pub const WipZirCode = struct { |
| 1356 | pub fn addExtra(wzc: *WipZirCode, extra: anytype) Allocator.Error!u32 { | 1391 | pub fn addExtra(wzc: *WipZirCode, extra: anytype) Allocator.Error!u32 { |
| 1357 | const fields = std.meta.fields(@TypeOf(extra)); | 1392 | const fields = std.meta.fields(@TypeOf(extra)); |
| 1358 | try wzc.extra.ensureCapacity(wzc.gpa, wzc.extra.items.len + fields.len); | 1393 | try wzc.extra.ensureCapacity(wzc.gpa, wzc.extra.items.len + fields.len); |
| 1394 | return addExtraAssumeCapacity(wzc, extra); | ||
| 1395 | } | ||
| 1396 | |||
| 1397 | pub fn addExtraAssumeCapacity(wzc: *WipZirCode, extra: anytype) u32 { | ||
| 1398 | const fields = std.meta.fields(@TypeOf(extra)); | ||
| 1359 | const result = @intCast(u32, wzc.extra.items.len); | 1399 | const result = @intCast(u32, wzc.extra.items.len); |
| 1360 | inline for (fields) |field| { | 1400 | inline for (fields) |field| { |
| 1361 | comptime assert(field.field_type == u32); | 1401 | comptime assert(field.field_type == u32); |
src/astgen.zig+41-57| ... | @@ -370,8 +370,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In | ... | @@ -370,8 +370,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In |
| 370 | .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat), | 370 | .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat), |
| 371 | .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul), | 371 | .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul), |
| 372 | 372 | ||
| 373 | .bool_and => return boolBinOp(mod, scope, rl, node, true), | 373 | .bool_and => return boolBinOp(mod, scope, rl, node, .bool_and), |
| 374 | .bool_or => return boolBinOp(mod, scope, rl, node, false), | 374 | .bool_or => return boolBinOp(mod, scope, rl, node, .bool_or), |
| 375 | 375 | ||
| 376 | .bool_not => return boolNot(mod, scope, rl, node), | 376 | .bool_not => return boolNot(mod, scope, rl, node), |
| 377 | .bit_not => return bitNot(mod, scope, rl, node), | 377 | .bit_not => return bitNot(mod, scope, rl, node), |
| ... | @@ -1805,87 +1805,71 @@ fn boolBinOp( | ... | @@ -1805,87 +1805,71 @@ fn boolBinOp( |
| 1805 | scope: *Scope, | 1805 | scope: *Scope, |
| 1806 | rl: ResultLoc, | 1806 | rl: ResultLoc, |
| 1807 | infix_node: ast.Node.Index, | 1807 | infix_node: ast.Node.Index, |
| 1808 | is_bool_and: bool, | 1808 | kind: enum { bool_and, bool_or }, |
| 1809 | ) InnerError!zir.Inst.Ref { | 1809 | ) InnerError!zir.Inst.Ref { |
| 1810 | if (true) @panic("TODO update for zir-memory-layout"); | ||
| 1811 | const tree = scope.tree(); | 1810 | const tree = scope.tree(); |
| 1812 | const node_datas = tree.nodes.items(.data); | 1811 | const node_datas = tree.nodes.items(.data); |
| 1813 | const main_tokens = tree.nodes.items(.main_token); | 1812 | const bool_type = @enumToInt(zir.Const.bool_type); |
| 1813 | const gz = scope.getGenZir(); | ||
| 1814 | 1814 | ||
| 1815 | const bool_type = try addZIRInstConst(mod, scope, src, .{ | 1815 | const lhs = try expr(mod, scope, .{ .ty = bool_type }, node_datas[infix_node].lhs); |
| 1816 | .ty = Type.initTag(.type), | ||
| 1817 | .val = Value.initTag(.bool_type), | ||
| 1818 | }); | ||
| 1819 | 1816 | ||
| 1817 | const block_inst = try gz.addBlock(.block, infix_node); | ||
| 1818 | const block_ref = gz.zir_code.ref_start_index + block_inst; | ||
| 1820 | var block_scope: Scope.GenZir = .{ | 1819 | var block_scope: Scope.GenZir = .{ |
| 1821 | .parent = scope, | 1820 | .parent = scope, |
| 1822 | .decl = scope.ownerDecl().?, | 1821 | .zir_code = gz.zir_code, |
| 1823 | .arena = scope.arena(), | 1822 | .force_comptime = gz.force_comptime, |
| 1824 | .force_comptime = scope.isComptime(), | ||
| 1825 | .instructions = .{}, | ||
| 1826 | }; | 1823 | }; |
| 1827 | defer block_scope.instructions.deinit(mod.gpa); | 1824 | defer block_scope.instructions.deinit(mod.gpa); |
| 1828 | 1825 | ||
| 1829 | const lhs = try expr(mod, scope, .{ .ty = bool_type }, node_datas[infix_node].lhs); | ||
| 1830 | const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{ | ||
| 1831 | .condition = lhs, | ||
| 1832 | .then_body = undefined, // populated below | ||
| 1833 | .else_body = undefined, // populated below | ||
| 1834 | }, .{}); | ||
| 1835 | |||
| 1836 | const block = try addZIRInstBlock(mod, scope, src, .block, .{ | ||
| 1837 | .instructions = try block_scope.arena.dupe(zir.Inst.Ref, block_scope.instructions.items), | ||
| 1838 | }); | ||
| 1839 | |||
| 1840 | var rhs_scope: Scope.GenZir = .{ | 1826 | var rhs_scope: Scope.GenZir = .{ |
| 1841 | .parent = scope, | 1827 | .parent = &block_scope.base, |
| 1842 | .decl = block_scope.decl, | 1828 | .zir_code = gz.zir_code, |
| 1843 | .arena = block_scope.arena, | 1829 | .force_comptime = gz.force_comptime, |
| 1844 | .force_comptime = block_scope.force_comptime, | ||
| 1845 | .instructions = .{}, | ||
| 1846 | }; | 1830 | }; |
| 1847 | defer rhs_scope.instructions.deinit(mod.gpa); | 1831 | defer rhs_scope.instructions.deinit(mod.gpa); |
| 1848 | |||
| 1849 | const rhs = try expr(mod, &rhs_scope.base, .{ .ty = bool_type }, node_datas[infix_node].rhs); | 1832 | const rhs = try expr(mod, &rhs_scope.base, .{ .ty = bool_type }, node_datas[infix_node].rhs); |
| 1850 | _ = try addZIRInst(mod, &rhs_scope.base, src, zir.Inst.Break, .{ | 1833 | _ = try rhs_scope.addBin(.@"break", block_inst, rhs); |
| 1851 | .block = block, | ||
| 1852 | .operand = rhs, | ||
| 1853 | }, .{}); | ||
| 1854 | 1834 | ||
| 1855 | var const_scope: Scope.GenZir = .{ | 1835 | // TODO: should we have zir.Const instructions for `break true` and `break false`? |
| 1856 | .parent = scope, | 1836 | const new_index = @intCast(zir.Inst.Index, gz.zir_code.instructions.len); |
| 1857 | .decl = block_scope.decl, | 1837 | const break_true_false_ref = new_index + gz.zir_code.ref_start_index; |
| 1858 | .arena = block_scope.arena, | 1838 | try gz.zir_code.instructions.append(gz.zir_code.gpa, .{ .tag = .@"break", .data = .{ .bin = .{ |
| 1859 | .force_comptime = block_scope.force_comptime, | 1839 | .lhs = block_inst, |
| 1860 | .instructions = .{}, | 1840 | .rhs = switch (kind) { |
| 1861 | }; | 1841 | .bool_and => @enumToInt(zir.Const.bool_false), |
| 1862 | defer const_scope.instructions.deinit(mod.gpa); | 1842 | .bool_or => @enumToInt(zir.Const.bool_true), |
| 1863 | 1843 | }, | |
| 1864 | _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{ | 1844 | } } }); |
| 1865 | .block = block, | ||
| 1866 | .operand = try addZIRInstConst(mod, &const_scope.base, src, .{ | ||
| 1867 | .ty = Type.initTag(.bool), | ||
| 1868 | .val = if (is_bool_and) Value.initTag(.bool_false) else Value.initTag(.bool_true), | ||
| 1869 | }), | ||
| 1870 | }, .{}); | ||
| 1871 | 1845 | ||
| 1872 | if (is_bool_and) { | 1846 | switch (kind) { |
| 1873 | // if lhs // AND | 1847 | // if lhs // AND |
| 1874 | // break rhs | 1848 | // break rhs |
| 1875 | // else | 1849 | // else |
| 1876 | // break false | 1850 | // break false |
| 1877 | condbr.positionals.then_body = .{ .instructions = try rhs_scope.arena.dupe(zir.Inst.Ref, rhs_scope.instructions.items) }; | 1851 | .bool_and => _ = try block_scope.addCondBr( |
| 1878 | condbr.positionals.else_body = .{ .instructions = try const_scope.arena.dupe(zir.Inst.Ref, const_scope.instructions.items) }; | 1852 | lhs, |
| 1879 | } else { | 1853 | rhs_scope.instructions.items, |
| 1854 | &[_]zir.Inst.Ref{break_true_false_ref}, | ||
| 1855 | infix_node, | ||
| 1856 | ), | ||
| 1880 | // if lhs // OR | 1857 | // if lhs // OR |
| 1881 | // break true | 1858 | // break true |
| 1882 | // else | 1859 | // else |
| 1883 | // break rhs | 1860 | // break rhs |
| 1884 | condbr.positionals.then_body = .{ .instructions = try const_scope.arena.dupe(zir.Inst.Ref, const_scope.instructions.items) }; | 1861 | .bool_or => _ = try block_scope.addCondBr( |
| 1885 | condbr.positionals.else_body = .{ .instructions = try rhs_scope.arena.dupe(zir.Inst.Ref, rhs_scope.instructions.items) }; | 1862 | lhs, |
| 1863 | &[_]zir.Inst.Ref{break_true_false_ref}, | ||
| 1864 | rhs_scope.instructions.items, | ||
| 1865 | infix_node, | ||
| 1866 | ), | ||
| 1886 | } | 1867 | } |
| 1887 | 1868 | ||
| 1888 | return rvalue(mod, scope, rl, &block.base); | 1869 | try gz.instructions.append(mod.gpa, block_inst); |
| 1870 | try copyBodyNoEliding(block_inst, block_scope); | ||
| 1871 | |||
| 1872 | return rvalue(mod, scope, rl, block_ref, infix_node); | ||
| 1889 | } | 1873 | } |
| 1890 | 1874 | ||
| 1891 | fn ifExpr( | 1875 | fn ifExpr( |