| author | |
| committer | |
| log | 7598a00f34e91375bc8d4f57e8f5ecbc0d1b4d14 |
| tree | 75338d2cf30fb9092692d0b447d8e2cd610d3023 |
| parent | d8692b8bdb4630f2bb2763cdbe609de7d73b28d8 |
* free Module.Fn ZIR code when destroying the owner Decl
* unreachable_safe and unreachable_unsafe are collapsed into one ZIR
instruction with a safety flag.
* astgen: emit an unreachable instruction for unreachable literals
* don't forget to call deinit on ZIR code
* astgen: implement some builtin functions5 files changed, 114 insertions(+), 84 deletions(-)
src/Module.zig+23-10| ... | ... | @@ -224,6 +224,10 @@ pub const Decl = struct { |
| 224 | 224 | const gpa = module.gpa; |
| 225 | 225 | gpa.free(mem.spanZ(decl.name)); |
| 226 | 226 | if (decl.typedValueManaged()) |tvm| { |
| 227 | if (tvm.typed_value.val.castTag(.function)) |payload| { | |
| 228 | const func = payload.data; | |
| 229 | func.deinit(gpa); | |
| 230 | } | |
| 227 | 231 | tvm.deinit(gpa); |
| 228 | 232 | } |
| 229 | 233 | decl.dependants.deinit(gpa); |
| ... | ... | @@ -334,7 +338,7 @@ pub const EmitH = struct { |
| 334 | 338 | fwd_decl: std.ArrayListUnmanaged(u8) = .{}, |
| 335 | 339 | }; |
| 336 | 340 | |
| 337 | /// Fn struct memory is owned by the Decl's TypedValue.Managed arena allocator. | |
| 341 | /// Some Fn struct memory is owned by the Decl's TypedValue.Managed arena allocator. | |
| 338 | 342 | /// Extern functions do not have this data structure; they are represented by |
| 339 | 343 | /// the `Decl` only, with a `Value` tag of `extern_fn`. |
| 340 | 344 | pub const Fn = struct { |
| ... | ... | @@ -347,6 +351,7 @@ pub const Fn = struct { |
| 347 | 351 | /// The number of parameters is determined by referring to the type. |
| 348 | 352 | /// The first N elements of `extra` are indexes into `string_bytes` to |
| 349 | 353 | /// a null-terminated string. |
| 354 | /// This memory is managed with gpa, must be freed when the function is freed. | |
| 350 | 355 | zir: zir.Code, |
| 351 | 356 | /// undefined unless analysis state is `success`. |
| 352 | 357 | body: ir.Body, |
| ... | ... | @@ -370,6 +375,10 @@ pub const Fn = struct { |
| 370 | 375 | pub fn dump(func: *Fn, mod: Module) void { |
| 371 | 376 | ir.dumpFn(mod, func); |
| 372 | 377 | } |
| 378 | ||
| 379 | pub fn deinit(func: *Fn, gpa: *Allocator) void { | |
| 380 | func.zir.deinit(gpa); | |
| 381 | } | |
| 373 | 382 | }; |
| 374 | 383 | |
| 375 | 384 | pub const Var = struct { |
| ... | ... | @@ -1502,8 +1511,7 @@ pub const WipZirCode = struct { |
| 1502 | 1511 | .ret_node, |
| 1503 | 1512 | .ret_tok, |
| 1504 | 1513 | .ret_coerce, |
| 1505 | .unreachable_unsafe, | |
| 1506 | .unreachable_safe, | |
| 1514 | .@"unreachable", | |
| 1507 | 1515 | .loop, |
| 1508 | 1516 | .suspend_block, |
| 1509 | 1517 | .suspend_block_one, |
| ... | ... | @@ -1521,6 +1529,7 @@ pub const WipZirCode = struct { |
| 1521 | 1529 | pub fn deinit(wzc: *WipZirCode) void { |
| 1522 | 1530 | wzc.instructions.deinit(wzc.gpa); |
| 1523 | 1531 | wzc.extra.deinit(wzc.gpa); |
| 1532 | wzc.string_bytes.deinit(wzc.gpa); | |
| 1524 | 1533 | } |
| 1525 | 1534 | }; |
| 1526 | 1535 | |
| ... | ... | @@ -2078,7 +2087,7 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool { |
| 2078 | 2087 | var analysis_arena = std.heap.ArenaAllocator.init(mod.gpa); |
| 2079 | 2088 | defer analysis_arena.deinit(); |
| 2080 | 2089 | |
| 2081 | const code: zir.Code = blk: { | |
| 2090 | var code: zir.Code = blk: { | |
| 2082 | 2091 | var wip_zir_code: WipZirCode = .{ |
| 2083 | 2092 | .decl = decl, |
| 2084 | 2093 | .arena = &analysis_arena.allocator, |
| ... | ... | @@ -2102,6 +2111,7 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool { |
| 2102 | 2111 | } |
| 2103 | 2112 | break :blk code; |
| 2104 | 2113 | }; |
| 2114 | defer code.deinit(mod.gpa); | |
| 2105 | 2115 | |
| 2106 | 2116 | var sema: Sema = .{ |
| 2107 | 2117 | .mod = mod, |
| ... | ... | @@ -2154,17 +2164,17 @@ fn astgenAndSemaFn( |
| 2154 | 2164 | var fn_type_scope_arena = std.heap.ArenaAllocator.init(mod.gpa); |
| 2155 | 2165 | defer fn_type_scope_arena.deinit(); |
| 2156 | 2166 | |
| 2157 | var fn_type_wip_zir_exec: WipZirCode = .{ | |
| 2167 | var fn_type_wip_zir_code: WipZirCode = .{ | |
| 2158 | 2168 | .decl = decl, |
| 2159 | 2169 | .arena = &fn_type_scope_arena.allocator, |
| 2160 | 2170 | .gpa = mod.gpa, |
| 2161 | 2171 | }; |
| 2162 | defer fn_type_wip_zir_exec.deinit(); | |
| 2172 | defer fn_type_wip_zir_code.deinit(); | |
| 2163 | 2173 | |
| 2164 | 2174 | var fn_type_scope: Scope.GenZir = .{ |
| 2165 | 2175 | .force_comptime = true, |
| 2166 | 2176 | .parent = &decl.container.base, |
| 2167 | .zir_code = &fn_type_wip_zir_exec, | |
| 2177 | .zir_code = &fn_type_wip_zir_code, | |
| 2168 | 2178 | }; |
| 2169 | 2179 | defer fn_type_scope.instructions.deinit(mod.gpa); |
| 2170 | 2180 | |
| ... | ... | @@ -2317,7 +2327,8 @@ fn astgenAndSemaFn( |
| 2317 | 2327 | errdefer decl_arena.deinit(); |
| 2318 | 2328 | const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State); |
| 2319 | 2329 | |
| 2320 | const fn_type_code = try fn_type_scope.finish(); | |
| 2330 | var fn_type_code = try fn_type_scope.finish(); | |
| 2331 | defer fn_type_code.deinit(mod.gpa); | |
| 2321 | 2332 | if (std.builtin.mode == .Debug and mod.comp.verbose_ir) { |
| 2322 | 2333 | fn_type_code.dump(mod.gpa, "fn_type", &fn_type_scope.base, 0) catch {}; |
| 2323 | 2334 | } |
| ... | ... | @@ -2621,7 +2632,8 @@ fn astgenAndSemaVarDecl( |
| 2621 | 2632 | init_result_loc, |
| 2622 | 2633 | var_decl.ast.init_node, |
| 2623 | 2634 | ); |
| 2624 | const code = try gen_scope.finish(); | |
| 2635 | var code = try gen_scope.finish(); | |
| 2636 | defer code.deinit(mod.gpa); | |
| 2625 | 2637 | if (std.builtin.mode == .Debug and mod.comp.verbose_ir) { |
| 2626 | 2638 | code.dump(mod.gpa, "var_init", &gen_scope.base, 0) catch {}; |
| 2627 | 2639 | } |
| ... | ... | @@ -2683,7 +2695,8 @@ fn astgenAndSemaVarDecl( |
| 2683 | 2695 | defer type_scope.instructions.deinit(mod.gpa); |
| 2684 | 2696 | |
| 2685 | 2697 | const var_type = try astgen.typeExpr(mod, &type_scope.base, var_decl.ast.type_node); |
| 2686 | const code = try type_scope.finish(); | |
| 2698 | var code = try type_scope.finish(); | |
| 2699 | defer code.deinit(mod.gpa); | |
| 2687 | 2700 | if (std.builtin.mode == .Debug and mod.comp.verbose_ir) { |
| 2688 | 2701 | code.dump(mod.gpa, "var_type", &type_scope.base, 0) catch {}; |
| 2689 | 2702 | } |
src/Sema.zig+5-10| ... | ... | @@ -137,8 +137,7 @@ pub fn analyzeBody(sema: *Sema, block: *Scope.Block, body: []const zir.Inst.Inde |
| 137 | 137 | .as_node => try sema.zirAsNode(block, zir_inst), |
| 138 | 138 | .@"asm" => try sema.zirAsm(block, zir_inst, false), |
| 139 | 139 | .asm_volatile => try sema.zirAsm(block, zir_inst, true), |
| 140 | .unreachable_safe => try sema.zirUnreachable(block, zir_inst, true), | |
| 141 | .unreachable_unsafe => try sema.zirUnreachable(block, zir_inst, false), | |
| 140 | .@"unreachable" => try sema.zirUnreachable(block, zir_inst), | |
| 142 | 141 | .ret_coerce => try sema.zirRetTok(block, zir_inst, true), |
| 143 | 142 | .ret_tok => try sema.zirRetTok(block, zir_inst, false), |
| 144 | 143 | .ret_node => try sema.zirRetNode(block, zir_inst), |
| ... | ... | @@ -2852,17 +2851,13 @@ fn zirCondbr(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) Inne |
| 2852 | 2851 | return parent_block.addCondBr(src, cond, tzir_then_body, tzir_else_body); |
| 2853 | 2852 | } |
| 2854 | 2853 | |
| 2855 | fn zirUnreachable( | |
| 2856 | sema: *Sema, | |
| 2857 | block: *Scope.Block, | |
| 2858 | inst: zir.Inst.Index, | |
| 2859 | safety_check: bool, | |
| 2860 | ) InnerError!*Inst { | |
| 2854 | fn zirUnreachable(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | |
| 2861 | 2855 | const tracy = trace(@src()); |
| 2862 | 2856 | defer tracy.end(); |
| 2863 | 2857 | |
| 2864 | const src_node = sema.code.instructions.items(.data)[inst].node; | |
| 2865 | const src: LazySrcLoc = .{ .node_offset = src_node }; | |
| 2858 | const inst_data = sema.code.instructions.items(.data)[inst].@"unreachable"; | |
| 2859 | const src = inst_data.src(); | |
| 2860 | const safety_check = inst_data.safety; | |
| 2866 | 2861 | try sema.requireRuntimeBlock(block, src); |
| 2867 | 2862 | // TODO Add compile error for @optimizeFor occurring too late in a scope. |
| 2868 | 2863 | if (safety_check and block.wantSafety()) { |
src/astgen.zig+40-31| ... | ... | @@ -415,10 +415,13 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In |
| 415 | 415 | return callExpr(mod, scope, rl, node, tree.callFull(node)); |
| 416 | 416 | }, |
| 417 | 417 | |
| 418 | .unreachable_literal => { | |
| 419 | const result = @enumToInt(zir.Const.unreachable_value); | |
| 420 | return rvalue(mod, scope, rl, result, node); | |
| 421 | }, | |
| 418 | .unreachable_literal => return gz.add(.{ | |
| 419 | .tag = .@"unreachable", | |
| 420 | .data = .{ .@"unreachable" = .{ | |
| 421 | .safety = true, | |
| 422 | .src_node = gz.zir_code.decl.nodeIndexToRelative(node), | |
| 423 | } }, | |
| 424 | }), | |
| 422 | 425 | .@"return" => return ret(mod, scope, node), |
| 423 | 426 | .field_access => return fieldAccess(mod, scope, rl, node), |
| 424 | 427 | .float_literal => return floatLiteral(mod, scope, rl, node), |
| ... | ... | @@ -3012,10 +3015,11 @@ fn as( |
| 3012 | 3015 | scope: *Scope, |
| 3013 | 3016 | rl: ResultLoc, |
| 3014 | 3017 | builtin_token: ast.TokenIndex, |
| 3015 | src: usize, | |
| 3018 | node: ast.Node.Index, | |
| 3016 | 3019 | lhs: ast.Node.Index, |
| 3017 | 3020 | rhs: ast.Node.Index, |
| 3018 | 3021 | ) InnerError!zir.Inst.Ref { |
| 3022 | if (true) @panic("TODO update for zir-memory-layout"); | |
| 3019 | 3023 | const dest_type = try typeExpr(mod, scope, lhs); |
| 3020 | 3024 | switch (rl) { |
| 3021 | 3025 | .none, .discard, .ref, .ty => { |
| ... | ... | @@ -3090,10 +3094,11 @@ fn bitCast( |
| 3090 | 3094 | scope: *Scope, |
| 3091 | 3095 | rl: ResultLoc, |
| 3092 | 3096 | builtin_token: ast.TokenIndex, |
| 3093 | src: usize, | |
| 3097 | node: ast.Node.Index, | |
| 3094 | 3098 | lhs: ast.Node.Index, |
| 3095 | 3099 | rhs: ast.Node.Index, |
| 3096 | 3100 | ) InnerError!zir.Inst.Ref { |
| 3101 | if (true) @panic("TODO update for zir-memory-layout"); | |
| 3097 | 3102 | const dest_type = try typeExpr(mod, scope, lhs); |
| 3098 | 3103 | switch (rl) { |
| 3099 | 3104 | .none => { |
| ... | ... | @@ -3138,9 +3143,10 @@ fn typeOf( |
| 3138 | 3143 | scope: *Scope, |
| 3139 | 3144 | rl: ResultLoc, |
| 3140 | 3145 | builtin_token: ast.TokenIndex, |
| 3141 | src: usize, | |
| 3146 | node: ast.Node.Index, | |
| 3142 | 3147 | params: []const ast.Node.Index, |
| 3143 | 3148 | ) InnerError!zir.Inst.Ref { |
| 3149 | if (true) @panic("TODO update for zir-memory-layout"); | |
| 3144 | 3150 | if (params.len < 1) { |
| 3145 | 3151 | return mod.failTok(scope, builtin_token, "expected at least 1 argument, found 0", .{}); |
| 3146 | 3152 | } |
| ... | ... | @@ -3158,14 +3164,13 @@ fn builtinCall( |
| 3158 | 3164 | mod: *Module, |
| 3159 | 3165 | scope: *Scope, |
| 3160 | 3166 | rl: ResultLoc, |
| 3161 | call: ast.Node.Index, | |
| 3167 | node: ast.Node.Index, | |
| 3162 | 3168 | params: []const ast.Node.Index, |
| 3163 | 3169 | ) InnerError!zir.Inst.Ref { |
| 3164 | if (true) @panic("TODO update for zir-memory-layout"); | |
| 3165 | 3170 | const tree = scope.tree(); |
| 3166 | 3171 | const main_tokens = tree.nodes.items(.main_token); |
| 3167 | 3172 | |
| 3168 | const builtin_token = main_tokens[call]; | |
| 3173 | const builtin_token = main_tokens[node]; | |
| 3169 | 3174 | const builtin_name = tree.tokenSlice(builtin_token); |
| 3170 | 3175 | |
| 3171 | 3176 | // We handle the different builtins manually because they have different semantics depending |
| ... | ... | @@ -3187,56 +3192,60 @@ fn builtinCall( |
| 3187 | 3192 | } |
| 3188 | 3193 | } |
| 3189 | 3194 | |
| 3195 | const gz = scope.getGenZir(); | |
| 3196 | ||
| 3190 | 3197 | switch (info.tag) { |
| 3191 | 3198 | .ptr_to_int => { |
| 3192 | 3199 | const operand = try expr(mod, scope, .none, params[0]); |
| 3193 | const result = try addZIRUnOp(mod, scope, src, .ptrtoint, operand); | |
| 3194 | return rvalue(mod, scope, rl, result); | |
| 3200 | const result = try gz.addUnNode(.ptrtoint, operand, node); | |
| 3201 | return rvalue(mod, scope, rl, result, node); | |
| 3195 | 3202 | }, |
| 3196 | 3203 | .float_cast => { |
| 3204 | if (true) @panic("TODO update for zir-memory-layout"); | |
| 3197 | 3205 | const dest_type = try typeExpr(mod, scope, params[0]); |
| 3198 | 3206 | const rhs = try expr(mod, scope, .none, params[1]); |
| 3199 | 3207 | const result = try addZIRBinOp(mod, scope, src, .floatcast, dest_type, rhs); |
| 3200 | return rvalue(mod, scope, rl, result); | |
| 3208 | return rvalue(mod, scope, rl, result, node); | |
| 3201 | 3209 | }, |
| 3202 | 3210 | .int_cast => { |
| 3211 | if (true) @panic("TODO update for zir-memory-layout"); | |
| 3203 | 3212 | const dest_type = try typeExpr(mod, scope, params[0]); |
| 3204 | 3213 | const rhs = try expr(mod, scope, .none, params[1]); |
| 3205 | 3214 | const result = try addZIRBinOp(mod, scope, src, .intcast, dest_type, rhs); |
| 3206 | return rvalue(mod, scope, rl, result); | |
| 3215 | return rvalue(mod, scope, rl, result, node); | |
| 3207 | 3216 | }, |
| 3208 | 3217 | .breakpoint => { |
| 3218 | if (true) @panic("TODO update for zir-memory-layout"); | |
| 3209 | 3219 | const result = try addZIRNoOp(mod, scope, src, .breakpoint); |
| 3210 | return rvalue(mod, scope, rl, result); | |
| 3220 | return rvalue(mod, scope, rl, result, node); | |
| 3211 | 3221 | }, |
| 3212 | 3222 | .import => { |
| 3213 | 3223 | const target = try expr(mod, scope, .none, params[0]); |
| 3214 | const result = try addZIRUnOp(mod, scope, src, .import, target); | |
| 3215 | return rvalue(mod, scope, rl, result); | |
| 3224 | const result = try gz.addUnNode(.import, target, node); | |
| 3225 | return rvalue(mod, scope, rl, result, node); | |
| 3216 | 3226 | }, |
| 3217 | 3227 | .compile_error => { |
| 3218 | 3228 | const target = try expr(mod, scope, .none, params[0]); |
| 3219 | const result = try addZIRUnOp(mod, scope, src, .compile_error, target); | |
| 3220 | return rvalue(mod, scope, rl, result); | |
| 3229 | const result = try gz.addUnNode(.compile_error, target, node); | |
| 3230 | return rvalue(mod, scope, rl, result, node); | |
| 3221 | 3231 | }, |
| 3222 | 3232 | .set_eval_branch_quota => { |
| 3223 | const u32_type = try addZIRInstConst(mod, scope, src, .{ | |
| 3224 | .ty = Type.initTag(.type), | |
| 3225 | .val = Value.initTag(.u32_type), | |
| 3226 | }); | |
| 3227 | const quota = try expr(mod, scope, .{ .ty = u32_type }, params[0]); | |
| 3228 | const result = try addZIRUnOp(mod, scope, src, .set_eval_branch_quota, quota); | |
| 3229 | return rvalue(mod, scope, rl, result); | |
| 3233 | const u32_rl: ResultLoc = .{ .ty = @enumToInt(zir.Const.u32_type) }; | |
| 3234 | const quota = try expr(mod, scope, u32_rl, params[0]); | |
| 3235 | const result = try gz.addUnNode(.set_eval_branch_quota, quota, node); | |
| 3236 | return rvalue(mod, scope, rl, result, node); | |
| 3230 | 3237 | }, |
| 3231 | 3238 | .compile_log => { |
| 3239 | if (true) @panic("TODO update for zir-memory-layout"); | |
| 3232 | 3240 | const arena = scope.arena(); |
| 3233 | 3241 | var targets = try arena.alloc(zir.Inst.Ref, params.len); |
| 3234 | 3242 | for (params) |param, param_i| |
| 3235 | 3243 | targets[param_i] = try expr(mod, scope, .none, param); |
| 3236 | 3244 | const result = try addZIRInst(mod, scope, src, zir.Inst.CompileLog, .{ .to_log = targets }, .{}); |
| 3237 | return rvalue(mod, scope, rl, result); | |
| 3245 | return rvalue(mod, scope, rl, result, node); | |
| 3238 | 3246 | }, |
| 3239 | 3247 | .field => { |
| 3248 | if (true) @panic("TODO update for zir-memory-layout"); | |
| 3240 | 3249 | const string_type = try addZIRInstConst(mod, scope, src, .{ |
| 3241 | 3250 | .ty = Type.initTag(.type), |
| 3242 | 3251 | .val = Value.initTag(.const_slice_u8_type), |
| ... | ... | @@ -3252,11 +3261,11 @@ fn builtinCall( |
| 3252 | 3261 | return rvalue(mod, scope, rl, try addZirInstTag(mod, scope, src, .field_val_named, .{ |
| 3253 | 3262 | .object = try expr(mod, scope, .none, params[0]), |
| 3254 | 3263 | .field_name = try comptimeExpr(mod, scope, string_rl, params[1]), |
| 3255 | })); | |
| 3264 | }), node); | |
| 3256 | 3265 | }, |
| 3257 | .as => return as(mod, scope, rl, builtin_token, src, params[0], params[1]), | |
| 3258 | .bit_cast => return bitCast(mod, scope, rl, builtin_token, src, params[0], params[1]), | |
| 3259 | .TypeOf => return typeOf(mod, scope, rl, builtin_token, src, params), | |
| 3266 | .as => return as(mod, scope, rl, builtin_token, node, params[0], params[1]), | |
| 3267 | .bit_cast => return bitCast(mod, scope, rl, builtin_token, node, params[0], params[1]), | |
| 3268 | .TypeOf => return typeOf(mod, scope, rl, builtin_token, node, params), | |
| 3260 | 3269 | |
| 3261 | 3270 | .add_with_overflow, |
| 3262 | 3271 | .align_cast, |
src/main.zig+13-20| ... | ... | @@ -1750,15 +1750,12 @@ fn buildOutputType( |
| 1750 | 1750 | } |
| 1751 | 1751 | |
| 1752 | 1752 | const self_exe_path = try fs.selfExePathAlloc(arena); |
| 1753 | var zig_lib_directory: Compilation.Directory = if (override_lib_dir) |lib_dir| | |
| 1754 | .{ | |
| 1755 | .path = lib_dir, | |
| 1756 | .handle = try fs.cwd().openDir(lib_dir, .{}), | |
| 1757 | } | |
| 1758 | else | |
| 1759 | introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | |
| 1760 | fatal("unable to find zig installation directory: {s}", .{@errorName(err)}); | |
| 1761 | }; | |
| 1753 | var zig_lib_directory: Compilation.Directory = if (override_lib_dir) |lib_dir| .{ | |
| 1754 | .path = lib_dir, | |
| 1755 | .handle = try fs.cwd().openDir(lib_dir, .{}), | |
| 1756 | } else introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | |
| 1757 | fatal("unable to find zig installation directory: {s}", .{@errorName(err)}); | |
| 1758 | }; | |
| 1762 | 1759 | defer zig_lib_directory.handle.close(); |
| 1763 | 1760 | |
| 1764 | 1761 | var thread_pool: ThreadPool = undefined; |
| ... | ... | @@ -2461,15 +2458,12 @@ pub fn cmdBuild(gpa: *Allocator, arena: *Allocator, args: []const []const u8) !v |
| 2461 | 2458 | } |
| 2462 | 2459 | } |
| 2463 | 2460 | |
| 2464 | var zig_lib_directory: Compilation.Directory = if (override_lib_dir) |lib_dir| | |
| 2465 | .{ | |
| 2466 | .path = lib_dir, | |
| 2467 | .handle = try fs.cwd().openDir(lib_dir, .{}), | |
| 2468 | } | |
| 2469 | else | |
| 2470 | introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | |
| 2471 | fatal("unable to find zig installation directory: {s}", .{@errorName(err)}); | |
| 2472 | }; | |
| 2461 | var zig_lib_directory: Compilation.Directory = if (override_lib_dir) |lib_dir| .{ | |
| 2462 | .path = lib_dir, | |
| 2463 | .handle = try fs.cwd().openDir(lib_dir, .{}), | |
| 2464 | } else introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | |
| 2465 | fatal("unable to find zig installation directory: {s}", .{@errorName(err)}); | |
| 2466 | }; | |
| 2473 | 2467 | defer zig_lib_directory.handle.close(); |
| 2474 | 2468 | |
| 2475 | 2469 | const std_special = "std" ++ fs.path.sep_str ++ "special"; |
| ... | ... | @@ -3281,8 +3275,7 @@ pub const ClangArgIterator = struct { |
| 3281 | 3275 | self.zig_equivalent = clang_arg.zig_equivalent; |
| 3282 | 3276 | break :find_clang_arg; |
| 3283 | 3277 | }, |
| 3284 | } | |
| 3285 | else { | |
| 3278 | } else { | |
| 3286 | 3279 | fatal("Unknown Clang option: '{s}'", .{arg}); |
| 3287 | 3280 | } |
| 3288 | 3281 | } |
src/zir.zig+33-13| ... | ... | @@ -67,6 +67,13 @@ pub const Code = struct { |
| 67 | 67 | return code.string_bytes[index..end :0]; |
| 68 | 68 | } |
| 69 | 69 | |
| 70 | pub fn deinit(code: *Code, gpa: *Allocator) void { | |
| 71 | code.instructions.deinit(gpa); | |
| 72 | gpa.free(code.string_bytes); | |
| 73 | gpa.free(code.extra); | |
| 74 | code.* = undefined; | |
| 75 | } | |
| 76 | ||
| 70 | 77 | /// For debugging purposes, like dumpFn but for unanalyzed zir blocks |
| 71 | 78 | pub fn dump( |
| 72 | 79 | code: Code, |
| ... | ... | @@ -737,15 +744,9 @@ pub const Inst = struct { |
| 737 | 744 | /// of one or more params. |
| 738 | 745 | /// Uses the `pl_node` field. AST node is the `@TypeOf` call. Payload is `MultiOp`. |
| 739 | 746 | typeof_peer, |
| 740 | /// Asserts control-flow will not reach this instruction. Not safety checked - the compiler | |
| 741 | /// will assume the correctness of this instruction. | |
| 742 | /// Uses the `node` union field. | |
| 743 | unreachable_unsafe, | |
| 744 | /// Asserts control-flow will not reach this instruction. In safety-checked modes, | |
| 745 | /// this will generate a call to the panic function unless it can be proven unreachable | |
| 746 | /// by the compiler. | |
| 747 | /// Uses the `node` union field. | |
| 748 | unreachable_safe, | |
| 747 | /// Asserts control-flow will not reach this instruction (`unreachable`). | |
| 748 | /// Uses the `unreachable` union field. | |
| 749 | @"unreachable", | |
| 749 | 750 | /// Bitwise XOR. `^` |
| 750 | 751 | xor, |
| 751 | 752 | /// Create an optional type '?T' |
| ... | ... | @@ -989,8 +990,7 @@ pub const Inst = struct { |
| 989 | 990 | .ret_node, |
| 990 | 991 | .ret_tok, |
| 991 | 992 | .ret_coerce, |
| 992 | .unreachable_unsafe, | |
| 993 | .unreachable_safe, | |
| 993 | .@"unreachable", | |
| 994 | 994 | .loop, |
| 995 | 995 | .suspend_block, |
| 996 | 996 | .suspend_block_one, |
| ... | ... | @@ -1131,6 +1131,20 @@ pub const Inst = struct { |
| 1131 | 1131 | callee: Ref, |
| 1132 | 1132 | param_index: u32, |
| 1133 | 1133 | }, |
| 1134 | @"unreachable": struct { | |
| 1135 | /// Offset from Decl AST node index. | |
| 1136 | /// `Tag` determines which kind of AST node this points to. | |
| 1137 | src_node: i32, | |
| 1138 | /// `false`: Not safety checked - the compiler will assume the | |
| 1139 | /// correctness of this instruction. | |
| 1140 | /// `true`: In safety-checked modes, this will generate a call | |
| 1141 | /// to the panic function unless it can be proven unreachable by the compiler. | |
| 1142 | safety: bool, | |
| 1143 | ||
| 1144 | pub fn src(self: @This()) LazySrcLoc { | |
| 1145 | return .{ .node_offset = self.src_node }; | |
| 1146 | } | |
| 1147 | }, | |
| 1134 | 1148 | |
| 1135 | 1149 | // Make sure we don't accidentally add a field to make this union |
| 1136 | 1150 | // bigger than expected. Note that in Debug builds, Zig is allowed |
| ... | ... | @@ -1408,8 +1422,6 @@ const Writer = struct { |
| 1408 | 1422 | .dbg_stmt_node, |
| 1409 | 1423 | .ret_ptr, |
| 1410 | 1424 | .ret_type, |
| 1411 | .unreachable_unsafe, | |
| 1412 | .unreachable_safe, | |
| 1413 | 1425 | => try self.writeNode(stream, inst), |
| 1414 | 1426 | |
| 1415 | 1427 | .decl_ref, |
| ... | ... | @@ -1424,6 +1436,7 @@ const Writer = struct { |
| 1424 | 1436 | .fn_type_cc => try self.writeFnTypeCc(stream, inst, false), |
| 1425 | 1437 | .fn_type_var_args => try self.writeFnType(stream, inst, true), |
| 1426 | 1438 | .fn_type_cc_var_args => try self.writeFnTypeCc(stream, inst, true), |
| 1439 | .@"unreachable" => try self.writeUnreachable(stream, inst), | |
| 1427 | 1440 | |
| 1428 | 1441 | .enum_literal_small => try self.writeSmallStr(stream, inst), |
| 1429 | 1442 | |
| ... | ... | @@ -1612,6 +1625,13 @@ const Writer = struct { |
| 1612 | 1625 | return self.writeFnTypeCommon(stream, param_types, inst_data.return_type, var_args, cc); |
| 1613 | 1626 | } |
| 1614 | 1627 | |
| 1628 | fn writeUnreachable(self: *Writer, stream: anytype, inst: Inst.Index) !void { | |
| 1629 | const inst_data = self.code.instructions.items(.data)[inst].@"unreachable"; | |
| 1630 | const safety_str = if (inst_data.safety) "safe" else "unsafe"; | |
| 1631 | try stream.print("{s}) ", .{safety_str}); | |
| 1632 | try self.writeSrc(stream, inst_data.src()); | |
| 1633 | } | |
| 1634 | ||
| 1615 | 1635 | fn writeFnTypeCommon( |
| 1616 | 1636 | self: *Writer, |
| 1617 | 1637 | stream: anytype, |