authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-20 16:35:24+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-22 21:56:34+01:00
logf4f23e307c7a493435bed155359a5f3a2b57d965
tree05eb45a407bf3703148aaf059a84634b8b166c12
parent358b5441570916a48f2f7df9ebe8b9cb5f87676b

codegen: lower error_set and error_union


3 files changed, 52 insertions(+), 6 deletions(-)

src/arch/x86_64/CodeGen.zig+3-6
......@@ -3509,6 +3509,7 @@ fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {
35093509 return self.fail("TODO isErr for errors with size larger than register size", .{});
35103510 }
35113511 } else {
3512 log.warn("operand = {}, payload_type = {}", .{ operand, payload_type });
35123513 return self.fail("TODO isErr for non-empty payloads", .{});
35133514 }
35143515}
......@@ -5108,22 +5109,18 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
51085109 const error_type = typed_value.ty.errorUnionSet();
51095110 const payload_type = typed_value.ty.errorUnionPayload();
51105111
5111 if (typed_value.val.castTag(.eu_payload)) |pl| {
5112 if (typed_value.val.castTag(.eu_payload)) |_| {
51125113 if (!payload_type.hasRuntimeBits()) {
51135114 // We use the error type directly as the type.
51145115 return MCValue{ .immediate = 0 };
51155116 }
5116
5117 _ = pl;
5118 return self.fail("TODO implement error union const of type '{}' (non-error)", .{typed_value.ty});
51195117 } else {
51205118 if (!payload_type.hasRuntimeBits()) {
51215119 // We use the error type directly as the type.
51225120 return self.genTypedValue(.{ .ty = error_type, .val = typed_value.val });
51235121 }
51245122 }
5125
5126 return self.fail("TODO implement error union const of type '{}' (error)", .{typed_value.ty});
5123 return self.lowerUnnamedConst(typed_value);
51275124 },
51285125 .Struct => {
51295126 return self.lowerUnnamedConst(typed_value);
src/codegen.zig+48
......@@ -432,6 +432,54 @@ pub fn generateSymbol(
432432
433433 return Result{ .appended = {} };
434434 },
435 .ErrorUnion => {
436 const error_ty = typed_value.ty.errorUnionSet();
437 const payload_ty = typed_value.ty.errorUnionPayload();
438 const is_payload = typed_value.val.errorUnionIsPayload();
439
440 const error_val = if (!is_payload) typed_value.val else Value.initTag(.zero);
441 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
442 .ty = error_ty,
443 .val = error_val,
444 }, code, debug_output)) {
445 .appended => {},
446 .externally_managed => |external_slice| {
447 code.appendSliceAssumeCapacity(external_slice);
448 },
449 .fail => |em| return Result{ .fail = em },
450 }
451
452 if (payload_ty.hasRuntimeBits()) {
453 const payload_val = if (typed_value.val.castTag(.eu_payload)) |val| val.data else Value.initTag(.undef);
454 switch (try generateSymbol(bin_file, parent_atom_index, src_loc, .{
455 .ty = payload_ty,
456 .val = payload_val,
457 }, code, debug_output)) {
458 .appended => {},
459 .externally_managed => |external_slice| {
460 code.appendSliceAssumeCapacity(external_slice);
461 },
462 .fail => |em| return Result{ .fail = em },
463 }
464 }
465
466 return Result{ .appended = {} };
467 },
468 .ErrorSet => {
469 const target = bin_file.options.target;
470 switch (typed_value.val.tag()) {
471 .@"error" => {
472 const name = typed_value.val.getError().?;
473 const kv = try bin_file.options.module.?.getErrorValue(name);
474 const endian = target.cpu.arch.endian();
475 try code.writer().writeInt(u32, kv.value, endian);
476 },
477 else => {
478 try code.writer().writeByteNTimes(0, @intCast(usize, typed_value.ty.abiSize(target)));
479 },
480 }
481 return Result{ .appended = {} };
482 },
435483 else => |t| {
436484 return Result{
437485 .fail = try ErrorMsg.create(
src/link/Elf.zig+1
......@@ -3127,6 +3127,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl: *Module.Decl
31273127 .fail => |em| {
31283128 decl.analysis = .codegen_failure;
31293129 try module.failed_decls.put(module.gpa, decl, em);
3130 log.err("{s}", .{em.msg});
31303131 return error.AnalysisFail;
31313132 },
31323133 };