authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-01-29 18:20:35+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-03-08 00:33:07+02:00
logcfc19eace71c92ecd7e138db6d961271a1b6c126
treea95c89dbf3b86a83747203c406b4fbb34a1eaad2
parentc22f010fdd2c5ead80cbdc902738a9d023322436
signature Commit is signed but in an unrecognized format.

stage2 cbe: errors


3 files changed, 54 insertions(+), 0 deletions(-)

src/codegen/c.zig+29
......@@ -217,6 +217,11 @@ pub const DeclGen = struct {
217217 try writer.writeAll(" }");
218218 }
219219 },
220 .ErrorSet => {
221 const payload = val.castTag(.@"error").?;
222 // error values will be #defined at the top of the file
223 return writer.print("zig_error_{s}", .{payload.data.name});
224 },
220225 else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement value {s}", .{
221226 @tagName(e),
222227 }),
......@@ -327,6 +332,16 @@ pub const DeclGen = struct {
327332 try dg.renderType(w, child_type);
328333 try w.writeAll(" payload; bool is_null; }");
329334 },
335 .ErrorSet => {
336 comptime std.debug.assert(Type.initTag(.anyerror).abiSize(std.Target.current) == 2);
337 try w.writeAll("uint16_t");
338 },
339 .ErrorUnion => {
340 // TODO this needs to be typedeffed since different structs are different types.
341 try w.writeAll("struct { ");
342 try dg.renderType(w, t.errorUnionChild());
343 try w.writeAll(" payload; uint16_t error; }");
344 },
330345 .Null, .Undefined => unreachable, // must be const or comptime
331346 else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement type {s}", .{
332347 @tagName(e),
......@@ -464,6 +479,8 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi
464479 .wrap_optional => try genWrapOptional(o, inst.castTag(.wrap_optional).?),
465480 .optional_payload => try genOptionalPayload(o, inst.castTag(.optional_payload).?),
466481 .optional_payload_ptr => try genOptionalPayload(o, inst.castTag(.optional_payload).?),
482 .is_err => try genIsErr(o, inst.castTag(.is_err).?),
483 .is_err_ptr => try genIsErr(o, inst.castTag(.is_err_ptr).?),
467484 else => |e| return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement codegen for {}", .{e}),
468485 };
469486 switch (result_value) {
......@@ -900,6 +917,18 @@ fn genWrapOptional(o: *Object, inst: *Inst.UnOp) !CValue {
900917 return local;
901918}
902919
920fn genIsErr(o: *Object, inst: *Inst.UnOp) !CValue {
921 const writer = o.writer();
922 const maybe_deref = if (inst.base.tag == .is_err_ptr) "[0]" else "";
923 const operand = try o.resolveInst(inst.operand);
924
925 const local = try o.allocLocal(Type.initTag(.bool), .Const);
926 try writer.writeAll(" = (");
927 try o.writeCValue(writer, operand);
928 try writer.print("){s}.error != 0;\n", .{maybe_deref});
929 return local;
930}
931
903932fn IndentWriter(comptime UnderlyingWriter: type) type {
904933 return struct {
905934 const Self = @This();
src/link/C.zig+13
......@@ -150,6 +150,19 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {
150150 .iov_len = zig_h.len,
151151 });
152152
153 var error_defs_buf = std.ArrayList(u8).init(comp.gpa);
154 defer error_defs_buf.deinit();
155
156 var it = module.global_error_set.iterator();
157 while (it.next()) |entry| {
158 try error_defs_buf.writer().print("#define zig_error_{s} {d}\n", .{ entry.key, entry.value });
159 }
160 try error_defs_buf.writer().writeByte('\n');
161 all_buffers.appendAssumeCapacity(.{
162 .iov_base = error_defs_buf.items.ptr,
163 .iov_len = error_defs_buf.items.len,
164 });
165
153166 var fn_count: usize = 0;
154167
155168 // Forward decls and non-functions first.
src/type.zig+12
......@@ -1813,6 +1813,18 @@ pub const Type = extern union {
18131813 }
18141814 }
18151815
1816 /// Asserts that the type is an error union.
1817 pub fn errorUnionChild(self: Type) Type {
1818 return switch (self.tag()) {
1819 .anyerror_void_error_union => Type.initTag(.anyerror),
1820 .error_union => {
1821 const payload = self.castTag(.error_union).?;
1822 return payload.data.payload;
1823 },
1824 else => unreachable,
1825 };
1826 }
1827
18161828 /// Asserts the type is an array or vector.
18171829 pub fn arrayLen(self: Type) u64 {
18181830 return switch (self.tag()) {