authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-28 21:40:51-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-01 06:47:20-04:00
log28729efe2998579fc36a35e5bdab12727ece1e7a
tree56339a095da516a56b72749d3272fadbeb5163eb
parent6b0f7de247f3c12281f47f38738e93651d6bf51b

ZIR: implement return instruction


5 files changed, 78 insertions(+), 5 deletions(-)

lib/std/math/big/int.zig+2-2
......@@ -62,6 +62,7 @@ pub const Int = struct {
6262
6363 /// Hint: use `calcLimbLen` to figure out how big an array to allocate for `limbs`.
6464 pub fn initSetFixed(limbs: []Limb, value: var) Int {
65 mem.set(Limb, limbs, 0);
6566 var s = Int.initFixed(limbs);
6667 s.set(value) catch unreachable;
6768 return s;
......@@ -126,11 +127,10 @@ pub const Int = struct {
126127 /// sufficient capacity, the exact amount will be allocated. This occurs even if the requested
127128 /// capacity is only greater than the current capacity by one limb.
128129 pub fn ensureCapacity(self: *Int, capacity: usize) !void {
129 self.assertWritable();
130130 if (capacity <= self.limbs.len) {
131131 return;
132132 }
133
133 self.assertWritable();
134134 self.limbs = try self.allocator.?.realloc(self.limbs, capacity);
135135 }
136136
src-self-hosted/ir.zig+22
......@@ -22,6 +22,7 @@ pub const Inst = struct {
2222
2323 pub const Tag = enum {
2424 unreach,
25 ret,
2526 constant,
2627 assembly,
2728 ptrtoint,
......@@ -58,6 +59,12 @@ pub const Inst = struct {
5859 args: void,
5960 };
6061
62 pub const Ret = struct {
63 pub const base_tag = Tag.ret;
64 base: Inst,
65 args: void,
66 };
67
6168 pub const Constant = struct {
6269 pub const base_tag = Tag.constant;
6370 base: Inst,
......@@ -491,6 +498,7 @@ const Analyze = struct {
491498 .as => return self.analyzeInstAs(block, old_inst.cast(text.Inst.As).?),
492499 .@"asm" => return self.analyzeInstAsm(block, old_inst.cast(text.Inst.Asm).?),
493500 .@"unreachable" => return self.analyzeInstUnreachable(block, old_inst.cast(text.Inst.Unreachable).?),
501 .@"return" => return self.analyzeInstRet(block, old_inst.cast(text.Inst.Return).?),
494502 .@"fn" => return self.analyzeInstFn(block, old_inst.cast(text.Inst.Fn).?),
495503 .@"export" => {
496504 try self.analyzeExport(block, old_inst.cast(text.Inst.Export).?);
......@@ -556,6 +564,13 @@ const Analyze = struct {
556564 return self.constType(fntype.base.src, Type.initTag(.fn_naked_noreturn_no_args));
557565 }
558566
567 if (return_type.zigTypeTag() == .Void and
568 fntype.positionals.param_types.len == 0 and
569 fntype.kw_args.cc == .C)
570 {
571 return self.constType(fntype.base.src, Type.initTag(.fn_ccc_void_no_args));
572 }
573
559574 return self.fail(fntype.base.src, "TODO implement fntype instruction more", .{});
560575 }
561576
......@@ -886,6 +901,11 @@ const Analyze = struct {
886901 return self.addNewInstArgs(b, unreach.base.src, Type.initTag(.noreturn), Inst.Unreach, {});
887902 }
888903
904 fn analyzeInstRet(self: *Analyze, block: ?*Block, inst: *text.Inst.Return) InnerError!*Inst {
905 const b = try self.requireRuntimeBlock(block, inst.base.src);
906 return self.addNewInstArgs(b, inst.base.src, Type.initTag(.noreturn), Inst.Ret, {});
907 }
908
889909 fn analyzeBody(self: *Analyze, block: ?*Block, body: text.Module.Body) !void {
890910 for (body.instructions) |src_inst| {
891911 const new_inst = self.analyzeInst(block, src_inst) catch |err| {
......@@ -1199,11 +1219,13 @@ pub fn main() anyerror!void {
11991219 const allocator = if (std.builtin.link_libc) std.heap.c_allocator else &arena.allocator;
12001220
12011221 const args = try std.process.argsAlloc(allocator);
1222 defer std.process.argsFree(allocator, args);
12021223
12031224 const src_path = args[1];
12041225 const debug_error_trace = true;
12051226
12061227 const source = try std.fs.cwd().readFileAllocOptions(allocator, src_path, std.math.maxInt(u32), 1, 0);
1228 defer allocator.free(source);
12071229
12081230 var zir_module = try text.parse(allocator, source);
12091231 defer zir_module.deinit(allocator);
src-self-hosted/ir/text.zig+24-3
......@@ -26,6 +26,7 @@ pub const Inst = struct {
2626 as,
2727 @"asm",
2828 @"unreachable",
29 @"return",
2930 @"fn",
3031 @"export",
3132 primitive,
......@@ -50,6 +51,7 @@ pub const Inst = struct {
5051 .as => As,
5152 .@"asm" => Asm,
5253 .@"unreachable" => Unreachable,
54 .@"return" => Return,
5355 .@"fn" => Fn,
5456 .@"export" => Export,
5557 .primitive => Primitive,
......@@ -159,6 +161,14 @@ pub const Inst = struct {
159161 kw_args: struct {},
160162 };
161163
164 pub const Return = struct {
165 pub const base_tag = Tag.@"return";
166 base: Inst,
167
168 positionals: struct {},
169 kw_args: struct {},
170 };
171
162172 pub const Fn = struct {
163173 pub const base_tag = Tag.@"fn";
164174 base: Inst,
......@@ -417,6 +427,7 @@ pub const Module = struct {
417427 .as => return self.writeInstToStreamGeneric(stream, .as, decl, inst_table),
418428 .@"asm" => return self.writeInstToStreamGeneric(stream, .@"asm", decl, inst_table),
419429 .@"unreachable" => return self.writeInstToStreamGeneric(stream, .@"unreachable", decl, inst_table),
430 .@"return" => return self.writeInstToStreamGeneric(stream, .@"return", decl, inst_table),
420431 .@"fn" => return self.writeInstToStreamGeneric(stream, .@"fn", decl, inst_table),
421432 .@"export" => return self.writeInstToStreamGeneric(stream, .@"export", decl, inst_table),
422433 .primitive => return self.writeInstToStreamGeneric(stream, .primitive, decl, inst_table),
......@@ -1000,14 +1011,15 @@ const EmitZIR = struct {
10001011
10011012 const fn_type = try self.emitType(src, module_fn.fn_type);
10021013
1014 const arena_instrs = try self.arena.allocator.alloc(*Inst, instructions.items.len);
1015 mem.copy(*Inst, arena_instrs, instructions.items);
1016
10031017 const fn_inst = try self.arena.allocator.create(Inst.Fn);
10041018 fn_inst.* = .{
10051019 .base = .{ .src = src, .tag = Inst.Fn.base_tag },
10061020 .positionals = .{
10071021 .fn_type = fn_type,
1008 .body = .{
1009 .instructions = instructions.toOwnedSlice(),
1010 },
1022 .body = .{ .instructions = arena_instrs },
10111023 },
10121024 .kw_args = .{},
10131025 };
......@@ -1035,6 +1047,15 @@ const EmitZIR = struct {
10351047 };
10361048 break :blk &unreach_inst.base;
10371049 },
1050 .ret => blk: {
1051 const ret_inst = try self.arena.allocator.create(Inst.Return);
1052 ret_inst.* = .{
1053 .base = .{ .src = inst.src, .tag = Inst.Return.base_tag },
1054 .positionals = .{},
1055 .kw_args = .{},
1056 };
1057 break :blk &ret_inst.base;
1058 },
10381059 .constant => unreachable, // excluded from function bodies
10391060 .assembly => blk: {
10401061 const old_inst = inst.cast(ir.Inst.Assembly).?;
src-self-hosted/type.zig+18
......@@ -53,6 +53,7 @@ pub const Type = extern union {
5353 .noreturn => return .NoReturn,
5454
5555 .fn_naked_noreturn_no_args => return .Fn,
56 .fn_ccc_void_no_args => return .Fn,
5657
5758 .array, .array_u8_sentinel_0 => return .Array,
5859 .single_const_pointer => return .Pointer,
......@@ -184,6 +185,7 @@ pub const Type = extern union {
184185
185186 .const_slice_u8 => return out_stream.writeAll("[]const u8"),
186187 .fn_naked_noreturn_no_args => return out_stream.writeAll("fn() callconv(.Naked) noreturn"),
188 .fn_ccc_void_no_args => return out_stream.writeAll("fn() callconv(.C) void"),
187189 .single_const_pointer_to_comptime_int => return out_stream.writeAll("*const comptime_int"),
188190
189191 .array_u8_sentinel_0 => {
......@@ -243,6 +245,7 @@ pub const Type = extern union {
243245 .comptime_float => return Value.initTag(.comptime_float_type),
244246 .noreturn => return Value.initTag(.noreturn_type),
245247 .fn_naked_noreturn_no_args => return Value.initTag(.fn_naked_noreturn_no_args_type),
248 .fn_ccc_void_no_args => return Value.initTag(.fn_ccc_void_no_args_type),
246249 .single_const_pointer_to_comptime_int => return Value.initTag(.single_const_pointer_to_comptime_int_type),
247250 .const_slice_u8 => return Value.initTag(.const_slice_u8_type),
248251 else => {
......@@ -284,6 +287,7 @@ pub const Type = extern union {
284287 .array_u8_sentinel_0,
285288 .const_slice_u8,
286289 .fn_naked_noreturn_no_args,
290 .fn_ccc_void_no_args,
287291 .int_unsigned,
288292 .int_signed,
289293 => false,
......@@ -326,6 +330,7 @@ pub const Type = extern union {
326330 .single_const_pointer,
327331 .single_const_pointer_to_comptime_int,
328332 .fn_naked_noreturn_no_args,
333 .fn_ccc_void_no_args,
329334 .int_unsigned,
330335 .int_signed,
331336 => false,
......@@ -365,6 +370,7 @@ pub const Type = extern union {
365370 .array,
366371 .array_u8_sentinel_0,
367372 .fn_naked_noreturn_no_args,
373 .fn_ccc_void_no_args,
368374 .int_unsigned,
369375 .int_signed,
370376 => unreachable,
......@@ -405,6 +411,7 @@ pub const Type = extern union {
405411 .comptime_float,
406412 .noreturn,
407413 .fn_naked_noreturn_no_args,
414 .fn_ccc_void_no_args,
408415 .int_unsigned,
409416 .int_signed,
410417 => unreachable,
......@@ -445,6 +452,7 @@ pub const Type = extern union {
445452 .comptime_float,
446453 .noreturn,
447454 .fn_naked_noreturn_no_args,
455 .fn_ccc_void_no_args,
448456 .single_const_pointer,
449457 .single_const_pointer_to_comptime_int,
450458 .const_slice_u8,
......@@ -474,6 +482,7 @@ pub const Type = extern union {
474482 .comptime_float,
475483 .noreturn,
476484 .fn_naked_noreturn_no_args,
485 .fn_ccc_void_no_args,
477486 .array,
478487 .single_const_pointer,
479488 .single_const_pointer_to_comptime_int,
......@@ -516,6 +525,7 @@ pub const Type = extern union {
516525 .comptime_float,
517526 .noreturn,
518527 .fn_naked_noreturn_no_args,
528 .fn_ccc_void_no_args,
519529 .array,
520530 .single_const_pointer,
521531 .single_const_pointer_to_comptime_int,
......@@ -570,6 +580,7 @@ pub const Type = extern union {
570580 pub fn fnParamLen(self: Type) usize {
571581 return switch (self.tag()) {
572582 .fn_naked_noreturn_no_args => 0,
583 .fn_ccc_void_no_args => 0,
573584
574585 .f16,
575586 .f32,
......@@ -612,6 +623,7 @@ pub const Type = extern union {
612623 pub fn fnParamTypes(self: Type, types: []Type) void {
613624 switch (self.tag()) {
614625 .fn_naked_noreturn_no_args => return,
626 .fn_ccc_void_no_args => return,
615627
616628 .f16,
617629 .f32,
......@@ -653,6 +665,7 @@ pub const Type = extern union {
653665 pub fn fnReturnType(self: Type) Type {
654666 return switch (self.tag()) {
655667 .fn_naked_noreturn_no_args => Type.initTag(.noreturn),
668 .fn_ccc_void_no_args => Type.initTag(.void),
656669
657670 .f16,
658671 .f32,
......@@ -694,6 +707,7 @@ pub const Type = extern union {
694707 pub fn fnCallingConvention(self: Type) std.builtin.CallingConvention {
695708 return switch (self.tag()) {
696709 .fn_naked_noreturn_no_args => .Naked,
710 .fn_ccc_void_no_args => .C,
697711
698712 .f16,
699713 .f32,
......@@ -763,6 +777,7 @@ pub const Type = extern union {
763777 .anyerror,
764778 .noreturn,
765779 .fn_naked_noreturn_no_args,
780 .fn_ccc_void_no_args,
766781 .array,
767782 .single_const_pointer,
768783 .single_const_pointer_to_comptime_int,
......@@ -798,6 +813,7 @@ pub const Type = extern union {
798813 .type,
799814 .anyerror,
800815 .fn_naked_noreturn_no_args,
816 .fn_ccc_void_no_args,
801817 .single_const_pointer_to_comptime_int,
802818 .array_u8_sentinel_0,
803819 .const_slice_u8,
......@@ -850,6 +866,7 @@ pub const Type = extern union {
850866 .type,
851867 .anyerror,
852868 .fn_naked_noreturn_no_args,
869 .fn_ccc_void_no_args,
853870 .single_const_pointer_to_comptime_int,
854871 .array_u8_sentinel_0,
855872 .const_slice_u8,
......@@ -898,6 +915,7 @@ pub const Type = extern union {
898915 comptime_float,
899916 noreturn,
900917 fn_naked_noreturn_no_args,
918 fn_ccc_void_no_args,
901919 single_const_pointer_to_comptime_int,
902920 const_slice_u8, // See last_no_payload_tag below.
903921 // After this, the tag requires a payload.
src-self-hosted/value.zig+12
......@@ -45,6 +45,7 @@ pub const Value = extern union {
4545 comptime_float_type,
4646 noreturn_type,
4747 fn_naked_noreturn_no_args_type,
48 fn_ccc_void_no_args_type,
4849 single_const_pointer_to_comptime_int_type,
4950 const_slice_u8_type,
5051
......@@ -134,6 +135,7 @@ pub const Value = extern union {
134135 .comptime_float_type => return out_stream.writeAll("comptime_float"),
135136 .noreturn_type => return out_stream.writeAll("noreturn"),
136137 .fn_naked_noreturn_no_args_type => return out_stream.writeAll("fn() callconv(.Naked) noreturn"),
138 .fn_ccc_void_no_args_type => return out_stream.writeAll("fn() callconv(.C) void"),
137139 .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"),
138140 .const_slice_u8_type => return out_stream.writeAll("[]const u8"),
139141
......@@ -202,6 +204,7 @@ pub const Value = extern union {
202204 .comptime_float_type => Type.initTag(.@"comptime_float"),
203205 .noreturn_type => Type.initTag(.@"noreturn"),
204206 .fn_naked_noreturn_no_args_type => Type.initTag(.fn_naked_noreturn_no_args),
207 .fn_ccc_void_no_args_type => Type.initTag(.fn_ccc_void_no_args),
205208 .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int),
206209 .const_slice_u8_type => Type.initTag(.const_slice_u8),
207210
......@@ -253,6 +256,7 @@ pub const Value = extern union {
253256 .comptime_float_type,
254257 .noreturn_type,
255258 .fn_naked_noreturn_no_args_type,
259 .fn_ccc_void_no_args_type,
256260 .single_const_pointer_to_comptime_int_type,
257261 .const_slice_u8_type,
258262 .bool_true,
......@@ -306,6 +310,7 @@ pub const Value = extern union {
306310 .comptime_float_type,
307311 .noreturn_type,
308312 .fn_naked_noreturn_no_args_type,
313 .fn_ccc_void_no_args_type,
309314 .single_const_pointer_to_comptime_int_type,
310315 .const_slice_u8_type,
311316 .bool_true,
......@@ -360,6 +365,7 @@ pub const Value = extern union {
360365 .comptime_float_type,
361366 .noreturn_type,
362367 .fn_naked_noreturn_no_args_type,
368 .fn_ccc_void_no_args_type,
363369 .single_const_pointer_to_comptime_int_type,
364370 .const_slice_u8_type,
365371 .bool_true,
......@@ -419,6 +425,7 @@ pub const Value = extern union {
419425 .comptime_float_type,
420426 .noreturn_type,
421427 .fn_naked_noreturn_no_args_type,
428 .fn_ccc_void_no_args_type,
422429 .single_const_pointer_to_comptime_int_type,
423430 .const_slice_u8_type,
424431 .bool_true,
......@@ -500,6 +507,7 @@ pub const Value = extern union {
500507 .comptime_float_type,
501508 .noreturn_type,
502509 .fn_naked_noreturn_no_args_type,
510 .fn_ccc_void_no_args_type,
503511 .single_const_pointer_to_comptime_int_type,
504512 .const_slice_u8_type,
505513 .bool_true,
......@@ -550,6 +558,7 @@ pub const Value = extern union {
550558 .comptime_float_type,
551559 .noreturn_type,
552560 .fn_naked_noreturn_no_args_type,
561 .fn_ccc_void_no_args_type,
553562 .single_const_pointer_to_comptime_int_type,
554563 .const_slice_u8_type,
555564 .bool_true,
......@@ -639,6 +648,7 @@ pub const Value = extern union {
639648 .comptime_float_type,
640649 .noreturn_type,
641650 .fn_naked_noreturn_no_args_type,
651 .fn_ccc_void_no_args_type,
642652 .single_const_pointer_to_comptime_int_type,
643653 .const_slice_u8_type,
644654 .zero,
......@@ -691,6 +701,7 @@ pub const Value = extern union {
691701 .comptime_float_type,
692702 .noreturn_type,
693703 .fn_naked_noreturn_no_args_type,
704 .fn_ccc_void_no_args_type,
694705 .single_const_pointer_to_comptime_int_type,
695706 .const_slice_u8_type,
696707 .zero,
......@@ -754,6 +765,7 @@ pub const Value = extern union {
754765 .comptime_float_type,
755766 .noreturn_type,
756767 .fn_naked_noreturn_no_args_type,
768 .fn_ccc_void_no_args_type,
757769 .single_const_pointer_to_comptime_int_type,
758770 .const_slice_u8_type,
759771 .zero,