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 {...@@ -217,6 +217,11 @@ pub const DeclGen = struct {
217 try writer.writeAll(" }");217 try writer.writeAll(" }");
218 }218 }
219 },219 },
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 },
220 else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement value {s}", .{225 else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement value {s}", .{
221 @tagName(e),226 @tagName(e),
222 }),227 }),
...@@ -327,6 +332,16 @@ pub const DeclGen = struct {...@@ -327,6 +332,16 @@ pub const DeclGen = struct {
327 try dg.renderType(w, child_type);332 try dg.renderType(w, child_type);
328 try w.writeAll(" payload; bool is_null; }");333 try w.writeAll(" payload; bool is_null; }");
329 },334 },
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 },
330 .Null, .Undefined => unreachable, // must be const or comptime345 .Null, .Undefined => unreachable, // must be const or comptime
331 else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement type {s}", .{346 else => |e| return dg.fail(dg.decl.src(), "TODO: C backend: implement type {s}", .{
332 @tagName(e),347 @tagName(e),
...@@ -464,6 +479,8 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi...@@ -464,6 +479,8 @@ pub fn genBody(o: *Object, body: ir.Body) error{ AnalysisFail, OutOfMemory }!voi
464 .wrap_optional => try genWrapOptional(o, inst.castTag(.wrap_optional).?),479 .wrap_optional => try genWrapOptional(o, inst.castTag(.wrap_optional).?),
465 .optional_payload => try genOptionalPayload(o, inst.castTag(.optional_payload).?),480 .optional_payload => try genOptionalPayload(o, inst.castTag(.optional_payload).?),
466 .optional_payload_ptr => try genOptionalPayload(o, inst.castTag(.optional_payload).?),481 .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).?),
467 else => |e| return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement codegen for {}", .{e}),484 else => |e| return o.dg.fail(o.dg.decl.src(), "TODO: C backend: implement codegen for {}", .{e}),
468 };485 };
469 switch (result_value) {486 switch (result_value) {
...@@ -900,6 +917,18 @@ fn genWrapOptional(o: *Object, inst: *Inst.UnOp) !CValue {...@@ -900,6 +917,18 @@ fn genWrapOptional(o: *Object, inst: *Inst.UnOp) !CValue {
900 return local;917 return local;
901}918}
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
903fn IndentWriter(comptime UnderlyingWriter: type) type {932fn IndentWriter(comptime UnderlyingWriter: type) type {
904 return struct {933 return struct {
905 const Self = @This();934 const Self = @This();
src/link/C.zig+13
...@@ -150,6 +150,19 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {...@@ -150,6 +150,19 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {
150 .iov_len = zig_h.len,150 .iov_len = zig_h.len,
151 });151 });
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
153 var fn_count: usize = 0;166 var fn_count: usize = 0;
154167
155 // Forward decls and non-functions first.168 // Forward decls and non-functions first.
src/type.zig+12
...@@ -1813,6 +1813,18 @@ pub const Type = extern union {...@@ -1813,6 +1813,18 @@ pub const Type = extern union {
1813 }1813 }
1814 }1814 }
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
1816 /// Asserts the type is an array or vector.1828 /// Asserts the type is an array or vector.
1817 pub fn arrayLen(self: Type) u64 {1829 pub fn arrayLen(self: Type) u64 {
1818 return switch (self.tag()) {1830 return switch (self.tag()) {