| ... | @@ -272,6 +272,8 @@ pub const Function = struct { | ... | @@ -272,6 +272,8 @@ pub const Function = struct { |
| 272 | /// variable declarations at the top of a function, sorted descending by | 272 | /// variable declarations at the top of a function, sorted descending by |
| 273 | /// type alignment. | 273 | /// type alignment. |
| 274 | allocs: std.AutoArrayHashMapUnmanaged(LocalIndex, void) = .{}, | 274 | allocs: std.AutoArrayHashMapUnmanaged(LocalIndex, void) = .{}, |
| | 275 | /// Needed for memory used by Type objects used as keys in free_locals. |
| | 276 | arena: std.heap.ArenaAllocator, |
| 275 | | 277 | |
| 276 | fn tyHashCtx(f: Function) Type.HashContext32 { | 278 | fn tyHashCtx(f: Function) Type.HashContext32 { |
| 277 | return .{ .mod = f.object.dg.module }; | 279 | return .{ .mod = f.object.dg.module }; |
| ... | @@ -314,7 +316,7 @@ pub const Function = struct { | ... | @@ -314,7 +316,7 @@ pub const Function = struct { |
| 314 | .ty = ty, | 316 | .ty = ty, |
| 315 | .alignment = alignment, | 317 | .alignment = alignment, |
| 316 | }); | 318 | }); |
| 317 | return .{ .local = @intCast(LocalIndex, f.locals.items.len - 1) }; | 319 | return CValue{ .local = @intCast(LocalIndex, f.locals.items.len - 1) }; |
| 318 | } | 320 | } |
| 319 | | 321 | |
| 320 | fn allocLocal(f: *Function, inst: Air.Inst.Index, ty: Type) !CValue { | 322 | fn allocLocal(f: *Function, inst: Air.Inst.Index, ty: Type) !CValue { |
| ... | @@ -420,6 +422,7 @@ pub const Function = struct { | ... | @@ -420,6 +422,7 @@ pub const Function = struct { |
| 420 | } | 422 | } |
| 421 | f.object.dg.typedefs.deinit(); | 423 | f.object.dg.typedefs.deinit(); |
| 422 | f.object.dg.fwd_decl.deinit(); | 424 | f.object.dg.fwd_decl.deinit(); |
| | 425 | f.arena.deinit(); |
| 423 | } | 426 | } |
| 424 | }; | 427 | }; |
| 425 | | 428 | |
| ... | @@ -3228,8 +3231,9 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { | ... | @@ -3228,8 +3231,9 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 3228 | var deref = is_ptr; | 3231 | var deref = is_ptr; |
| 3229 | const operand = try f.resolveInst(un_op); | 3232 | const operand = try f.resolveInst(un_op); |
| 3230 | try reap(f, inst, &.{un_op}); | 3233 | try reap(f, inst, &.{un_op}); |
| 3231 | const ret_val = if (lowersToArray(ret_ty, target)) ret_val: { | 3234 | const is_array = lowersToArray(ret_ty, target); |
| 3232 | const array_local = try f.allocLocal(inst, lowered_ret_ty); | 3235 | const ret_val = if (is_array) ret_val: { |
| | 3236 | const array_local = try f.allocLocal(inst, try lowered_ret_ty.copy(f.arena.allocator())); |
| 3233 | try writer.writeAll("memcpy("); | 3237 | try writer.writeAll("memcpy("); |
| 3234 | try f.writeCValueMember(writer, array_local, .{ .field = 0 }); | 3238 | try f.writeCValueMember(writer, array_local, .{ .field = 0 }); |
| 3235 | try writer.writeAll(", "); | 3239 | try writer.writeAll(", "); |
| ... | @@ -3250,6 +3254,9 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { | ... | @@ -3250,6 +3254,9 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 3250 | else | 3254 | else |
| 3251 | try f.writeCValue(writer, ret_val, .Other); | 3255 | try f.writeCValue(writer, ret_val, .Other); |
| 3252 | try writer.writeAll(";\n"); | 3256 | try writer.writeAll(";\n"); |
| | 3257 | if (is_array) { |
| | 3258 | try freeLocal(f, inst, ret_val.local, 0); |
| | 3259 | } |
| 3253 | } else { | 3260 | } else { |
| 3254 | try reap(f, inst, &.{un_op}); | 3261 | try reap(f, inst, &.{un_op}); |
| 3255 | if (f.object.dg.decl.ty.fnCallingConvention() != .Naked) { | 3262 | if (f.object.dg.decl.ty.fnCallingConvention() != .Naked) { |
| ... | @@ -3884,7 +3891,7 @@ fn airCall( | ... | @@ -3884,7 +3891,7 @@ fn airCall( |
| 3884 | try writer.writeByte(')'); | 3891 | try writer.writeByte(')'); |
| 3885 | break :r .none; | 3892 | break :r .none; |
| 3886 | } else r: { | 3893 | } else r: { |
| 3887 | const local = try f.allocLocal(inst, lowered_ret_ty); | 3894 | const local = try f.allocLocal(inst, try lowered_ret_ty.copy(f.arena.allocator())); |
| 3888 | try f.writeCValue(writer, local, .Other); | 3895 | try f.writeCValue(writer, local, .Other); |
| 3889 | try writer.writeAll(" = "); | 3896 | try writer.writeAll(" = "); |
| 3890 | break :r local; | 3897 | break :r local; |
| ... | @@ -5110,7 +5117,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5110,7 +5117,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5110 | }; | 5117 | }; |
| 5111 | const field_int_ty = Type.initPayload(&field_int_pl.base); | 5118 | const field_int_ty = Type.initPayload(&field_int_pl.base); |
| 5112 | | 5119 | |
| 5113 | const temp_local = try f.allocLocal(inst, field_int_ty); | 5120 | const temp_local = try f.allocLocal(inst, try field_int_ty.copy(f.arena.allocator())); |
| 5114 | try f.writeCValue(writer, temp_local, .Other); | 5121 | try f.writeCValue(writer, temp_local, .Other); |
| 5115 | try writer.writeAll(" = zig_wrap_"); | 5122 | try writer.writeAll(" = zig_wrap_"); |
| 5116 | try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty); | 5123 | try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty); |