| author | |
| committer | |
| log | b1a86040dd530fd5632b22359eb7534dc2e3f4c9 |
| tree | dcf3a68e060acd29eeb7454ff1c84761af1ade1a |
| parent | 993e6545546b499e8052a0020cc10e399c235c11 |
2 files changed, 196 insertions(+), 2 deletions(-)
src-self-hosted/ir/text.zig+39-2| ... | @@ -880,7 +880,20 @@ const EmitZIR = struct { | ... | @@ -880,7 +880,20 @@ const EmitZIR = struct { |
| 880 | break :blk &unreach_inst.base; | 880 | break :blk &unreach_inst.base; |
| 881 | }, | 881 | }, |
| 882 | .constant => unreachable, // excluded from function bodies | 882 | .constant => unreachable, // excluded from function bodies |
| 883 | .assembly => @panic("TODO emit zir asm instruction"), | 883 | .assembly => blk: { |
| 884 | const old_inst = inst.cast(ir.Inst.Assembly).?; | ||
| 885 | const new_inst = try self.arena.allocator.create(Inst.Asm); | ||
| 886 | new_inst.* = .{ | ||
| 887 | .base = .{ .src = inst.src, .tag = Inst.Asm.base_tag }, | ||
| 888 | .positionals = .{ | ||
| 889 | .asm_source = try self.emitStringLiteral(inst.src, old_inst.args.asm_source), | ||
| 890 | .return_type = try self.emitType(inst.src, inst.ty), | ||
| 891 | }, | ||
| 892 | // TODO emit more kw_args | ||
| 893 | .kw_args = .{}, | ||
| 894 | }; | ||
| 895 | break :blk &new_inst.base; | ||
| 896 | }, | ||
| 884 | .ptrtoint => blk: { | 897 | .ptrtoint => blk: { |
| 885 | const old_inst = inst.cast(ir.Inst.PtrToInt).?; | 898 | const old_inst = inst.cast(ir.Inst.PtrToInt).?; |
| 886 | const new_inst = try self.arena.allocator.create(Inst.PtrToInt); | 899 | const new_inst = try self.arena.allocator.create(Inst.PtrToInt); |
| ... | @@ -918,7 +931,7 @@ const EmitZIR = struct { | ... | @@ -918,7 +931,7 @@ const EmitZIR = struct { |
| 918 | } | 931 | } |
| 919 | } | 932 | } |
| 920 | 933 | ||
| 921 | pub fn emitType(self: *EmitZIR, src: usize, ty: Type) !*Inst { | 934 | pub fn emitType(self: *EmitZIR, src: usize, ty: Type) Allocator.Error!*Inst { |
| 922 | switch (ty.tag()) { | 935 | switch (ty.tag()) { |
| 923 | .isize => return self.emitPrimitiveType(src, .isize), | 936 | .isize => return self.emitPrimitiveType(src, .isize), |
| 924 | .usize => return self.emitPrimitiveType(src, .usize), | 937 | .usize => return self.emitPrimitiveType(src, .usize), |
| ... | @@ -944,6 +957,30 @@ const EmitZIR = struct { | ... | @@ -944,6 +957,30 @@ const EmitZIR = struct { |
| 944 | .Type => return self.emitPrimitiveType(src, .type), | 957 | .Type => return self.emitPrimitiveType(src, .type), |
| 945 | .ComptimeInt => return self.emitPrimitiveType(src, .comptime_int), | 958 | .ComptimeInt => return self.emitPrimitiveType(src, .comptime_int), |
| 946 | .ComptimeFloat => return self.emitPrimitiveType(src, .comptime_float), | 959 | .ComptimeFloat => return self.emitPrimitiveType(src, .comptime_float), |
| 960 | .Fn => { | ||
| 961 | const param_types = try self.allocator.alloc(Type, ty.fnParamLen()); | ||
| 962 | defer self.allocator.free(param_types); | ||
| 963 | |||
| 964 | ty.fnParamTypes(param_types); | ||
| 965 | const emitted_params = try self.arena.allocator.alloc(*Inst, param_types.len); | ||
| 966 | for (param_types) |param_type, i| { | ||
| 967 | emitted_params[i] = try self.emitType(src, param_type); | ||
| 968 | } | ||
| 969 | |||
| 970 | const fntype_inst = try self.arena.allocator.create(Inst.FnType); | ||
| 971 | fntype_inst.* = .{ | ||
| 972 | .base = .{ .src = src, .tag = Inst.FnType.base_tag }, | ||
| 973 | .positionals = .{ | ||
| 974 | .param_types = emitted_params, | ||
| 975 | .return_type = try self.emitType(src, ty.fnReturnType()), | ||
| 976 | }, | ||
| 977 | .kw_args = .{ | ||
| 978 | .cc = ty.fnCallingConvention(), | ||
| 979 | }, | ||
| 980 | }; | ||
| 981 | try self.decls.append(&fntype_inst.base); | ||
| 982 | return &fntype_inst.base; | ||
| 983 | }, | ||
| 947 | else => std.debug.panic("TODO implement emitType for {}", .{ty}), | 984 | else => std.debug.panic("TODO implement emitType for {}", .{ty}), |
| 948 | }, | 985 | }, |
| 949 | } | 986 | } |
src-self-hosted/type.zig+157| ... | @@ -422,6 +422,163 @@ pub const Type = extern union { | ... | @@ -422,6 +422,163 @@ pub const Type = extern union { |
| 422 | }; | 422 | }; |
| 423 | } | 423 | } |
| 424 | 424 | ||
| 425 | /// Asserts the type is a function. | ||
| 426 | pub fn fnParamLen(self: Type) usize { | ||
| 427 | return switch (self.tag()) { | ||
| 428 | .fn_naked_noreturn_no_args => 0, | ||
| 429 | |||
| 430 | .f16, | ||
| 431 | .f32, | ||
| 432 | .f64, | ||
| 433 | .f128, | ||
| 434 | .c_longdouble, | ||
| 435 | .c_void, | ||
| 436 | .bool, | ||
| 437 | .void, | ||
| 438 | .type, | ||
| 439 | .anyerror, | ||
| 440 | .comptime_int, | ||
| 441 | .comptime_float, | ||
| 442 | .noreturn, | ||
| 443 | .array, | ||
| 444 | .single_const_pointer, | ||
| 445 | .single_const_pointer_to_comptime_int, | ||
| 446 | .array_u8_sentinel_0, | ||
| 447 | .const_slice_u8, | ||
| 448 | .u8, | ||
| 449 | .i8, | ||
| 450 | .usize, | ||
| 451 | .isize, | ||
| 452 | .c_short, | ||
| 453 | .c_ushort, | ||
| 454 | .c_int, | ||
| 455 | .c_uint, | ||
| 456 | .c_long, | ||
| 457 | .c_ulong, | ||
| 458 | .c_longlong, | ||
| 459 | .c_ulonglong, | ||
| 460 | => unreachable, | ||
| 461 | }; | ||
| 462 | } | ||
| 463 | |||
| 464 | /// Asserts the type is a function. The length of the slice must be at least the length | ||
| 465 | /// given by `fnParamLen`. | ||
| 466 | pub fn fnParamTypes(self: Type, types: []Type) void { | ||
| 467 | switch (self.tag()) { | ||
| 468 | .fn_naked_noreturn_no_args => return, | ||
| 469 | |||
| 470 | .f16, | ||
| 471 | .f32, | ||
| 472 | .f64, | ||
| 473 | .f128, | ||
| 474 | .c_longdouble, | ||
| 475 | .c_void, | ||
| 476 | .bool, | ||
| 477 | .void, | ||
| 478 | .type, | ||
| 479 | .anyerror, | ||
| 480 | .comptime_int, | ||
| 481 | .comptime_float, | ||
| 482 | .noreturn, | ||
| 483 | .array, | ||
| 484 | .single_const_pointer, | ||
| 485 | .single_const_pointer_to_comptime_int, | ||
| 486 | .array_u8_sentinel_0, | ||
| 487 | .const_slice_u8, | ||
| 488 | .u8, | ||
| 489 | .i8, | ||
| 490 | .usize, | ||
| 491 | .isize, | ||
| 492 | .c_short, | ||
| 493 | .c_ushort, | ||
| 494 | .c_int, | ||
| 495 | .c_uint, | ||
| 496 | .c_long, | ||
| 497 | .c_ulong, | ||
| 498 | .c_longlong, | ||
| 499 | .c_ulonglong, | ||
| 500 | => unreachable, | ||
| 501 | } | ||
| 502 | } | ||
| 503 | |||
| 504 | /// Asserts the type is a function. | ||
| 505 | pub fn fnReturnType(self: Type) Type { | ||
| 506 | return switch (self.tag()) { | ||
| 507 | .fn_naked_noreturn_no_args => Type.initTag(.noreturn), | ||
| 508 | |||
| 509 | .f16, | ||
| 510 | .f32, | ||
| 511 | .f64, | ||
| 512 | .f128, | ||
| 513 | .c_longdouble, | ||
| 514 | .c_void, | ||
| 515 | .bool, | ||
| 516 | .void, | ||
| 517 | .type, | ||
| 518 | .anyerror, | ||
| 519 | .comptime_int, | ||
| 520 | .comptime_float, | ||
| 521 | .noreturn, | ||
| 522 | .array, | ||
| 523 | .single_const_pointer, | ||
| 524 | .single_const_pointer_to_comptime_int, | ||
| 525 | .array_u8_sentinel_0, | ||
| 526 | .const_slice_u8, | ||
| 527 | .u8, | ||
| 528 | .i8, | ||
| 529 | .usize, | ||
| 530 | .isize, | ||
| 531 | .c_short, | ||
| 532 | .c_ushort, | ||
| 533 | .c_int, | ||
| 534 | .c_uint, | ||
| 535 | .c_long, | ||
| 536 | .c_ulong, | ||
| 537 | .c_longlong, | ||
| 538 | .c_ulonglong, | ||
| 539 | => unreachable, | ||
| 540 | }; | ||
| 541 | } | ||
| 542 | |||
| 543 | /// Asserts the type is a function. | ||
| 544 | pub fn fnCallingConvention(self: Type) std.builtin.CallingConvention { | ||
| 545 | return switch (self.tag()) { | ||
| 546 | .fn_naked_noreturn_no_args => .Naked, | ||
| 547 | |||
| 548 | .f16, | ||
| 549 | .f32, | ||
| 550 | .f64, | ||
| 551 | .f128, | ||
| 552 | .c_longdouble, | ||
| 553 | .c_void, | ||
| 554 | .bool, | ||
| 555 | .void, | ||
| 556 | .type, | ||
| 557 | .anyerror, | ||
| 558 | .comptime_int, | ||
| 559 | .comptime_float, | ||
| 560 | .noreturn, | ||
| 561 | .array, | ||
| 562 | .single_const_pointer, | ||
| 563 | .single_const_pointer_to_comptime_int, | ||
| 564 | .array_u8_sentinel_0, | ||
| 565 | .const_slice_u8, | ||
| 566 | .u8, | ||
| 567 | .i8, | ||
| 568 | .usize, | ||
| 569 | .isize, | ||
| 570 | .c_short, | ||
| 571 | .c_ushort, | ||
| 572 | .c_int, | ||
| 573 | .c_uint, | ||
| 574 | .c_long, | ||
| 575 | .c_ulong, | ||
| 576 | .c_longlong, | ||
| 577 | .c_ulonglong, | ||
| 578 | => unreachable, | ||
| 579 | }; | ||
| 580 | } | ||
| 581 | |||
| 425 | /// This enum does not directly correspond to `std.builtin.TypeId` because | 582 | /// This enum does not directly correspond to `std.builtin.TypeId` because |
| 426 | /// it has extra enum tags in it, as a way of using less memory. For example, | 583 | /// it has extra enum tags in it, as a way of using less memory. For example, |
| 427 | /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types | 584 | /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types |