authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-12 20:41:25+03:00
committergravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-10-21 10:43:42-07:00
log5316a00a188955d60cc38d56def51b8605181225
treed26f110e2472fe5ea0853056ab86924f17e046c0
parent28054d96f0ed5280660811612732cb000f9c09e8

stage2: properly reset error return trace index


4 files changed, 111 insertions(+), 5 deletions(-)

src/AstGen.zig+39-2
......@@ -2471,6 +2471,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
24712471 .try_ptr,
24722472 //.try_inline,
24732473 //.try_ptr_inline,
2474 .save_err_ret_index,
24742475 => break :b false,
24752476
24762477 .extended => switch (gz.astgen.instructions.items(.data)[inst].extended.opcode) {
......@@ -2533,6 +2534,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
25332534 .validate_array_init_ty,
25342535 .validate_struct_init_ty,
25352536 .validate_deref,
2537 .restore_err_ret_index,
25362538 => break :b true,
25372539
25382540 .@"defer" => unreachable,
......@@ -5152,10 +5154,16 @@ fn orelseCatchExpr(
51525154 const astgen = parent_gz.astgen;
51535155 const tree = astgen.tree;
51545156
5157 const do_err_trace = astgen.fn_block != null and (cond_op == .is_non_err or cond_op == .is_non_err_ptr);
5158
51555159 var block_scope = parent_gz.makeSubBlock(scope);
51565160 block_scope.setBreakResultLoc(rl);
51575161 defer block_scope.unstack();
51585162
5163 if (do_err_trace) {
5164 block_scope.saved_err_trace_index = try parent_gz.addNode(.save_err_ret_index, node);
5165 }
5166
51595167 const operand_rl: ResultLoc = switch (block_scope.break_result_loc) {
51605168 .ref => .ref,
51615169 else => .none,
......@@ -5220,7 +5228,7 @@ fn orelseCatchExpr(
52205228 // instructions or not.
52215229
52225230 const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break";
5223 return finishThenElseBlock(
5231 const result = try finishThenElseBlock(
52245232 parent_gz,
52255233 rl,
52265234 node,
......@@ -5235,6 +5243,16 @@ fn orelseCatchExpr(
52355243 block,
52365244 break_tag,
52375245 );
5246 if (do_err_trace) {
5247 _ = try parent_gz.add(.{
5248 .tag = .restore_err_ret_index,
5249 .data = .{ .un_node = .{
5250 .operand = parent_gz.saved_err_trace_index,
5251 .src_node = parent_gz.nodeIndexToRelative(node),
5252 } },
5253 });
5254 }
5255 return result;
52385256}
52395257
52405258/// Supports `else_scope` stacked on `then_scope` stacked on `block_scope`. Unstacks `else_scope` then `then_scope`.
......@@ -5430,10 +5448,16 @@ fn ifExpr(
54305448 const tree = astgen.tree;
54315449 const token_tags = tree.tokens.items(.tag);
54325450
5451 const do_err_trace = astgen.fn_block != null and if_full.error_token != null;
5452
54335453 var block_scope = parent_gz.makeSubBlock(scope);
54345454 block_scope.setBreakResultLoc(rl);
54355455 defer block_scope.unstack();
54365456
5457 if (do_err_trace) {
5458 block_scope.saved_err_trace_index = try parent_gz.addNode(.save_err_ret_index, node);
5459 }
5460
54375461 const payload_is_ref = if (if_full.payload_token) |payload_token|
54385462 token_tags[payload_token] == .asterisk
54395463 else
......@@ -5602,7 +5626,7 @@ fn ifExpr(
56025626 };
56035627
56045628 const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break";
5605 return finishThenElseBlock(
5629 const result = try finishThenElseBlock(
56065630 parent_gz,
56075631 rl,
56085632 node,
......@@ -5617,6 +5641,16 @@ fn ifExpr(
56175641 block,
56185642 break_tag,
56195643 );
5644 if (do_err_trace) {
5645 _ = try parent_gz.add(.{
5646 .tag = .restore_err_ret_index,
5647 .data = .{ .un_node = .{
5648 .operand = parent_gz.saved_err_trace_index,
5649 .src_node = parent_gz.nodeIndexToRelative(node),
5650 } },
5651 });
5652 }
5653 return result;
56205654}
56215655
56225656/// Supports `else_scope` stacked on `then_scope`. Unstacks `else_scope` then `then_scope`.
......@@ -10300,6 +10334,8 @@ const GenZir = struct {
1030010334 /// Keys are the raw instruction index, values are the closure_capture instruction.
1030110335 captures: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{},
1030210336
10337 saved_err_trace_index: Zir.Inst.Ref = .none,
10338
1030310339 const unstacked_top = std.math.maxInt(usize);
1030410340 /// Call unstack before adding any new instructions to containing GenZir.
1030510341 fn unstack(self: *GenZir) void {
......@@ -10344,6 +10380,7 @@ const GenZir = struct {
1034410380 .any_defer_node = gz.any_defer_node,
1034510381 .instructions = gz.instructions,
1034610382 .instructions_top = gz.instructions.items.len,
10383 .saved_err_trace_index = gz.saved_err_trace_index,
1034710384 };
1034810385 }
1034910386
src/Sema.zig+53-2
......@@ -926,6 +926,8 @@ fn analyzeBodyInner(
926926 .ret_ptr => try sema.zirRetPtr(block, inst),
927927 .ret_type => try sema.addType(sema.fn_ret_ty),
928928
929 .save_err_ret_index => try sema.zirSaveErrRetIndex(block, inst),
930
929931 // Instructions that we know to *always* be noreturn based solely on their tag.
930932 // These functions match the return type of analyzeBody so that we can
931933 // tail call them here.
......@@ -1208,6 +1210,11 @@ fn analyzeBodyInner(
12081210 i += 1;
12091211 continue;
12101212 },
1213 .restore_err_ret_index => {
1214 try sema.zirRestoreErrRetIndex(block, inst);
1215 i += 1;
1216 continue;
1217 },
12111218
12121219 // Special case instructions to handle comptime control flow.
12131220 .@"break" => {
......@@ -16176,6 +16183,52 @@ fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool {
1617616183 backend_supports_error_return_tracing;
1617716184}
1617816185
16186fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
16187 const inst_data = sema.code.instructions.items(.data)[inst].node;
16188 const src = LazySrcLoc.nodeOffset(inst_data);
16189
16190 // This is only relevant at runtime.
16191 if (block.is_comptime) return Air.Inst.Ref.zero_usize;
16192
16193 const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm;
16194 const ok = sema.owner_func.?.calls_or_awaits_errorable_fn and
16195 sema.mod.comp.bin_file.options.error_return_tracing and
16196 backend_supports_error_return_tracing;
16197 if (!ok) return Air.Inst.Ref.zero_usize;
16198
16199 const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace");
16200 const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty);
16201 const ptr_stack_trace_ty = try Type.Tag.single_mut_pointer.create(sema.arena, stack_trace_ty);
16202 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
16203 return sema.fieldVal(block, src, err_return_trace, "index", src);
16204}
16205
16206fn zirRestoreErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void {
16207 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
16208 const src = inst_data.src();
16209
16210 // This is only relevant at runtime.
16211 if (block.is_comptime) return;
16212
16213 const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm;
16214 const ok = sema.owner_func.?.calls_or_awaits_errorable_fn and
16215 sema.mod.comp.bin_file.options.error_return_tracing and
16216 backend_supports_error_return_tracing;
16217 if (!ok) return;
16218
16219 const operand = if (inst_data.operand != .none)
16220 try sema.resolveInst(inst_data.operand)
16221 else
16222 .zero_usize;
16223
16224 const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace");
16225 const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty);
16226 const ptr_stack_trace_ty = try Type.Tag.single_mut_pointer.create(sema.arena, stack_trace_ty);
16227 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
16228 const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, "index", src, stack_trace_ty, true);
16229 try sema.storePtr2(block, src, field_ptr, src, operand, src, .store);
16230}
16231
1617916232fn addToInferredErrorSet(sema: *Sema, uncasted_operand: Air.Inst.Ref) !void {
1618016233 assert(sema.fn_ret_ty.zigTypeTag() == .ErrorUnion);
1618116234
......@@ -17181,8 +17234,6 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1718117234
1718217235fn zirErrorName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1718317236 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
17184 const src = inst_data.src();
17185 _ = src;
1718617237 const operand = try sema.resolveInst(inst_data.operand);
1718717238 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
1718817239
src/Zir.zig+16
......@@ -988,6 +988,15 @@ pub const Inst = struct {
988988 /// Uses the `err_defer_code` union field.
989989 defer_err_code,
990990
991 /// Saves the current error return case if it exists,
992 /// otherwise just returns zero.
993 /// Uses the `node` union field.
994 save_err_ret_index,
995 /// Sets error return trace to zero if no operand is given,
996 /// otherwise sets the value to the given amount.
997 /// Uses the `un_node` union field.
998 restore_err_ret_index,
999
9911000 /// The ZIR instruction tag is one of the `Extended` ones.
9921001 /// Uses the `extended` union field.
9931002 extended,
......@@ -1236,6 +1245,8 @@ pub const Inst = struct {
12361245 //.try_ptr_inline,
12371246 .@"defer",
12381247 .defer_err_code,
1248 .save_err_ret_index,
1249 .restore_err_ret_index,
12391250 => false,
12401251
12411252 .@"break",
......@@ -1305,6 +1316,7 @@ pub const Inst = struct {
13051316 .check_comptime_control_flow,
13061317 .@"defer",
13071318 .defer_err_code,
1319 .restore_err_ret_index,
13081320 => true,
13091321
13101322 .param,
......@@ -1530,6 +1542,7 @@ pub const Inst = struct {
15301542 .try_ptr,
15311543 //.try_inline,
15321544 //.try_ptr_inline,
1545 .save_err_ret_index,
15331546 => false,
15341547
15351548 .extended => switch (data.extended.opcode) {
......@@ -1810,6 +1823,9 @@ pub const Inst = struct {
18101823 .@"defer" = .@"defer",
18111824 .defer_err_code = .defer_err_code,
18121825
1826 .save_err_ret_index = .node,
1827 .restore_err_ret_index = .un_node,
1828
18131829 .extended = .extended,
18141830 });
18151831 };
src/print_zir.zig+3-1
......@@ -232,6 +232,7 @@ const Writer = struct {
232232 .validate_deref,
233233 .overflow_arithmetic_ptr,
234234 .check_comptime_control_flow,
235 .restore_err_ret_index,
235236 => try self.writeUnNode(stream, inst),
236237
237238 .ref,
......@@ -405,6 +406,7 @@ const Writer = struct {
405406 .alloc_inferred_comptime_mut,
406407 .ret_ptr,
407408 .ret_type,
409 .save_err_ret_index,
408410 => try self.writeNode(stream, inst),
409411
410412 .error_value,
......@@ -440,7 +442,7 @@ const Writer = struct {
440442
441443 .dbg_block_begin,
442444 .dbg_block_end,
443 => try stream.writeAll("))"),
445 => try stream.writeAll(")"),
444446
445447 .closure_get => try self.writeInstNode(stream, inst),
446448