Skip to content

Commit 1a178d4

Browse files
authored
Merge pull request ziglang#21210 from jacobly0/eh-frame
Dwarf: implement .eh_frame
2 parents 93cb44c + f289b82 commit 1a178d4

27 files changed

+1419
-346
lines changed

ci/x86_64-linux-debug.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ stage3-debug/bin/zig build \
6464

6565
stage3-debug/bin/zig build test docs \
6666
--maxrss 21000000000 \
67-
-Dlldb=$HOME/deps/lldb-zig/Debug-62538077d/bin/lldb \
67+
-Dlldb=$HOME/deps/lldb-zig/Debug-70b8227f1/bin/lldb \
6868
-fqemu \
6969
-fwasmtime \
7070
-Dstatic-llvm \

ci/x86_64-linux-release.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ stage3-release/bin/zig build \
6464

6565
stage3-release/bin/zig build test docs \
6666
--maxrss 21000000000 \
67-
-Dlldb=$HOME/deps/lldb-zig/Release-62538077d/bin/lldb \
67+
-Dlldb=$HOME/deps/lldb-zig/Release-70b8227f1/bin/lldb \
6868
-fqemu \
6969
-fwasmtime \
7070
-Dstatic-llvm \

lib/std/leb128.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ pub const readILEB128 = readIleb128;
125125
pub fn writeIleb128(writer: anytype, arg: anytype) !void {
126126
const Arg = @TypeOf(arg);
127127
const Int = switch (Arg) {
128-
comptime_int => std.math.IntFittingRange(-arg - 1, arg),
128+
comptime_int => std.math.IntFittingRange(-@abs(arg), @abs(arg)),
129129
else => Arg,
130130
};
131131
const Signed = if (@typeInfo(Int).Int.bits < 8) i8 else Int;

lib/std/os/linux/x86_64.zig

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,15 @@ pub fn clone() callconv(.Naked) usize {
114114
\\ movq %%rcx,(%%rsi)
115115
\\ syscall
116116
\\ testq %%rax,%%rax
117-
\\ jnz 1f
117+
\\ jz 1f
118+
\\ retq
119+
\\1: .cfi_undefined %%rip
118120
\\ xorl %%ebp,%%ebp
119121
\\ popq %%rdi
120122
\\ callq *%%r9
121123
\\ movl %%eax,%%edi
122124
\\ movl $60,%%eax // SYS_exit
123125
\\ syscall
124-
\\1: ret
125126
\\
126127
);
127128
}

