mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 13:30:45 +00:00
Merge pull request #11228 from Vexu/panic
enable default panic handler for stage2 LLVM
This commit is contained in:
commit
69e6d455ce
@ -753,7 +753,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn
|
||||
@setCold(true);
|
||||
// Until self-hosted catches up with stage1 language features, we have a simpler
|
||||
// default panic function:
|
||||
if (builtin.zig_backend != .stage1) {
|
||||
if (builtin.zig_backend != .stage1 and builtin.zig_backend != .stage2_llvm) {
|
||||
while (true) {
|
||||
@breakpoint();
|
||||
}
|
||||
|
||||
@ -624,8 +624,7 @@ pub const pthread_attr_t = extern struct {
|
||||
__opaque: [56]u8,
|
||||
};
|
||||
|
||||
const pthread_t = std.c.pthread_t;
|
||||
pub extern "c" fn pthread_threadid_np(thread: ?pthread_t, thread_id: *u64) c_int;
|
||||
pub extern "c" fn pthread_threadid_np(thread: ?std.c.pthread_t, thread_id: *u64) c_int;
|
||||
pub extern "c" fn pthread_setname_np(name: [*:0]const u8) E;
|
||||
pub extern "c" fn pthread_getname_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) E;
|
||||
|
||||
@ -921,12 +920,17 @@ pub const siginfo_t = extern struct {
|
||||
|
||||
/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
|
||||
pub const Sigaction = extern struct {
|
||||
pub const handler_fn = fn (c_int) callconv(.C) void;
|
||||
pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void;
|
||||
pub usingnamespace if (builtin.zig_backend == .stage1) struct {
|
||||
pub const handler_fn = fn (c_int) callconv(.C) void;
|
||||
pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void;
|
||||
} else struct {
|
||||
pub const handler_fn = *const fn (c_int) callconv(.C) void;
|
||||
pub const sigaction_fn = *const fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void;
|
||||
};
|
||||
|
||||
handler: extern union {
|
||||
handler: ?handler_fn,
|
||||
sigaction: ?sigaction_fn,
|
||||
handler: ?Sigaction.handler_fn,
|
||||
sigaction: ?Sigaction.sigaction_fn,
|
||||
},
|
||||
mask: sigset_t,
|
||||
flags: c_uint,
|
||||
|
||||
@ -1541,7 +1541,6 @@ pub const ModuleDebugInfo = switch (native_os) {
|
||||
.symbol_name = o_file_di.getSymbolName(relocated_address_o) orelse "???",
|
||||
.compile_unit_name = compile_unit.die.getAttrString(o_file_di, DW.AT.name) catch |err| switch (err) {
|
||||
error.MissingDebugInfo, error.InvalidDebugInfo => "???",
|
||||
else => return err,
|
||||
},
|
||||
.line_info = o_file_di.getLineNumberInfo(compile_unit.*, relocated_address_o + addr_off) catch |err| switch (err) {
|
||||
error.MissingDebugInfo, error.InvalidDebugInfo => null,
|
||||
|
||||
@ -341,15 +341,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
|
||||
const slot_index = @intCast(SlotIndex, used_bits_byte * 8 + bit_index);
|
||||
const stack_trace = bucketStackTrace(bucket, size_class, slot_index, .alloc);
|
||||
const addr = bucket.page + slot_index * size_class;
|
||||
if (builtin.zig_backend == .stage1) {
|
||||
log.err("memory address 0x{x} leaked: {s}", .{
|
||||
@ptrToInt(addr), stack_trace,
|
||||
});
|
||||
} else { // TODO
|
||||
log.err("memory address 0x{x} leaked", .{
|
||||
@ptrToInt(addr),
|
||||
});
|
||||
}
|
||||
log.err("memory address 0x{x} leaked: {s}", .{
|
||||
@ptrToInt(addr), stack_trace,
|
||||
});
|
||||
leaks = true;
|
||||
}
|
||||
if (bit_index == math.maxInt(u3))
|
||||
@ -379,15 +373,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
|
||||
while (it.next()) |large_alloc| {
|
||||
if (config.retain_metadata and large_alloc.freed) continue;
|
||||
const stack_trace = large_alloc.getStackTrace(.alloc);
|
||||
if (builtin.zig_backend == .stage1) {
|
||||
log.err("memory address 0x{x} leaked: {s}", .{
|
||||
@ptrToInt(large_alloc.bytes.ptr), stack_trace,
|
||||
});
|
||||
} else { // TODO
|
||||
log.err("memory address 0x{x} leaked", .{
|
||||
@ptrToInt(large_alloc.bytes.ptr),
|
||||
});
|
||||
}
|
||||
log.err("memory address 0x{x} leaked: {s}", .{
|
||||
@ptrToInt(large_alloc.bytes.ptr), stack_trace,
|
||||
});
|
||||
leaks = true;
|
||||
}
|
||||
return leaks;
|
||||
|
||||
@ -624,7 +624,9 @@ pub const segment_command_64 = extern struct {
|
||||
cmd: LC = .SEGMENT_64,
|
||||
|
||||
/// includes sizeof section_64 structs
|
||||
cmdsize: u32 = @sizeOf(segment_command_64),
|
||||
cmdsize: u32,
|
||||
// TODO lazy values in stage2
|
||||
// cmdsize: u32 = @sizeOf(segment_command_64),
|
||||
|
||||
/// segment name
|
||||
segname: [16]u8,
|
||||
|
||||
@ -1080,12 +1080,19 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact
|
||||
const mask_size = @sizeOf(@TypeOf(ksa.mask));
|
||||
|
||||
if (act) |new| {
|
||||
const restorer_fn = if ((new.flags & SA.SIGINFO) != 0) restore_rt else restore;
|
||||
const restore_rt_ptr = if (builtin.zig_backend == .stage1) restore_rt else &syscall_bits.restore_rt;
|
||||
// TODO https://github.com/ziglang/zig/issues/11227
|
||||
const restore_ptr = if (builtin.zig_backend == .stage1) restore else switch (native_arch) {
|
||||
.arm, .thumb, .mips, .mipsel, .i386 => &syscall_bits.restore,
|
||||
.x86_64, .aarch64, .riscv64, .sparcv9, .powerpc, .powerpc64, .powerpc64le => &syscall_bits.restore_rt,
|
||||
else => unreachable,
|
||||
};
|
||||
const restorer_fn = if ((new.flags & SA.SIGINFO) != 0) restore_rt_ptr else restore_ptr;
|
||||
ksa = k_sigaction{
|
||||
.handler = new.handler.handler,
|
||||
.flags = new.flags | SA.RESTORER,
|
||||
.mask = undefined,
|
||||
.restorer = @ptrCast(fn () callconv(.C) void, restorer_fn),
|
||||
.restorer = @ptrCast(k_sigaction_funcs.restorer, restorer_fn),
|
||||
};
|
||||
@memcpy(@ptrCast([*]u8, &ksa.mask), @ptrCast([*]const u8, &new.mask), mask_size);
|
||||
}
|
||||
@ -3047,39 +3054,55 @@ pub const sigset_t = [1024 / 32]u32;
|
||||
pub const all_mask: sigset_t = [_]u32{0xffffffff} ** sigset_t.len;
|
||||
pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffffffff} ** 30;
|
||||
|
||||
const k_sigaction_funcs = if (builtin.zig_backend == .stage1) struct {
|
||||
const handler = ?fn (c_int) callconv(.C) void;
|
||||
const restorer = fn () callconv(.C) void;
|
||||
} else struct {
|
||||
const handler = ?*const fn (c_int) callconv(.C) void;
|
||||
const restorer = *const fn () callconv(.C) void;
|
||||
};
|
||||
|
||||
pub const k_sigaction = switch (native_arch) {
|
||||
.mips, .mipsel => extern struct {
|
||||
flags: c_uint,
|
||||
handler: ?fn (c_int) callconv(.C) void,
|
||||
handler: k_sigaction_funcs.handler,
|
||||
mask: [4]c_ulong,
|
||||
restorer: fn () callconv(.C) void,
|
||||
restorer: k_sigaction_funcs.restorer,
|
||||
},
|
||||
.mips64, .mips64el => extern struct {
|
||||
flags: c_uint,
|
||||
handler: ?fn (c_int) callconv(.C) void,
|
||||
handler: k_sigaction_funcs.handler,
|
||||
mask: [2]c_ulong,
|
||||
restorer: fn () callconv(.C) void,
|
||||
restorer: k_sigaction_funcs.restorer,
|
||||
},
|
||||
else => extern struct {
|
||||
handler: ?fn (c_int) callconv(.C) void,
|
||||
handler: k_sigaction_funcs.handler,
|
||||
flags: c_ulong,
|
||||
restorer: fn () callconv(.C) void,
|
||||
restorer: k_sigaction_funcs.restorer,
|
||||
mask: [2]c_uint,
|
||||
},
|
||||
};
|
||||
|
||||
/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
|
||||
pub const Sigaction = extern struct {
|
||||
pub const handler_fn = fn (c_int) callconv(.C) void;
|
||||
pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void;
|
||||
pub usingnamespace if (builtin.zig_backend == .stage1) struct {
|
||||
pub const handler_fn = fn (c_int) callconv(.C) void;
|
||||
pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void;
|
||||
} else struct {
|
||||
pub const handler_fn = *const fn (c_int) callconv(.C) void;
|
||||
pub const sigaction_fn = *const fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void;
|
||||
};
|
||||
|
||||
handler: extern union {
|
||||
handler: ?handler_fn,
|
||||
sigaction: ?sigaction_fn,
|
||||
handler: ?Sigaction.handler_fn,
|
||||
sigaction: ?Sigaction.sigaction_fn,
|
||||
},
|
||||
mask: sigset_t,
|
||||
flags: c_uint,
|
||||
restorer: ?fn () callconv(.C) void = null,
|
||||
restorer: ?if (builtin.zig_backend == .stage1)
|
||||
fn () callconv(.C) void
|
||||
else
|
||||
*const fn () callconv(.C) void = null,
|
||||
};
|
||||
|
||||
pub const empty_sigset = [_]u32{0} ** @typeInfo(sigset_t).Array.len;
|
||||
|
||||
177
src/Sema.zig
177
src/Sema.zig
@ -131,6 +131,9 @@ pub const Block = struct {
|
||||
|
||||
c_import_buf: ?*std.ArrayList(u8) = null,
|
||||
|
||||
/// type of `err` in `else => |err|`
|
||||
switch_else_err_ty: ?Type = null,
|
||||
|
||||
const Param = struct {
|
||||
/// `noreturn` means `anytype`.
|
||||
ty: Type,
|
||||
@ -189,6 +192,7 @@ pub const Block = struct {
|
||||
.runtime_index = parent.runtime_index,
|
||||
.want_safety = parent.want_safety,
|
||||
.c_import_buf = parent.c_import_buf,
|
||||
.switch_else_err_ty = parent.switch_else_err_ty,
|
||||
};
|
||||
}
|
||||
|
||||
@ -3930,6 +3934,23 @@ fn analyzeBlockBody(
|
||||
// to emit a jump instruction to after the block when it encounters the break.
|
||||
try parent_block.instructions.append(gpa, merges.block_inst);
|
||||
const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .none);
|
||||
|
||||
const type_src = src; // TODO: better source location
|
||||
const valid_rt = try sema.validateRunTimeType(child_block, type_src, resolved_ty, false);
|
||||
if (!valid_rt) {
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(child_block, type_src, "value with comptime only type '{}' depends on runtime control flow", .{resolved_ty});
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
|
||||
const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;
|
||||
try sema.errNote(child_block, runtime_src, msg, "runtime control flow here", .{});
|
||||
|
||||
try sema.explainWhyTypeIsComptime(child_block, type_src, msg, type_src.toSrcLoc(child_block.src_decl), resolved_ty);
|
||||
|
||||
break :msg msg;
|
||||
};
|
||||
return sema.failWithOwnedErrorMsg(child_block, msg);
|
||||
}
|
||||
const ty_inst = try sema.addType(resolved_ty);
|
||||
try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len +
|
||||
child_block.instructions.items.len);
|
||||
@ -4191,6 +4212,11 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
const br_ref = try start_block.addBr(label.merges.block_inst, operand);
|
||||
try label.merges.results.append(sema.gpa, operand);
|
||||
try label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?);
|
||||
block.runtime_index += 1;
|
||||
if (block.runtime_cond == null and block.runtime_loop == null) {
|
||||
block.runtime_cond = start_block.runtime_cond orelse start_block.runtime_loop;
|
||||
block.runtime_loop = start_block.runtime_loop;
|
||||
}
|
||||
return inst;
|
||||
}
|
||||
}
|
||||
@ -6692,12 +6718,6 @@ fn zirSwitchCapture(
|
||||
|
||||
if (capture_info.prong_index == std.math.maxInt(@TypeOf(capture_info.prong_index))) {
|
||||
// It is the else/`_` prong.
|
||||
switch (operand_ty.zigTypeTag()) {
|
||||
.ErrorSet => {
|
||||
return sema.fail(block, operand_src, "TODO implement Sema for zirSwitchCaptureElse for error sets", .{});
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
if (is_ref) {
|
||||
assert(operand_is_ref);
|
||||
return operand_ptr;
|
||||
@ -6708,7 +6728,10 @@ fn zirSwitchCapture(
|
||||
else
|
||||
operand_ptr;
|
||||
|
||||
return operand;
|
||||
switch (operand_ty.zigTypeTag()) {
|
||||
.ErrorSet => return sema.bitCast(block, block.switch_else_err_ty.?, operand, operand_src),
|
||||
else => return operand,
|
||||
}
|
||||
}
|
||||
|
||||
if (is_multi) {
|
||||
@ -6885,6 +6908,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
|
||||
const operand_ty = sema.typeOf(operand);
|
||||
|
||||
var else_error_ty: ?Type = null;
|
||||
|
||||
// Validate usage of '_' prongs.
|
||||
if (special_prong == .under and !operand_ty.isNonexhaustiveEnum()) {
|
||||
const msg = msg: {
|
||||
@ -7077,6 +7102,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
.{},
|
||||
);
|
||||
}
|
||||
else_error_ty = Type.@"anyerror";
|
||||
} else {
|
||||
var maybe_msg: ?*Module.ErrorMsg = null;
|
||||
errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa);
|
||||
@ -7121,6 +7147,17 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
.{},
|
||||
);
|
||||
}
|
||||
|
||||
const error_names = operand_ty.errorSetNames();
|
||||
var names: Module.ErrorSet.NameMap = .{};
|
||||
try names.ensureUnusedCapacity(sema.arena, error_names.len);
|
||||
for (error_names) |error_name| {
|
||||
if (seen_errors.contains(error_name)) continue;
|
||||
|
||||
names.putAssumeCapacityNoClobber(error_name, {});
|
||||
}
|
||||
|
||||
else_error_ty = try Type.Tag.error_set_merged.create(sema.arena, names);
|
||||
}
|
||||
},
|
||||
.Union => return sema.fail(block, src, "TODO validate switch .Union", .{}),
|
||||
@ -7398,6 +7435,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
.label = &label,
|
||||
.inlining = block.inlining,
|
||||
.is_comptime = block.is_comptime,
|
||||
.switch_else_err_ty = else_error_ty,
|
||||
};
|
||||
const merges = &child_block.label.?.merges;
|
||||
defer child_block.instructions.deinit(gpa);
|
||||
@ -15447,56 +15485,7 @@ fn validateVarType(
|
||||
var_ty: Type,
|
||||
is_extern: bool,
|
||||
) CompileError!void {
|
||||
var ty = var_ty;
|
||||
while (true) switch (ty.zigTypeTag()) {
|
||||
.Bool,
|
||||
.Int,
|
||||
.Float,
|
||||
.ErrorSet,
|
||||
.Enum,
|
||||
.Frame,
|
||||
.AnyFrame,
|
||||
.Void,
|
||||
=> return,
|
||||
|
||||
.BoundFn,
|
||||
.ComptimeFloat,
|
||||
.ComptimeInt,
|
||||
.EnumLiteral,
|
||||
.NoReturn,
|
||||
.Type,
|
||||
.Undefined,
|
||||
.Null,
|
||||
.Fn,
|
||||
=> break,
|
||||
|
||||
.Pointer => {
|
||||
const elem_ty = ty.childType();
|
||||
switch (elem_ty.zigTypeTag()) {
|
||||
.Opaque, .Fn => return,
|
||||
else => ty = elem_ty,
|
||||
}
|
||||
},
|
||||
.Opaque => if (is_extern) return else break,
|
||||
|
||||
.Optional => {
|
||||
var buf: Type.Payload.ElemType = undefined;
|
||||
const child_ty = ty.optionalChild(&buf);
|
||||
return validateVarType(sema, block, src, child_ty, is_extern);
|
||||
},
|
||||
.Array, .Vector => ty = ty.elemType(),
|
||||
|
||||
.ErrorUnion => ty = ty.errorUnionPayload(),
|
||||
|
||||
.Struct, .Union => {
|
||||
const resolved_ty = try sema.resolveTypeFields(block, src, ty);
|
||||
if (try sema.typeRequiresComptime(block, src, resolved_ty)) {
|
||||
break;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
},
|
||||
} else unreachable; // TODO should not need else unreachable
|
||||
if (try sema.validateRunTimeType(block, src, var_ty, is_extern)) return;
|
||||
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty});
|
||||
@ -15509,6 +15498,62 @@ fn validateVarType(
|
||||
return sema.failWithOwnedErrorMsg(block, msg);
|
||||
}
|
||||
|
||||
fn validateRunTimeType(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
src: LazySrcLoc,
|
||||
var_ty: Type,
|
||||
is_extern: bool,
|
||||
) CompileError!bool {
|
||||
var ty = var_ty;
|
||||
while (true) switch (ty.zigTypeTag()) {
|
||||
.Bool,
|
||||
.Int,
|
||||
.Float,
|
||||
.ErrorSet,
|
||||
.Enum,
|
||||
.Frame,
|
||||
.AnyFrame,
|
||||
.Void,
|
||||
=> return true,
|
||||
|
||||
.BoundFn,
|
||||
.ComptimeFloat,
|
||||
.ComptimeInt,
|
||||
.EnumLiteral,
|
||||
.NoReturn,
|
||||
.Type,
|
||||
.Undefined,
|
||||
.Null,
|
||||
.Fn,
|
||||
=> return false,
|
||||
|
||||
.Pointer => {
|
||||
const elem_ty = ty.childType();
|
||||
switch (elem_ty.zigTypeTag()) {
|
||||
.Opaque, .Fn => return true,
|
||||
else => ty = elem_ty,
|
||||
}
|
||||
},
|
||||
.Opaque => return is_extern,
|
||||
|
||||
.Optional => {
|
||||
var buf: Type.Payload.ElemType = undefined;
|
||||
const child_ty = ty.optionalChild(&buf);
|
||||
return validateRunTimeType(sema, block, src, child_ty, is_extern);
|
||||
},
|
||||
.Array, .Vector => ty = ty.elemType(),
|
||||
|
||||
.ErrorUnion => ty = ty.errorUnionPayload(),
|
||||
|
||||
.Struct, .Union => {
|
||||
const resolved_ty = try sema.resolveTypeFields(block, src, ty);
|
||||
const needs_comptime = try sema.typeRequiresComptime(block, src, resolved_ty);
|
||||
return !needs_comptime;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn explainWhyTypeIsComptime(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
@ -18494,8 +18539,8 @@ pub fn bitCastVal(
|
||||
const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target));
|
||||
const buffer = try sema.gpa.alloc(u8, abi_size);
|
||||
defer sema.gpa.free(buffer);
|
||||
val.writeToMemory(old_ty, target, buffer);
|
||||
return Value.readFromMemory(new_ty, target, buffer[buffer_offset..], sema.arena);
|
||||
val.writeToMemory(old_ty, sema.mod, buffer);
|
||||
return Value.readFromMemory(new_ty, sema.mod, buffer[buffer_offset..], sema.arena);
|
||||
}
|
||||
|
||||
fn coerceArrayPtrToSlice(
|
||||
@ -20351,6 +20396,20 @@ pub fn resolveTypeFully(
|
||||
return resolveTypeFully(sema, block, src, ty.optionalChild(&buf));
|
||||
},
|
||||
.ErrorUnion => return resolveTypeFully(sema, block, src, ty.errorUnionPayload()),
|
||||
.Fn => {
|
||||
const info = ty.fnInfo();
|
||||
if (info.is_generic) {
|
||||
// Resolving of generic function types is defeerred to when
|
||||
// the function is instantiated.
|
||||
return;
|
||||
}
|
||||
for (info.param_types) |param_ty| {
|
||||
const param_ty_src = src; // TODO better source location
|
||||
try sema.resolveTypeFully(block, param_ty_src, param_ty);
|
||||
}
|
||||
const return_ty_src = src; // TODO better source location
|
||||
try sema.resolveTypeFully(block, return_ty_src, info.return_type);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
@ -4301,6 +4301,7 @@ fn populateMissingMetadata(self: *MachO) !void {
|
||||
.inner = .{
|
||||
.segname = makeStaticString("__PAGEZERO"),
|
||||
.vmsize = pagezero_vmsize,
|
||||
.cmdsize = @sizeOf(macho.segment_command_64),
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -4326,6 +4327,7 @@ fn populateMissingMetadata(self: *MachO) !void {
|
||||
.filesize = needed_size,
|
||||
.maxprot = macho.PROT.READ | macho.PROT.EXEC,
|
||||
.initprot = macho.PROT.READ | macho.PROT.EXEC,
|
||||
.cmdsize = @sizeOf(macho.segment_command_64),
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -4431,6 +4433,7 @@ fn populateMissingMetadata(self: *MachO) !void {
|
||||
.filesize = needed_size,
|
||||
.maxprot = macho.PROT.READ | macho.PROT.WRITE,
|
||||
.initprot = macho.PROT.READ | macho.PROT.WRITE,
|
||||
.cmdsize = @sizeOf(macho.segment_command_64),
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -4480,6 +4483,7 @@ fn populateMissingMetadata(self: *MachO) !void {
|
||||
.filesize = needed_size,
|
||||
.maxprot = macho.PROT.READ | macho.PROT.WRITE,
|
||||
.initprot = macho.PROT.READ | macho.PROT.WRITE,
|
||||
.cmdsize = @sizeOf(macho.segment_command_64),
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -4589,6 +4593,7 @@ fn populateMissingMetadata(self: *MachO) !void {
|
||||
.fileoff = fileoff,
|
||||
.maxprot = macho.PROT.READ,
|
||||
.initprot = macho.PROT.READ,
|
||||
.cmdsize = @sizeOf(macho.segment_command_64),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -148,6 +148,7 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: Allocator) !void
|
||||
.vmsize = needed_size,
|
||||
.fileoff = fileoff,
|
||||
.filesize = needed_size,
|
||||
.cmdsize = @sizeOf(macho.segment_command_64),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -1042,7 +1042,8 @@ pub const Value = extern union {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn writeToMemory(val: Value, ty: Type, target: Target, buffer: []u8) void {
|
||||
pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) void {
|
||||
const target = mod.getTarget();
|
||||
if (val.isUndef()) {
|
||||
const size = @intCast(usize, ty.abiSize(target));
|
||||
std.mem.set(u8, buffer[0..size], 0xaa);
|
||||
@ -1081,7 +1082,7 @@ pub const Value = extern union {
|
||||
var buf_off: usize = 0;
|
||||
while (elem_i < len) : (elem_i += 1) {
|
||||
const elem_val = val.elemValueBuffer(elem_i, &elem_value_buf);
|
||||
writeToMemory(elem_val, elem_ty, target, buffer[buf_off..]);
|
||||
writeToMemory(elem_val, elem_ty, mod, buffer[buf_off..]);
|
||||
buf_off += elem_size;
|
||||
}
|
||||
},
|
||||
@ -1092,7 +1093,7 @@ pub const Value = extern union {
|
||||
const field_vals = val.castTag(.aggregate).?.data;
|
||||
for (fields) |field, i| {
|
||||
const off = @intCast(usize, ty.structFieldOffset(i, target));
|
||||
writeToMemory(field_vals[i], field.ty, target, buffer[off..]);
|
||||
writeToMemory(field_vals[i], field.ty, mod, buffer[off..]);
|
||||
}
|
||||
},
|
||||
.Packed => {
|
||||
@ -1105,6 +1106,12 @@ pub const Value = extern union {
|
||||
host_int.writeTwosComplement(buffer, bit_size, abi_size, target.cpu.arch.endian());
|
||||
},
|
||||
},
|
||||
.ErrorSet => {
|
||||
// TODO revisit this when we have the concept of the error tag type
|
||||
const Int = u16;
|
||||
const int = mod.global_error_set.get(val.castTag(.@"error").?.data.name).?;
|
||||
std.mem.writeInt(Int, buffer[0..@sizeOf(Int)], @intCast(Int, int), target.cpu.arch.endian());
|
||||
},
|
||||
else => @panic("TODO implement writeToMemory for more types"),
|
||||
}
|
||||
}
|
||||
@ -1153,10 +1160,11 @@ pub const Value = extern union {
|
||||
|
||||
pub fn readFromMemory(
|
||||
ty: Type,
|
||||
target: Target,
|
||||
mod: *Module,
|
||||
buffer: []const u8,
|
||||
arena: Allocator,
|
||||
) Allocator.Error!Value {
|
||||
const target = mod.getTarget();
|
||||
switch (ty.zigTypeTag()) {
|
||||
.Int => {
|
||||
if (buffer.len == 0) return Value.zero;
|
||||
@ -1184,7 +1192,7 @@ pub const Value = extern union {
|
||||
const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen()));
|
||||
var offset: usize = 0;
|
||||
for (elems) |*elem| {
|
||||
elem.* = try readFromMemory(elem_ty, target, buffer[offset..], arena);
|
||||
elem.* = try readFromMemory(elem_ty, mod, buffer[offset..], arena);
|
||||
offset += @intCast(usize, elem_size);
|
||||
}
|
||||
return Tag.aggregate.create(arena, elems);
|
||||
@ -1196,7 +1204,7 @@ pub const Value = extern union {
|
||||
const field_vals = try arena.alloc(Value, fields.len);
|
||||
for (fields) |field, i| {
|
||||
const off = @intCast(usize, ty.structFieldOffset(i, target));
|
||||
field_vals[i] = try readFromMemory(field.ty, target, buffer[off..], arena);
|
||||
field_vals[i] = try readFromMemory(field.ty, mod, buffer[off..], arena);
|
||||
}
|
||||
return Tag.aggregate.create(arena, field_vals);
|
||||
},
|
||||
@ -1212,6 +1220,18 @@ pub const Value = extern union {
|
||||
return intToPackedStruct(ty, target, bigint.toConst(), arena);
|
||||
},
|
||||
},
|
||||
.ErrorSet => {
|
||||
// TODO revisit this when we have the concept of the error tag type
|
||||
const Int = u16;
|
||||
const int = std.mem.readInt(Int, buffer[0..@sizeOf(Int)], target.cpu.arch.endian());
|
||||
|
||||
const payload = try arena.create(Value.Payload.Error);
|
||||
payload.* = .{
|
||||
.base = .{ .tag = .@"error" },
|
||||
.data = .{ .name = mod.error_name_list.items[@intCast(usize, int)] },
|
||||
};
|
||||
return Value.initPayload(&payload.base);
|
||||
},
|
||||
else => @panic("TODO implement readFromMemory for more types"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,6 +331,7 @@ fn copy(src: *const u64, dst: *u64) void {
|
||||
}
|
||||
|
||||
test "call result of if else expression" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest; // stage1 has different function pointers
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
@ -341,7 +342,7 @@ test "call result of if else expression" {
|
||||
try expect(mem.eql(u8, f2(false), "b"));
|
||||
}
|
||||
fn f2(x: bool) []const u8 {
|
||||
return (if (x) fA else fB)();
|
||||
return (if (x) &fA else &fB)();
|
||||
}
|
||||
|
||||
test "memcpy and memset intrinsics" {
|
||||
|
||||
@ -430,7 +430,11 @@ test "switch on integer with else capturing expr" {
|
||||
}
|
||||
|
||||
test "else prong of switch on error set excludes other cases" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user