Commit 28729efe29
lib/std/math/big/int.zig
@@ -62,6 +62,7 @@ pub const Int = struct {
/// Hint: use `calcLimbLen` to figure out how big an array to allocate for `limbs`.
pub fn initSetFixed(limbs: []Limb, value: var) Int {
+ mem.set(Limb, limbs, 0);
var s = Int.initFixed(limbs);
s.set(value) catch unreachable;
return s;
@@ -126,11 +127,10 @@ pub const Int = struct {
/// sufficient capacity, the exact amount will be allocated. This occurs even if the requested
/// capacity is only greater than the current capacity by one limb.
pub fn ensureCapacity(self: *Int, capacity: usize) !void {
- self.assertWritable();
if (capacity <= self.limbs.len) {
return;
}
-
+ self.assertWritable();
self.limbs = try self.allocator.?.realloc(self.limbs, capacity);
}
src-self-hosted/ir/text.zig
@@ -26,6 +26,7 @@ pub const Inst = struct {
as,
@"asm",
@"unreachable",
+ @"return",
@"fn",
@"export",
primitive,
@@ -50,6 +51,7 @@ pub const Inst = struct {
.as => As,
.@"asm" => Asm,
.@"unreachable" => Unreachable,
+ .@"return" => Return,
.@"fn" => Fn,
.@"export" => Export,
.primitive => Primitive,
@@ -159,6 +161,14 @@ pub const Inst = struct {
kw_args: struct {},
};
+ pub const Return = struct {
+ pub const base_tag = Tag.@"return";
+ base: Inst,
+
+ positionals: struct {},
+ kw_args: struct {},
+ };
+
pub const Fn = struct {
pub const base_tag = Tag.@"fn";
base: Inst,
@@ -417,6 +427,7 @@ pub const Module = struct {
.as => return self.writeInstToStreamGeneric(stream, .as, decl, inst_table),
.@"asm" => return self.writeInstToStreamGeneric(stream, .@"asm", decl, inst_table),
.@"unreachable" => return self.writeInstToStreamGeneric(stream, .@"unreachable", decl, inst_table),
+ .@"return" => return self.writeInstToStreamGeneric(stream, .@"return", decl, inst_table),
.@"fn" => return self.writeInstToStreamGeneric(stream, .@"fn", decl, inst_table),
.@"export" => return self.writeInstToStreamGeneric(stream, .@"export", decl, inst_table),
.primitive => return self.writeInstToStreamGeneric(stream, .primitive, decl, inst_table),
@@ -1000,14 +1011,15 @@ const EmitZIR = struct {
const fn_type = try self.emitType(src, module_fn.fn_type);
+ const arena_instrs = try self.arena.allocator.alloc(*Inst, instructions.items.len);
+ mem.copy(*Inst, arena_instrs, instructions.items);
+
const fn_inst = try self.arena.allocator.create(Inst.Fn);
fn_inst.* = .{
.base = .{ .src = src, .tag = Inst.Fn.base_tag },
.positionals = .{
.fn_type = fn_type,
- .body = .{
- .instructions = instructions.toOwnedSlice(),
- },
+ .body = .{ .instructions = arena_instrs },
},
.kw_args = .{},
};
@@ -1035,6 +1047,15 @@ const EmitZIR = struct {
};
break :blk &unreach_inst.base;
},
+ .ret => blk: {
+ const ret_inst = try self.arena.allocator.create(Inst.Return);
+ ret_inst.* = .{
+ .base = .{ .src = inst.src, .tag = Inst.Return.base_tag },
+ .positionals = .{},
+ .kw_args = .{},
+ };
+ break :blk &ret_inst.base;
+ },
.constant => unreachable, // excluded from function bodies
.assembly => blk: {
const old_inst = inst.cast(ir.Inst.Assembly).?;
src-self-hosted/ir.zig
@@ -22,6 +22,7 @@ pub const Inst = struct {
pub const Tag = enum {
unreach,
+ ret,
constant,
assembly,
ptrtoint,
@@ -58,6 +59,12 @@ pub const Inst = struct {
args: void,
};
+ pub const Ret = struct {
+ pub const base_tag = Tag.ret;
+ base: Inst,
+ args: void,
+ };
+
pub const Constant = struct {
pub const base_tag = Tag.constant;
base: Inst,
@@ -491,6 +498,7 @@ const Analyze = struct {
.as => return self.analyzeInstAs(block, old_inst.cast(text.Inst.As).?),
.@"asm" => return self.analyzeInstAsm(block, old_inst.cast(text.Inst.Asm).?),
.@"unreachable" => return self.analyzeInstUnreachable(block, old_inst.cast(text.Inst.Unreachable).?),
+ .@"return" => return self.analyzeInstRet(block, old_inst.cast(text.Inst.Return).?),
.@"fn" => return self.analyzeInstFn(block, old_inst.cast(text.Inst.Fn).?),
.@"export" => {
try self.analyzeExport(block, old_inst.cast(text.Inst.Export).?);
@@ -556,6 +564,13 @@ const Analyze = struct {
return self.constType(fntype.base.src, Type.initTag(.fn_naked_noreturn_no_args));
}
+ if (return_type.zigTypeTag() == .Void and
+ fntype.positionals.param_types.len == 0 and
+ fntype.kw_args.cc == .C)
+ {
+ return self.constType(fntype.base.src, Type.initTag(.fn_ccc_void_no_args));
+ }
+
return self.fail(fntype.base.src, "TODO implement fntype instruction more", .{});
}
@@ -886,6 +901,11 @@ const Analyze = struct {
return self.addNewInstArgs(b, unreach.base.src, Type.initTag(.noreturn), Inst.Unreach, {});
}
+ fn analyzeInstRet(self: *Analyze, block: ?*Block, inst: *text.Inst.Return) InnerError!*Inst {
+ const b = try self.requireRuntimeBlock(block, inst.base.src);
+ return self.addNewInstArgs(b, inst.base.src, Type.initTag(.noreturn), Inst.Ret, {});
+ }
+
fn analyzeBody(self: *Analyze, block: ?*Block, body: text.Module.Body) !void {
for (body.instructions) |src_inst| {
const new_inst = self.analyzeInst(block, src_inst) catch |err| {
@@ -1199,11 +1219,13 @@ pub fn main() anyerror!void {
const allocator = if (std.builtin.link_libc) std.heap.c_allocator else &arena.allocator;
const args = try std.process.argsAlloc(allocator);
+ defer std.process.argsFree(allocator, args);
const src_path = args[1];
const debug_error_trace = true;
const source = try std.fs.cwd().readFileAllocOptions(allocator, src_path, std.math.maxInt(u32), 1, 0);
+ defer allocator.free(source);
var zir_module = try text.parse(allocator, source);
defer zir_module.deinit(allocator);
src-self-hosted/type.zig
@@ -53,6 +53,7 @@ pub const Type = extern union {
.noreturn => return .NoReturn,
.fn_naked_noreturn_no_args => return .Fn,
+ .fn_ccc_void_no_args => return .Fn,
.array, .array_u8_sentinel_0 => return .Array,
.single_const_pointer => return .Pointer,
@@ -184,6 +185,7 @@ pub const Type = extern union {
.const_slice_u8 => return out_stream.writeAll("[]const u8"),
.fn_naked_noreturn_no_args => return out_stream.writeAll("fn() callconv(.Naked) noreturn"),
+ .fn_ccc_void_no_args => return out_stream.writeAll("fn() callconv(.C) void"),
.single_const_pointer_to_comptime_int => return out_stream.writeAll("*const comptime_int"),
.array_u8_sentinel_0 => {
@@ -243,6 +245,7 @@ pub const Type = extern union {
.comptime_float => return Value.initTag(.comptime_float_type),
.noreturn => return Value.initTag(.noreturn_type),
.fn_naked_noreturn_no_args => return Value.initTag(.fn_naked_noreturn_no_args_type),
+ .fn_ccc_void_no_args => return Value.initTag(.fn_ccc_void_no_args_type),
.single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),
.const_slice_u8 => return Value.initTag(.const_slice_u8_type),
else => {
@@ -284,6 +287,7 @@ pub const Type = extern union {
.array_u8_sentinel_0,
.const_slice_u8,
.fn_naked_noreturn_no_args,
+ .fn_ccc_void_no_args,
.int_unsigned,
.int_signed,
=> false,
@@ -326,6 +330,7 @@ pub const Type = extern union {
.single_const_pointer,
.single_const_pointer_to_comptime_int,
.fn_naked_noreturn_no_args,
+ .fn_ccc_void_no_args,
.int_unsigned,
.int_signed,
=> false,
@@ -365,6 +370,7 @@ pub const Type = extern union {
.array,
.array_u8_sentinel_0,
.fn_naked_noreturn_no_args,
+ .fn_ccc_void_no_args,
.int_unsigned,
.int_signed,
=> unreachable,
@@ -405,6 +411,7 @@ pub const Type = extern union {
.comptime_float,
.noreturn,
.fn_naked_noreturn_no_args,
+ .fn_ccc_void_no_args,
.int_unsigned,
.int_signed,
=> unreachable,
@@ -445,6 +452,7 @@ pub const Type = extern union {
.comptime_float,
.noreturn,
.fn_naked_noreturn_no_args,
+ .fn_ccc_void_no_args,
.single_const_pointer,
.single_const_pointer_to_comptime_int,
.const_slice_u8,
@@ -474,6 +482,7 @@ pub const Type = extern union {
.comptime_float,
.noreturn,
.fn_naked_noreturn_no_args,
+ .fn_ccc_void_no_args,
.array,
.single_const_pointer,
.single_const_pointer_to_comptime_int,
@@ -516,6 +525,7 @@ pub const Type = extern union {
.comptime_float,
.noreturn,
.fn_naked_noreturn_no_args,
+ .fn_ccc_void_no_args,
.array,
.single_const_pointer,
.single_const_pointer_to_comptime_int,
@@ -570,6 +580,7 @@ pub const Type = extern union {
pub fn fnParamLen(self: Type) usize {
return switch (self.tag()) {
.fn_naked_noreturn_no_args => 0,
+ .fn_ccc_void_no_args => 0,
.f16,
.f32,
@@ -612,6 +623,7 @@ pub const Type = extern union {
pub fn fnParamTypes(self: Type, types: []Type) void {
switch (self.tag()) {
.fn_naked_noreturn_no_args => return,
+ .fn_ccc_void_no_args => return,
.f16,
.f32,
@@ -653,6 +665,7 @@ pub const Type = extern union {
pub fn fnReturnType(self: Type) Type {
return switch (self.tag()) {
.fn_naked_noreturn_no_args => Type.initTag(.noreturn),
+ .fn_ccc_void_no_args => Type.initTag(.void),
.f16,
.f32,
@@ -694,6 +707,7 @@ pub const Type = extern union {
pub fn fnCallingConvention(self: Type) std.builtin.CallingConvention {
return switch (self.tag()) {
.fn_naked_noreturn_no_args => .Naked,
+ .fn_ccc_void_no_args => .C,
.f16,
.f32,
@@ -763,6 +777,7 @@ pub const Type = extern union {
.anyerror,
.noreturn,
.fn_naked_noreturn_no_args,
+ .fn_ccc_void_no_args,
.array,
.single_const_pointer,
.single_const_pointer_to_comptime_int,
@@ -798,6 +813,7 @@ pub const Type = extern union {
.type,
.anyerror,
.fn_naked_noreturn_no_args,
+ .fn_ccc_void_no_args,
.single_const_pointer_to_comptime_int,
.array_u8_sentinel_0,
.const_slice_u8,
@@ -850,6 +866,7 @@ pub const Type = extern union {
.type,
.anyerror,
.fn_naked_noreturn_no_args,
+ .fn_ccc_void_no_args,
.single_const_pointer_to_comptime_int,
.array_u8_sentinel_0,
.const_slice_u8,
@@ -898,6 +915,7 @@ pub const Type = extern union {
comptime_float,
noreturn,
fn_naked_noreturn_no_args,
+ fn_ccc_void_no_args,
single_const_pointer_to_comptime_int,
const_slice_u8, // See last_no_payload_tag below.
// After this, the tag requires a payload.
src-self-hosted/value.zig
@@ -45,6 +45,7 @@ pub const Value = extern union {
comptime_float_type,
noreturn_type,
fn_naked_noreturn_no_args_type,
+ fn_ccc_void_no_args_type,
single_const_pointer_to_comptime_int_type,
const_slice_u8_type,
@@ -134,6 +135,7 @@ pub const Value = extern union {
.comptime_float_type => return out_stream.writeAll("comptime_float"),
.noreturn_type => return out_stream.writeAll("noreturn"),
.fn_naked_noreturn_no_args_type => return out_stream.writeAll("fn() callconv(.Naked) noreturn"),
+ .fn_ccc_void_no_args_type => return out_stream.writeAll("fn() callconv(.C) void"),
.single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),
.const_slice_u8_type => return out_stream.writeAll("[]const u8"),
@@ -202,6 +204,7 @@ pub const Value = extern union {
.comptime_float_type => Type.initTag(.@"comptime_float"),
.noreturn_type => Type.initTag(.@"noreturn"),
.fn_naked_noreturn_no_args_type => Type.initTag(.fn_naked_noreturn_no_args),
+ .fn_ccc_void_no_args_type => Type.initTag(.fn_ccc_void_no_args),
.single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),
.const_slice_u8_type => Type.initTag(.const_slice_u8),
@@ -253,6 +256,7 @@ pub const Value = extern union {
.comptime_float_type,
.noreturn_type,
.fn_naked_noreturn_no_args_type,
+ .fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.bool_true,
@@ -306,6 +310,7 @@ pub const Value = extern union {
.comptime_float_type,
.noreturn_type,
.fn_naked_noreturn_no_args_type,
+ .fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.bool_true,
@@ -360,6 +365,7 @@ pub const Value = extern union {
.comptime_float_type,
.noreturn_type,
.fn_naked_noreturn_no_args_type,
+ .fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.bool_true,
@@ -419,6 +425,7 @@ pub const Value = extern union {
.comptime_float_type,
.noreturn_type,
.fn_naked_noreturn_no_args_type,
+ .fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.bool_true,
@@ -500,6 +507,7 @@ pub const Value = extern union {
.comptime_float_type,
.noreturn_type,
.fn_naked_noreturn_no_args_type,
+ .fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.bool_true,
@@ -550,6 +558,7 @@ pub const Value = extern union {
.comptime_float_type,
.noreturn_type,
.fn_naked_noreturn_no_args_type,
+ .fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.bool_true,
@@ -639,6 +648,7 @@ pub const Value = extern union {
.comptime_float_type,
.noreturn_type,
.fn_naked_noreturn_no_args_type,
+ .fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.zero,
@@ -691,6 +701,7 @@ pub const Value = extern union {
.comptime_float_type,
.noreturn_type,
.fn_naked_noreturn_no_args_type,
+ .fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.zero,
@@ -754,6 +765,7 @@ pub const Value = extern union {
.comptime_float_type,
.noreturn_type,
.fn_naked_noreturn_no_args_type,
+ .fn_ccc_void_no_args_type,
.single_const_pointer_to_comptime_int_type,
.const_slice_u8_type,
.zero,