lib/std/start.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ fn _start() callconv(.Naked) noreturn {
249249
// linker explicitly.
250250
asm volatile (switch (native_arch) {
251251
.x86_64 =>
252+
\\ .cfi_undefined %%rip
252253
\\ xorl %%ebp, %%ebp
253254
\\ movq %%rsp, %%rdi
254255
\\ andq $-16, %%rsp

src/Air.zig

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const Value = @import("Value.zig");
1313
const Type = @import("Type.zig");
1414
const InternPool = @import("InternPool.zig");
1515
const Zcu = @import("Zcu.zig");
16+
const types_resolved = @import("Air/types_resolved.zig");
1617

1718
instructions: std.MultiArrayList(Inst).Slice,
1819
/// The meaning of this data is determined by `Inst.Tag` value.
@@ -1899,4 +1900,6 @@ pub fn unwrapSwitch(air: *const Air, switch_inst: Inst.Index) UnwrappedSwitch {
18991900
};
19001901
}
19011902

1902-
pub const typesFullyResolved = @import("Air/types_resolved.zig").typesFullyResolved;
1903+
pub const typesFullyResolved = types_resolved.typesFullyResolved;
1904+
pub const typeFullyResolved = types_resolved.checkType;
1905+
pub const valFullyResolved = types_resolved.checkVal;

src/Air/types_resolved.zig

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -432,8 +432,10 @@ fn checkRef(ref: Air.Inst.Ref, zcu: *Zcu) bool {
432432
return checkVal(Value.fromInterned(ip_index), zcu);
433433
}
434434

435-
fn checkVal(val: Value, zcu: *Zcu) bool {
436-
if (!checkType(val.typeOf(zcu), zcu)) return false;
435+
pub fn checkVal(val: Value, zcu: *Zcu) bool {
436+
const ty = val.typeOf(zcu);
437+
if (!checkType(ty, zcu)) return false;
438+
if (ty.toIntern() == .type_type and !checkType(val.toType(), zcu)) return false;
437439
// Check for lazy values
438440
switch (zcu.intern_pool.indexToKey(val.toIntern())) {
439441
.int => |int| switch (int.storage) {
@@ -446,9 +448,11 @@ fn checkVal(val: Value, zcu: *Zcu) bool {
446448
}
447449
}
448450

449-
fn checkType(ty: Type, zcu: *Zcu) bool {
451+
pub fn checkType(ty: Type, zcu: *Zcu) bool {
450452
const ip = &zcu.intern_pool;
451-
return switch (ty.zigTypeTag(zcu)) {
453+
return switch (ty.zigTypeTagOrPoison(zcu) catch |err| switch (err) {
454+
error.GenericPoison => return true,
455+
}) {
452456
.Type,
453457
.Void,
454458
.Bool,

src/Value.zig

Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,12 @@ pub fn toBigIntAdvanced(
192192
zcu: *Zcu,
193193
tid: strat.Tid(),
194194
) Zcu.CompileError!BigIntConst {
195+
const ip = &zcu.intern_pool;
195196
return switch (val.toIntern()) {
196197
.bool_false => BigIntMutable.init(&space.limbs, 0).toConst(),
197198
.bool_true => BigIntMutable.init(&space.limbs, 1).toConst(),
198199
.null_value => BigIntMutable.init(&space.limbs, 0).toConst(),
199-
else => switch (zcu.intern_pool.indexToKey(val.toIntern())) {
200+
else => switch (ip.indexToKey(val.toIntern())) {
200201
.int => |int| switch (int.storage) {
201202
.u64, .i64, .big_int => int.storage.toBigInt(space),
202203
.lazy_align, .lazy_size => |ty| {
@@ -214,6 +215,7 @@ pub fn toBigIntAdvanced(
214215
&space.limbs,
215216
(try val.getUnsignedIntInner(strat, zcu, tid)).?,
216217
).toConst(),
218+
.err => |err| BigIntMutable.init(&space.limbs, ip.getErrorValueIfExists(err.name).?).toConst(),
217219
else => unreachable,
218220
},
219221
};
@@ -326,15 +328,11 @@ pub fn toBool(val: Value) bool {
326328
};
327329
}
328330

329-
fn ptrHasIntAddr(val: Value, zcu: *Zcu) bool {
330-
return zcu.intern_pool.getBackingAddrTag(val.toIntern()).? == .int;
331-
}
332-
333331
/// Write a Value's contents to `buffer`.
334332
///
335333
/// Asserts that buffer.len >= ty.abiSize(). The buffer is allowed to extend past
336334
/// the end of the value in memory.
337-
pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) error{
335+
pub fn writeToMemory(val: Value, pt: Zcu.PerThread, buffer: []u8) error{
338336
ReinterpretDeclRef,
339337
IllDefinedMemoryLayout,
340338
Unimplemented,
@@ -343,19 +341,25 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
343341
const zcu = pt.zcu;
344342
const target = zcu.getTarget();
345343
const endian = target.cpu.arch.endian();
344+
const ip = &zcu.intern_pool;
345+
const ty = val.typeOf(zcu);
346346
if (val.isUndef(zcu)) {
347347
const size: usize = @intCast(ty.abiSize(zcu));
348348
@memset(buffer[0..size], 0xaa);
349349
return;
350350
}
351-
const ip = &zcu.intern_pool;
352351
switch (ty.zigTypeTag(zcu)) {
353352
.Void => {},
354353
.Bool => {
355354
buffer[0] = @intFromBool(val.toBool());
356355
},
357-
.Int, .Enum => {
358-
const int_info = ty.intInfo(zcu);
356+
.Int, .Enum, .ErrorSet, .Pointer => |tag| {
357+
const int_ty = if (tag == .Pointer) int_ty: {
358+
if (ty.isSlice(zcu)) return error.IllDefinedMemoryLayout;
359+
if (ip.getBackingAddrTag(val.toIntern()).? != .int) return error.ReinterpretDeclRef;
360+
break :int_ty Type.usize;
361+
} else ty;
362+
const int_info = int_ty.intInfo(zcu);
359363
const bits = int_info.bits;
360364
const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8);
361365

@@ -379,7 +383,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
379383
var buf_off: usize = 0;
380384
while (elem_i < len) : (elem_i += 1) {
381385
const elem_val = try val.elemValue(pt, elem_i);
382-
try elem_val.writeToMemory(elem_ty, pt, buffer[buf_off..]);
386+
try elem_val.writeToMemory(pt, buffer[buf_off..]);
383387
buf_off += elem_size;
384388
}
385389
},
@@ -403,31 +407,14 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
403407
.elems => |elems| elems[field_index],
404408
.repeated_elem => |elem| elem,
405409
});
406-
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
407-
try writeToMemory(field_val, field_ty, pt, buffer[off..]);
410+
try writeToMemory(field_val, pt, buffer[off..]);
408411
},
409412
.@"packed" => {
410413
const byte_count = (@as(usize, @intCast(ty.bitSize(zcu))) + 7) / 8;
411414
return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
412415
},
413416
}
414417
},
415-
.ErrorSet => {
416-
const bits = zcu.errorSetBits();
417-
const byte_count: u16 = @intCast((@as(u17, bits) + 7) / 8);
418-
419-
const name = switch (ip.indexToKey(val.toIntern())) {
420-
.err => |err| err.name,
421-
.error_union => |error_union| error_union.val.err_name,
422-
else => unreachable,
423-
};
424-
var bigint_buffer: BigIntSpace = undefined;
425-
const bigint = BigIntMutable.init(
426-
&bigint_buffer.limbs,
427-
ip.getErrorValueIfExists(name).?,
428-
).toConst();
429-
bigint.writeTwosComplement(buffer[0..byte_count], endian);
430-
},
431418
.Union => switch (ty.containerLayout(zcu)) {
432419
.auto => return error.IllDefinedMemoryLayout, // Sema is supposed to have emitted a compile error already
433420
.@"extern" => {
@@ -437,11 +424,11 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
437424
const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
438425
const field_val = try val.fieldValue(pt, field_index);
439426
const byte_count: usize = @intCast(field_type.abiSize(zcu));
440-
return writeToMemory(field_val, field_type, pt, buffer[0..byte_count]);
427+
return writeToMemory(field_val, pt, buffer[0..byte_count]);
441428
} else {
442429
const backing_ty = try ty.unionBackingType(pt);
443430
const byte_count: usize = @intCast(backing_ty.abiSize(zcu));
444-
return writeToMemory(val.unionValue(zcu), backing_ty, pt, buffer[0..byte_count]);
431+
return writeToMemory(val.unionValue(zcu), pt, buffer[0..byte_count]);
445432
}
446433
},
447434
.@"packed" => {
@@ -450,19 +437,13 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
450437
return writeToPackedMemory(val, ty, pt, buffer[0..byte_count], 0);
451438
},
452439
},
453-
.Pointer => {
454-
if (ty.isSlice(zcu)) return error.IllDefinedMemoryLayout;
455-
if (!val.ptrHasIntAddr(zcu)) return error.ReinterpretDeclRef;
456-
return val.writeToMemory(Type.usize, pt, buffer);
457-
},
458440
.Optional => {
459441
if (!ty.isPtrLikeOptional(zcu)) return error.IllDefinedMemoryLayout;
460-
const child = ty.optionalChild(zcu);
461442
const opt_val = val.optionalValue(zcu);
462443
if (opt_val) |some| {
463-
return some.writeToMemory(child, pt, buffer);
444+
return some.writeToMemory(pt, buffer);
464445
} else {
465-
return writeToMemory(try pt.intValue(Type.usize, 0), Type.usize, pt, buffer);
446+
return writeToMemory(try pt.intValue(Type.usize, 0), pt, buffer);
466447
}
467448
},
468449
else => return error.Unimplemented,
@@ -582,7 +563,7 @@ pub fn writeToPackedMemory(
582563
},
583564
.Pointer => {
584565
assert(!ty.isSlice(zcu)); // No well defined layout.
585-
if (!val.ptrHasIntAddr(zcu)) return error.ReinterpretDeclRef;
566+
if (ip.getBackingAddrTag(val.toIntern()).? != .int) return error.ReinterpretDeclRef;
586567
return val.writeToPackedMemory(Type.usize, pt, buffer, bit_offset);
587568
},
588569
.Optional => {
@@ -3658,14 +3639,15 @@ pub fn mulAddScalar(
36583639

36593640
/// If the value is represented in-memory as a series of bytes that all
36603641
/// have the same value, return that byte value, otherwise null.
3661-
pub fn hasRepeatedByteRepr(val: Value, ty: Type, pt: Zcu.PerThread) !?u8 {
3642+
pub fn hasRepeatedByteRepr(val: Value, pt: Zcu.PerThread) !?u8 {
36623643
const zcu = pt.zcu;
3644+
const ty = val.typeOf(zcu);
36633645
const abi_size = std.math.cast(usize, ty.abiSize(zcu)) orelse return null;
36643646
assert(abi_size >= 1);
36653647
const byte_buffer = try zcu.gpa.alloc(u8, abi_size);
36663648
defer zcu.gpa.free(byte_buffer);
36673649

3668-
writeToMemory(val, ty, pt, byte_buffer) catch |err| switch (err) {
3650+
writeToMemory(val, pt, byte_buffer) catch |err| switch (err) {
36693651
error.OutOfMemory => return error.OutOfMemory,
36703652
error.ReinterpretDeclRef => return null,
36713653
// TODO: The writeToMemory function was originally created for the purpose

src/Zcu/PerThread.zig

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2560,12 +2560,17 @@ pub fn populateTestFunctions(
25602560
pub fn linkerUpdateNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
25612561
const zcu = pt.zcu;
25622562
const comp = zcu.comp;
2563+
const ip = &zcu.intern_pool;
25632564

25642565
const nav = zcu.intern_pool.getNav(nav_index);
2565-
const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(&zcu.intern_pool), 0);
2566+
const codegen_prog_node = zcu.codegen_prog_node.start(nav.fqn.toSlice(ip), 0);
25662567
defer codegen_prog_node.end();
25672568

2568-
if (comp.bin_file) |lf| {
2569+
if (!Air.valFullyResolved(zcu.navValue(nav_index), zcu)) {
2570+
// The value of this nav failed to resolve. This is a transitive failure.
2571+
// TODO: do we need to mark this failure anywhere? I don't think so, since compilation
2572+
// will fail due to the type error anyway.
2573+
} else if (comp.bin_file) |lf| {
25692574
lf.updateNav(pt, nav_index) catch |err| switch (err) {
25702575
error.OutOfMemory => return error.OutOfMemory,
25712576
error.AnalysisFail => {
@@ -2605,7 +2610,11 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) !void
26052610
const codegen_prog_node = zcu.codegen_prog_node.start(Type.fromInterned(ty).containerTypeName(ip).toSlice(ip), 0);
26062611
defer codegen_prog_node.end();
26072612

2608-
if (comp.bin_file) |lf| {
2613+
if (!Air.typeFullyResolved(Type.fromInterned(ty), zcu)) {
2614+
// This type failed to resolve. This is a transitive failure.
2615+
// TODO: do we need to mark this failure anywhere? I don't think so, since compilation
2616+
// will fail due to the type error anyway.
2617+
} else if (comp.bin_file) |lf| {
26092618
lf.updateContainerType(pt, ty) catch |err| switch (err) {
26102619
error.OutOfMemory => return error.OutOfMemory,
26112620
else => |e| log.err("codegen type failed: {s}", .{@errorName(e)}),

src/arch/wasm/CodeGen.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3357,7 +3357,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
33573357
.vector_type => {
33583358
assert(determineSimdStoreStrategy(ty, zcu, func.target.*) == .direct);
33593359
var buf: [16]u8 = undefined;
3360-
val.writeToMemory(ty, pt, &buf) catch unreachable;
3360+
val.writeToMemory(pt, &buf) catch unreachable;
33613361
return func.storeSimdImmd(buf);
33623362
},
33633363
.struct_type => {

0 commit comments

Comments
 (0)