| ... | @@ -356,16 +356,15 @@ pub const Module = struct { | ... | @@ -356,16 +356,15 @@ pub const Module = struct { |
| 356 | comptime var need_comma = pos_fields.len != 0; | 356 | comptime var need_comma = pos_fields.len != 0; |
| 357 | const KW_Args = @TypeOf(inst.kw_args); | 357 | const KW_Args = @TypeOf(inst.kw_args); |
| 358 | inline for (@typeInfo(KW_Args).Struct.fields) |arg_field, i| { | 358 | inline for (@typeInfo(KW_Args).Struct.fields) |arg_field, i| { |
| 359 | if (need_comma) { | | |
| 360 | try stream.writeAll(", "); | | |
| 361 | } | | |
| 362 | if (@typeInfo(arg_field.field_type) == .Optional) { | 359 | if (@typeInfo(arg_field.field_type) == .Optional) { |
| 363 | if (@field(inst.kw_args, arg_field.name)) |non_optional| { | 360 | if (@field(inst.kw_args, arg_field.name)) |non_optional| { |
| | 361 | if (need_comma) try stream.writeAll(", "); |
| 364 | try stream.print("{}=", .{arg_field.name}); | 362 | try stream.print("{}=", .{arg_field.name}); |
| 365 | try self.writeParamToStream(stream, non_optional, inst_table); | 363 | try self.writeParamToStream(stream, non_optional, inst_table); |
| 366 | need_comma = true; | 364 | need_comma = true; |
| 367 | } | 365 | } |
| 368 | } else { | 366 | } else { |
| | 367 | if (need_comma) try stream.writeAll(", "); |
| 369 | try stream.print("{}=", .{arg_field.name}); | 368 | try stream.print("{}=", .{arg_field.name}); |
| 370 | try self.writeParamToStream(stream, @field(inst.kw_args, arg_field.name), inst_table); | 369 | try self.writeParamToStream(stream, @field(inst.kw_args, arg_field.name), inst_table); |
| 371 | need_comma = true; | 370 | need_comma = true; |
| ... | @@ -806,7 +805,7 @@ const EmitZIR = struct { | ... | @@ -806,7 +805,7 @@ const EmitZIR = struct { |
| 806 | decls: std.ArrayList(*Inst), | 805 | decls: std.ArrayList(*Inst), |
| 807 | decl_table: std.AutoHashMap(*ir.Inst, *Inst), | 806 | decl_table: std.AutoHashMap(*ir.Inst, *Inst), |
| 808 | | 807 | |
| 809 | pub fn emit(self: *EmitZIR) !void { | 808 | fn emit(self: *EmitZIR) !void { |
| 810 | for (self.old_module.exports) |module_export| { | 809 | for (self.old_module.exports) |module_export| { |
| 811 | const export_value = try self.emitTypedValue(module_export.src, module_export.typed_value); | 810 | const export_value = try self.emitTypedValue(module_export.src, module_export.typed_value); |
| 812 | const symbol_name = try self.emitStringLiteral(module_export.src, module_export.name); | 811 | const symbol_name = try self.emitStringLiteral(module_export.src, module_export.name); |
| ... | @@ -823,7 +822,7 @@ const EmitZIR = struct { | ... | @@ -823,7 +822,7 @@ const EmitZIR = struct { |
| 823 | } | 822 | } |
| 824 | } | 823 | } |
| 825 | | 824 | |
| 826 | pub fn resolveInst(self: *EmitZIR, inst_table: *const std.AutoHashMap(*ir.Inst, *Inst), inst: *ir.Inst) !*Inst { | 825 | fn resolveInst(self: *EmitZIR, inst_table: *const std.AutoHashMap(*ir.Inst, *Inst), inst: *ir.Inst) !*Inst { |
| 827 | if (inst.cast(ir.Inst.Constant)) |const_inst| { | 826 | if (inst.cast(ir.Inst.Constant)) |const_inst| { |
| 828 | if (self.decl_table.getValue(inst)) |decl| { | 827 | if (self.decl_table.getValue(inst)) |decl| { |
| 829 | return decl; | 828 | return decl; |
| ... | @@ -836,7 +835,20 @@ const EmitZIR = struct { | ... | @@ -836,7 +835,20 @@ const EmitZIR = struct { |
| 836 | } | 835 | } |
| 837 | } | 836 | } |
| 838 | | 837 | |
| 839 | pub fn emitTypedValue(self: *EmitZIR, src: usize, typed_value: ir.TypedValue) Allocator.Error!*Inst { | 838 | fn emitComptimeIntVal(self: *EmitZIR, src: usize, val: Value) !*Inst { |
| | 839 | const int_inst = try self.arena.allocator.create(Inst.Int); |
| | 840 | int_inst.* = .{ |
| | 841 | .base = .{ .src = src, .tag = Inst.Int.base_tag }, |
| | 842 | .positionals = .{ |
| | 843 | .int = try val.toBigInt(&self.arena.allocator), |
| | 844 | }, |
| | 845 | .kw_args = .{}, |
| | 846 | }; |
| | 847 | try self.decls.append(&int_inst.base); |
| | 848 | return &int_inst.base; |
| | 849 | } |
| | 850 | |
| | 851 | fn emitTypedValue(self: *EmitZIR, src: usize, typed_value: ir.TypedValue) Allocator.Error!*Inst { |
| 840 | switch (typed_value.ty.zigTypeTag()) { | 852 | switch (typed_value.ty.zigTypeTag()) { |
| 841 | .Pointer => { | 853 | .Pointer => { |
| 842 | const ptr_elem_type = typed_value.ty.elemType(); | 854 | const ptr_elem_type = typed_value.ty.elemType(); |
| ... | @@ -854,6 +866,21 @@ const EmitZIR = struct { | ... | @@ -854,6 +866,21 @@ const EmitZIR = struct { |
| 854 | else => |t| std.debug.panic("TODO implement emitTypedValue for pointer to {}", .{@tagName(t)}), | 866 | else => |t| std.debug.panic("TODO implement emitTypedValue for pointer to {}", .{@tagName(t)}), |
| 855 | } | 867 | } |
| 856 | }, | 868 | }, |
| | 869 | .ComptimeInt => return self.emitComptimeIntVal(src, typed_value.val), |
| | 870 | .Int => { |
| | 871 | const as_inst = try self.arena.allocator.create(Inst.As); |
| | 872 | as_inst.* = .{ |
| | 873 | .base = .{ .src = src, .tag = Inst.As.base_tag }, |
| | 874 | .positionals = .{ |
| | 875 | .dest_type = try self.emitType(src, typed_value.ty), |
| | 876 | .value = try self.emitComptimeIntVal(src, typed_value.val), |
| | 877 | }, |
| | 878 | .kw_args = .{}, |
| | 879 | }; |
| | 880 | try self.decls.append(&as_inst.base); |
| | 881 | |
| | 882 | return &as_inst.base; |
| | 883 | }, |
| 857 | .Type => { | 884 | .Type => { |
| 858 | const ty = typed_value.val.toType(); | 885 | const ty = typed_value.val.toType(); |
| 859 | return self.emitType(src, ty); | 886 | return self.emitType(src, ty); |
| ... | @@ -883,14 +910,38 @@ const EmitZIR = struct { | ... | @@ -883,14 +910,38 @@ const EmitZIR = struct { |
| 883 | .assembly => blk: { | 910 | .assembly => blk: { |
| 884 | const old_inst = inst.cast(ir.Inst.Assembly).?; | 911 | const old_inst = inst.cast(ir.Inst.Assembly).?; |
| 885 | const new_inst = try self.arena.allocator.create(Inst.Asm); | 912 | const new_inst = try self.arena.allocator.create(Inst.Asm); |
| | 913 | |
| | 914 | const inputs = try self.arena.allocator.alloc(*Inst, old_inst.args.inputs.len); |
| | 915 | for (inputs) |*elem, i| { |
| | 916 | elem.* = try self.emitStringLiteral(inst.src, old_inst.args.inputs[i]); |
| | 917 | } |
| | 918 | |
| | 919 | const clobbers = try self.arena.allocator.alloc(*Inst, old_inst.args.clobbers.len); |
| | 920 | for (clobbers) |*elem, i| { |
| | 921 | elem.* = try self.emitStringLiteral(inst.src, old_inst.args.clobbers[i]); |
| | 922 | } |
| | 923 | |
| | 924 | const args = try self.arena.allocator.alloc(*Inst, old_inst.args.args.len); |
| | 925 | for (args) |*elem, i| { |
| | 926 | elem.* = try self.resolveInst(&inst_table, old_inst.args.args[i]); |
| | 927 | } |
| | 928 | |
| 886 | new_inst.* = .{ | 929 | new_inst.* = .{ |
| 887 | .base = .{ .src = inst.src, .tag = Inst.Asm.base_tag }, | 930 | .base = .{ .src = inst.src, .tag = Inst.Asm.base_tag }, |
| 888 | .positionals = .{ | 931 | .positionals = .{ |
| 889 | .asm_source = try self.emitStringLiteral(inst.src, old_inst.args.asm_source), | 932 | .asm_source = try self.emitStringLiteral(inst.src, old_inst.args.asm_source), |
| 890 | .return_type = try self.emitType(inst.src, inst.ty), | 933 | .return_type = try self.emitType(inst.src, inst.ty), |
| 891 | }, | 934 | }, |
| 892 | // TODO emit more kw_args | 935 | .kw_args = .{ |
| 893 | .kw_args = .{}, | 936 | .@"volatile" = old_inst.args.is_volatile, |
| | 937 | .output = if (old_inst.args.output) |o| |
| | 938 | try self.emitStringLiteral(inst.src, o) |
| | 939 | else |
| | 940 | null, |
| | 941 | .inputs = inputs, |
| | 942 | .clobbers = clobbers, |
| | 943 | .args = args, |
| | 944 | }, |
| 894 | }; | 945 | }; |
| 895 | break :blk &new_inst.base; | 946 | break :blk &new_inst.base; |
| 896 | }, | 947 | }, |
| ... | @@ -931,7 +982,7 @@ const EmitZIR = struct { | ... | @@ -931,7 +982,7 @@ const EmitZIR = struct { |
| 931 | } | 982 | } |
| 932 | } | 983 | } |
| 933 | | 984 | |
| 934 | pub fn emitType(self: *EmitZIR, src: usize, ty: Type) Allocator.Error!*Inst { | 985 | fn emitType(self: *EmitZIR, src: usize, ty: Type) Allocator.Error!*Inst { |
| 935 | switch (ty.tag()) { | 986 | switch (ty.tag()) { |
| 936 | .isize => return self.emitPrimitiveType(src, .isize), | 987 | .isize => return self.emitPrimitiveType(src, .isize), |
| 937 | .usize => return self.emitPrimitiveType(src, .usize), | 988 | .usize => return self.emitPrimitiveType(src, .usize), |
| ... | @@ -986,7 +1037,7 @@ const EmitZIR = struct { | ... | @@ -986,7 +1037,7 @@ const EmitZIR = struct { |
| 986 | } | 1037 | } |
| 987 | } | 1038 | } |
| 988 | | 1039 | |
| 989 | pub fn emitPrimitiveType(self: *EmitZIR, src: usize, tag: Inst.Primitive.BuiltinType) !*Inst { | 1040 | fn emitPrimitiveType(self: *EmitZIR, src: usize, tag: Inst.Primitive.BuiltinType) !*Inst { |
| 990 | const primitive_inst = try self.arena.allocator.create(Inst.Primitive); | 1041 | const primitive_inst = try self.arena.allocator.create(Inst.Primitive); |
| 991 | primitive_inst.* = .{ | 1042 | primitive_inst.* = .{ |
| 992 | .base = .{ .src = src, .tag = Inst.Primitive.base_tag }, | 1043 | .base = .{ .src = src, .tag = Inst.Primitive.base_tag }, |
| ... | @@ -999,7 +1050,7 @@ const EmitZIR = struct { | ... | @@ -999,7 +1050,7 @@ const EmitZIR = struct { |
| 999 | return &primitive_inst.base; | 1050 | return &primitive_inst.base; |
| 1000 | } | 1051 | } |
| 1001 | | 1052 | |
| 1002 | pub fn emitStringLiteral(self: *EmitZIR, src: usize, str: []const u8) !*Inst { | 1053 | fn emitStringLiteral(self: *EmitZIR, src: usize, str: []const u8) !*Inst { |
| 1003 | const str_inst = try self.arena.allocator.create(Inst.Str); | 1054 | const str_inst = try self.arena.allocator.create(Inst.Str); |
| 1004 | str_inst.* = .{ | 1055 | str_inst.* = .{ |
| 1005 | .base = .{ .src = src, .tag = Inst.Str.base_tag }, | 1056 | .base = .{ .src = src, .tag = Inst.Str.base_tag }, |