authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-12-17 23:37:21-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-01-15 15:11:35-08:00
log416fc2df94ee7a17eb8f133c0814e36e0a358e22
tree33389ae0098c6f58f80b9d59ed1697df64edc41f
parent458f658b427c26ede2776a04113ba00a3a491793

complete wasm.Emit implementation


3 files changed, 326 insertions(+), 32 deletions(-)

src/arch/wasm/Emit.zig+249-9
...@@ -30,6 +30,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -30,6 +30,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
30 const is_obj = comp.config.output_mode == .Obj;30 const is_obj = comp.config.output_mode == .Obj;
31 const target = &comp.root_mod.resolved_target.result;31 const target = &comp.root_mod.resolved_target.result;
32 const is_wasm32 = target.cpu.arch == .wasm32;32 const is_wasm32 = target.cpu.arch == .wasm32;
33 const function_imports_len: u32 = @intCast(wasm.function_imports.entries.len);
3334
34 const tags = mir.instruction_tags;35 const tags = mir.instruction_tags;
35 const datas = mir.instruction_datas;36 const datas = mir.instruction_datas;
...@@ -158,8 +159,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -158,8 +159,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {
158 });159 });
159 code.appendNTimesAssumeCapacity(0, 5);160 code.appendNTimesAssumeCapacity(0, 5);
160 } else {161 } else {
161 const func_index = try wasm.navFunctionIndex(datas[inst].nav_index);162 const func_index = Wasm.FunctionIndex.fromIpNav(wasm, datas[inst].nav_index).?;
162 leb.writeUleb128(code.fixedWriter(), @intFromEnum(func_index)) catch unreachable;163 leb.writeUleb128(code.fixedWriter(), function_imports_len + @intFromEnum(func_index)) catch unreachable;
163 }164 }
164165
165 inst += 1;166 inst += 1;
...@@ -199,8 +200,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -199,8 +200,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {
199 });200 });
200 code.appendNTimesAssumeCapacity(0, 5);201 code.appendNTimesAssumeCapacity(0, 5);
201 } else {202 } else {
202 const func_index = try wasm.tagNameFunctionIndex(datas[inst].ip_index);203 const func_index = Wasm.FunctionIndex.fromTagNameType(wasm, datas[inst].ip_index).?;
203 leb.writeUleb128(code.fixedWriter(), @intFromEnum(func_index)) catch unreachable;204 leb.writeUleb128(code.fixedWriter(), function_imports_len + @intFromEnum(func_index)) catch unreachable;
204 }205 }
205206
206 inst += 1;207 inst += 1;
...@@ -224,8 +225,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -224,8 +225,8 @@ pub fn lowerToCode(emit: *Emit) Error!void {
224 });225 });
225 code.appendNTimesAssumeCapacity(0, 5);226 code.appendNTimesAssumeCapacity(0, 5);
226 } else {227 } else {
227 const func_index = try wasm.symbolNameFunctionIndex(symbol_name);228 const func_index = Wasm.FunctionIndex.fromSymbolName(wasm, symbol_name).?;
228 leb.writeUleb128(code.fixedWriter(), @intFromEnum(func_index)) catch unreachable;229 leb.writeUleb128(code.fixedWriter(), function_imports_len + @intFromEnum(func_index)) catch unreachable;
229 }230 }
230231
231 inst += 1;232 inst += 1;
...@@ -282,7 +283,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -282,7 +283,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
282 try code.ensureUnusedCapacity(gpa, 11);283 try code.ensureUnusedCapacity(gpa, 11);
283 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_const));284 code.appendAssumeCapacity(@intFromEnum(std.wasm.Opcode.i64_const));
284 const int64: i64 = @bitCast(mir.extraData(Mir.Imm64, datas[inst].payload).data.toInt());285 const int64: i64 = @bitCast(mir.extraData(Mir.Imm64, datas[inst].payload).data.toInt());
285 leb.writeIleb128(code.writer(), int64) catch unreachable;286 leb.writeIleb128(code.fixedWriter(), int64) catch unreachable;
286287
287 inst += 1;288 inst += 1;
288 continue :loop tags[inst];289 continue :loop tags[inst];
...@@ -314,7 +315,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -314,7 +315,7 @@ pub fn lowerToCode(emit: *Emit) Error!void {
314 => {315 => {
315 try code.ensureUnusedCapacity(gpa, 1 + 20);316 try code.ensureUnusedCapacity(gpa, 1 + 20);
316 code.appendAssumeCapacity(@intFromEnum(tags[inst]));317 code.appendAssumeCapacity(@intFromEnum(tags[inst]));
317 encodeMemArg(code, mir.extraData(Mir.MemArg, datas[inst]).data);318 encodeMemArg(code, mir.extraData(Mir.MemArg, datas[inst].payload).data);
318 inst += 1;319 inst += 1;
319 continue :loop tags[inst];320 continue :loop tags[inst];
320 },321 },
...@@ -504,6 +505,13 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -504,6 +505,13 @@ pub fn lowerToCode(emit: *Emit) Error!void {
504 continue :loop tags[inst];505 continue :loop tags[inst];
505 },506 },
506507
508 .table_init => @panic("TODO"),
509 .elem_drop => @panic("TODO"),
510 .table_copy => @panic("TODO"),
511 .table_grow => @panic("TODO"),
512 .table_size => @panic("TODO"),
513 .table_fill => @panic("TODO"),
514
507 _ => unreachable,515 _ => unreachable,
508 }516 }
509 comptime unreachable;517 comptime unreachable;
...@@ -560,7 +568,236 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -560,7 +568,236 @@ pub fn lowerToCode(emit: *Emit) Error!void {
560 inst += 1;568 inst += 1;
561 continue :loop tags[inst];569 continue :loop tags[inst];
562 },570 },
563 _ => unreachable,571
572 .v128_load8x8_s => @panic("TODO"),
573 .v128_load8x8_u => @panic("TODO"),
574 .v128_load16x4_s => @panic("TODO"),
575 .v128_load16x4_u => @panic("TODO"),
576 .v128_load32x2_s => @panic("TODO"),
577 .v128_load32x2_u => @panic("TODO"),
578 .i8x16_swizzle => @panic("TODO"),
579 .i8x16_eq => @panic("TODO"),
580 .i16x8_eq => @panic("TODO"),
581 .i32x4_eq => @panic("TODO"),
582 .i8x16_ne => @panic("TODO"),
583 .i16x8_ne => @panic("TODO"),
584 .i32x4_ne => @panic("TODO"),
585 .i8x16_lt_s => @panic("TODO"),
586 .i16x8_lt_s => @panic("TODO"),
587 .i32x4_lt_s => @panic("TODO"),
588 .i8x16_lt_u => @panic("TODO"),
589 .i16x8_lt_u => @panic("TODO"),
590 .i32x4_lt_u => @panic("TODO"),
591 .i8x16_gt_s => @panic("TODO"),
592 .i16x8_gt_s => @panic("TODO"),
593 .i32x4_gt_s => @panic("TODO"),
594 .i8x16_gt_u => @panic("TODO"),
595 .i16x8_gt_u => @panic("TODO"),
596 .i32x4_gt_u => @panic("TODO"),
597 .i8x16_le_s => @panic("TODO"),
598 .i16x8_le_s => @panic("TODO"),
599 .i32x4_le_s => @panic("TODO"),
600 .i8x16_le_u => @panic("TODO"),
601 .i16x8_le_u => @panic("TODO"),
602 .i32x4_le_u => @panic("TODO"),
603 .i8x16_ge_s => @panic("TODO"),
604 .i16x8_ge_s => @panic("TODO"),
605 .i32x4_ge_s => @panic("TODO"),
606 .i8x16_ge_u => @panic("TODO"),
607 .i16x8_ge_u => @panic("TODO"),
608 .i32x4_ge_u => @panic("TODO"),
609 .f32x4_eq => @panic("TODO"),
610 .f64x2_eq => @panic("TODO"),
611 .f32x4_ne => @panic("TODO"),
612 .f64x2_ne => @panic("TODO"),
613 .f32x4_lt => @panic("TODO"),
614 .f64x2_lt => @panic("TODO"),
615 .f32x4_gt => @panic("TODO"),
616 .f64x2_gt => @panic("TODO"),
617 .f32x4_le => @panic("TODO"),
618 .f64x2_le => @panic("TODO"),
619 .f32x4_ge => @panic("TODO"),
620 .f64x2_ge => @panic("TODO"),
621 .v128_not => @panic("TODO"),
622 .v128_and => @panic("TODO"),
623 .v128_andnot => @panic("TODO"),
624 .v128_or => @panic("TODO"),
625 .v128_xor => @panic("TODO"),
626 .v128_bitselect => @panic("TODO"),
627 .v128_any_true => @panic("TODO"),
628 .v128_load8_lane => @panic("TODO"),
629 .v128_load16_lane => @panic("TODO"),
630 .v128_load32_lane => @panic("TODO"),
631 .v128_load64_lane => @panic("TODO"),
632 .v128_store8_lane => @panic("TODO"),
633 .v128_store16_lane => @panic("TODO"),
634 .v128_store32_lane => @panic("TODO"),
635 .v128_store64_lane => @panic("TODO"),
636 .v128_load32_zero => @panic("TODO"),
637 .v128_load64_zero => @panic("TODO"),
638 .f32x4_demote_f64x2_zero => @panic("TODO"),
639 .f64x2_promote_low_f32x4 => @panic("TODO"),
640 .i8x16_abs => @panic("TODO"),
641 .i16x8_abs => @panic("TODO"),
642 .i32x4_abs => @panic("TODO"),
643 .i64x2_abs => @panic("TODO"),
644 .i8x16_neg => @panic("TODO"),
645 .i16x8_neg => @panic("TODO"),
646 .i32x4_neg => @panic("TODO"),
647 .i64x2_neg => @panic("TODO"),
648 .i8x16_popcnt => @panic("TODO"),
649 .i16x8_q15mulr_sat_s => @panic("TODO"),
650 .i8x16_all_true => @panic("TODO"),
651 .i16x8_all_true => @panic("TODO"),
652 .i32x4_all_true => @panic("TODO"),
653 .i64x2_all_true => @panic("TODO"),
654 .i8x16_bitmask => @panic("TODO"),
655 .i16x8_bitmask => @panic("TODO"),
656 .i32x4_bitmask => @panic("TODO"),
657 .i64x2_bitmask => @panic("TODO"),
658 .i8x16_narrow_i16x8_s => @panic("TODO"),
659 .i16x8_narrow_i32x4_s => @panic("TODO"),
660 .i8x16_narrow_i16x8_u => @panic("TODO"),
661 .i16x8_narrow_i32x4_u => @panic("TODO"),
662 .f32x4_ceil => @panic("TODO"),
663 .i16x8_extend_low_i8x16_s => @panic("TODO"),
664 .i32x4_extend_low_i16x8_s => @panic("TODO"),
665 .i64x2_extend_low_i32x4_s => @panic("TODO"),
666 .f32x4_floor => @panic("TODO"),
667 .i16x8_extend_high_i8x16_s => @panic("TODO"),
668 .i32x4_extend_high_i16x8_s => @panic("TODO"),
669 .i64x2_extend_high_i32x4_s => @panic("TODO"),
670 .f32x4_trunc => @panic("TODO"),
671 .i16x8_extend_low_i8x16_u => @panic("TODO"),
672 .i32x4_extend_low_i16x8_u => @panic("TODO"),
673 .i64x2_extend_low_i32x4_u => @panic("TODO"),
674 .f32x4_nearest => @panic("TODO"),
675 .i16x8_extend_high_i8x16_u => @panic("TODO"),
676 .i32x4_extend_high_i16x8_u => @panic("TODO"),
677 .i64x2_extend_high_i32x4_u => @panic("TODO"),
678 .i8x16_shl => @panic("TODO"),
679 .i16x8_shl => @panic("TODO"),
680 .i32x4_shl => @panic("TODO"),
681 .i64x2_shl => @panic("TODO"),
682 .i8x16_shr_s => @panic("TODO"),
683 .i16x8_shr_s => @panic("TODO"),
684 .i32x4_shr_s => @panic("TODO"),
685 .i64x2_shr_s => @panic("TODO"),
686 .i8x16_shr_u => @panic("TODO"),
687 .i16x8_shr_u => @panic("TODO"),
688 .i32x4_shr_u => @panic("TODO"),
689 .i64x2_shr_u => @panic("TODO"),
690 .i8x16_add => @panic("TODO"),
691 .i16x8_add => @panic("TODO"),
692 .i32x4_add => @panic("TODO"),
693 .i64x2_add => @panic("TODO"),
694 .i8x16_add_sat_s => @panic("TODO"),
695 .i16x8_add_sat_s => @panic("TODO"),
696 .i8x16_add_sat_u => @panic("TODO"),
697 .i16x8_add_sat_u => @panic("TODO"),
698 .i8x16_sub => @panic("TODO"),
699 .i16x8_sub => @panic("TODO"),
700 .i32x4_sub => @panic("TODO"),
701 .i64x2_sub => @panic("TODO"),
702 .i8x16_sub_sat_s => @panic("TODO"),
703 .i16x8_sub_sat_s => @panic("TODO"),
704 .i8x16_sub_sat_u => @panic("TODO"),
705 .i16x8_sub_sat_u => @panic("TODO"),
706 .f64x2_ceil => @panic("TODO"),
707 .f64x2_nearest => @panic("TODO"),
708 .f64x2_floor => @panic("TODO"),
709 .i16x8_mul => @panic("TODO"),
710 .i32x4_mul => @panic("TODO"),
711 .i64x2_mul => @panic("TODO"),
712 .i8x16_min_s => @panic("TODO"),
713 .i16x8_min_s => @panic("TODO"),
714 .i32x4_min_s => @panic("TODO"),
715 .i64x2_eq => @panic("TODO"),
716 .i8x16_min_u => @panic("TODO"),
717 .i16x8_min_u => @panic("TODO"),
718 .i32x4_min_u => @panic("TODO"),
719 .i64x2_ne => @panic("TODO"),
720 .i8x16_max_s => @panic("TODO"),
721 .i16x8_max_s => @panic("TODO"),
722 .i32x4_max_s => @panic("TODO"),
723 .i64x2_lt_s => @panic("TODO"),
724 .i8x16_max_u => @panic("TODO"),
725 .i16x8_max_u => @panic("TODO"),
726 .i32x4_max_u => @panic("TODO"),
727 .i64x2_gt_s => @panic("TODO"),
728 .f64x2_trunc => @panic("TODO"),
729 .i32x4_dot_i16x8_s => @panic("TODO"),
730 .i64x2_le_s => @panic("TODO"),
731 .i8x16_avgr_u => @panic("TODO"),
732 .i16x8_avgr_u => @panic("TODO"),
733 .i64x2_ge_s => @panic("TODO"),
734 .i16x8_extadd_pairwise_i8x16_s => @panic("TODO"),
735 .i16x8_extmul_low_i8x16_s => @panic("TODO"),
736 .i32x4_extmul_low_i16x8_s => @panic("TODO"),
737 .i64x2_extmul_low_i32x4_s => @panic("TODO"),
738 .i16x8_extadd_pairwise_i8x16_u => @panic("TODO"),
739 .i16x8_extmul_high_i8x16_s => @panic("TODO"),
740 .i32x4_extmul_high_i16x8_s => @panic("TODO"),
741 .i64x2_extmul_high_i32x4_s => @panic("TODO"),
742 .i32x4_extadd_pairwise_i16x8_s => @panic("TODO"),
743 .i16x8_extmul_low_i8x16_u => @panic("TODO"),
744 .i32x4_extmul_low_i16x8_u => @panic("TODO"),
745 .i64x2_extmul_low_i32x4_u => @panic("TODO"),
746 .i32x4_extadd_pairwise_i16x8_u => @panic("TODO"),
747 .i16x8_extmul_high_i8x16_u => @panic("TODO"),
748 .i32x4_extmul_high_i16x8_u => @panic("TODO"),
749 .i64x2_extmul_high_i32x4_u => @panic("TODO"),
750 .f32x4_abs => @panic("TODO"),
751 .f64x2_abs => @panic("TODO"),
752 .f32x4_neg => @panic("TODO"),
753 .f64x2_neg => @panic("TODO"),
754 .f32x4_sqrt => @panic("TODO"),
755 .f64x2_sqrt => @panic("TODO"),
756 .f32x4_add => @panic("TODO"),
757 .f64x2_add => @panic("TODO"),
758 .f32x4_sub => @panic("TODO"),
759 .f64x2_sub => @panic("TODO"),
760 .f32x4_mul => @panic("TODO"),
761 .f64x2_mul => @panic("TODO"),
762 .f32x4_div => @panic("TODO"),
763 .f64x2_div => @panic("TODO"),
764 .f32x4_min => @panic("TODO"),
765 .f64x2_min => @panic("TODO"),
766 .f32x4_max => @panic("TODO"),
767 .f64x2_max => @panic("TODO"),
768 .f32x4_pmin => @panic("TODO"),
769 .f64x2_pmin => @panic("TODO"),
770 .f32x4_pmax => @panic("TODO"),
771 .f64x2_pmax => @panic("TODO"),
772 .i32x4_trunc_sat_f32x4_s => @panic("TODO"),
773 .i32x4_trunc_sat_f32x4_u => @panic("TODO"),
774 .f32x4_convert_i32x4_s => @panic("TODO"),
775 .f32x4_convert_i32x4_u => @panic("TODO"),
776 .i32x4_trunc_sat_f64x2_s_zero => @panic("TODO"),
777 .i32x4_trunc_sat_f64x2_u_zero => @panic("TODO"),
778 .f64x2_convert_low_i32x4_s => @panic("TODO"),
779 .f64x2_convert_low_i32x4_u => @panic("TODO"),
780 .i8x16_relaxed_swizzle => @panic("TODO"),
781 .i32x4_relaxed_trunc_f32x4_s => @panic("TODO"),
782 .i32x4_relaxed_trunc_f32x4_u => @panic("TODO"),
783 .i32x4_relaxed_trunc_f64x2_s_zero => @panic("TODO"),
784 .i32x4_relaxed_trunc_f64x2_u_zero => @panic("TODO"),
785 .f32x4_relaxed_madd => @panic("TODO"),
786 .f32x4_relaxed_nmadd => @panic("TODO"),
787 .f64x2_relaxed_madd => @panic("TODO"),
788 .f64x2_relaxed_nmadd => @panic("TODO"),
789 .i8x16_relaxed_laneselect => @panic("TODO"),
790 .i16x8_relaxed_laneselect => @panic("TODO"),
791 .i32x4_relaxed_laneselect => @panic("TODO"),
792 .i64x2_relaxed_laneselect => @panic("TODO"),
793 .f32x4_relaxed_min => @panic("TODO"),
794 .f32x4_relaxed_max => @panic("TODO"),
795 .f64x2_relaxed_min => @panic("TODO"),
796 .f64x2_relaxed_max => @panic("TODO"),
797 .i16x8_relaxed_q15mulr_s => @panic("TODO"),
798 .i16x8_relaxed_dot_i8x16_i7x16_s => @panic("TODO"),
799 .i32x4_relaxed_dot_i8x16_i7x16_add_s => @panic("TODO"),
800 .f32x4_relaxed_dot_bf16x8_add_f32x4 => @panic("TODO"),
564 }801 }
565 comptime unreachable;802 comptime unreachable;
566 },803 },
...@@ -650,6 +887,9 @@ pub fn lowerToCode(emit: *Emit) Error!void {...@@ -650,6 +887,9 @@ pub fn lowerToCode(emit: *Emit) Error!void {
650 inst += 1;887 inst += 1;
651 continue :loop tags[inst];888 continue :loop tags[inst];
652 },889 },
890 .memory_atomic_notify => @panic("TODO"),
891 .memory_atomic_wait32 => @panic("TODO"),
892 .memory_atomic_wait64 => @panic("TODO"),
653 }893 }
654 comptime unreachable;894 comptime unreachable;
655 },895 },
src/link/Wasm.zig+58-14
...@@ -291,6 +291,16 @@ pub const FunctionIndex = enum(u32) {...@@ -291,6 +291,16 @@ pub const FunctionIndex = enum(u32) {
291 return fromResolution(wasm, .fromIpNav(wasm, nav_index));291 return fromResolution(wasm, .fromIpNav(wasm, nav_index));
292 }292 }
293293
294 pub fn fromTagNameType(wasm: *const Wasm, tag_type: InternPool.Index) ?FunctionIndex {
295 const zcu_func: ZcuFunc.Index = @enumFromInt(wasm.zcu_funcs.getIndex(tag_type) orelse return null);
296 return fromResolution(wasm, .pack(wasm, .{ .zcu_func = zcu_func }));
297 }
298
299 pub fn fromSymbolName(wasm: *const Wasm, name: String) ?FunctionIndex {
300 const import = wasm.object_function_imports.getPtr(name) orelse return null;
301 return fromResolution(wasm, import.resolution);
302 }
303
294 pub fn fromResolution(wasm: *const Wasm, resolution: FunctionImport.Resolution) ?FunctionIndex {304 pub fn fromResolution(wasm: *const Wasm, resolution: FunctionImport.Resolution) ?FunctionIndex {
295 const i = wasm.functions.getIndex(resolution) orelse return null;305 const i = wasm.functions.getIndex(resolution) orelse return null;
296 return @enumFromInt(i);306 return @enumFromInt(i);
...@@ -749,15 +759,14 @@ pub const FunctionImport = extern struct {...@@ -749,15 +759,14 @@ pub const FunctionImport = extern struct {
749 .__wasm_init_tls => .__wasm_init_tls,759 .__wasm_init_tls => .__wasm_init_tls,
750 .__zig_error_names => .__zig_error_names,760 .__zig_error_names => .__zig_error_names,
751 _ => {761 _ => {
752 const i: u32 = @intFromEnum(r);762 const object_function_index = @intFromEnum(r) - first_object_function;
753 const object_function_index = i - first_object_function;763
754 if (object_function_index < wasm.object_functions.items.len) {764 const zcu_func_index = if (object_function_index < wasm.object_functions.items.len)
755 return .{ .object_function = @enumFromInt(object_function_index) };765 return .{ .object_function = @enumFromInt(object_function_index) }
756 } else {766 else
757 return .{767 object_function_index - wasm.object_functions.items.len;
758 .zcu_func = @enumFromInt(object_function_index - wasm.object_functions.items.len),768
759 };769 return .{ .zcu_func = @enumFromInt(zcu_func_index) };
760 }
761 },770 },
762 };771 };
763 }772 }
...@@ -1281,7 +1290,7 @@ pub const DataSegment = extern struct {...@@ -1281,7 +1290,7 @@ pub const DataSegment = extern struct {
1281 return .{ .nav_obj = @enumFromInt(nav_index) };1290 return .{ .nav_obj = @enumFromInt(nav_index) };
1282 } else {1291 } else {
1283 const nav_index = if (uav_index < wasm.uavs_exe.entries.len)1292 const nav_index = if (uav_index < wasm.uavs_exe.entries.len)
1284 return .{ .uav_obj = @enumFromInt(uav_index) }1293 return .{ .uav_exe = @enumFromInt(uav_index) }
1285 else1294 else
1286 uav_index - wasm.uavs_exe.entries.len;1295 uav_index - wasm.uavs_exe.entries.len;
12871296
...@@ -1297,7 +1306,7 @@ pub const DataSegment = extern struct {...@@ -1297,7 +1306,7 @@ pub const DataSegment = extern struct {
1297 .object => |i| {1306 .object => |i| {
1298 const ptr = i.ptr(wasm);1307 const ptr = i.ptr(wasm);
1299 if (ptr.flags.tls) return .tls;1308 if (ptr.flags.tls) return .tls;
1300 if (isBss(wasm, ptr.name)) return .zero;1309 if (wasm.isBss(ptr.name)) return .zero;
1301 return .data;1310 return .data;
1302 },1311 },
1303 inline .uav_exe, .uav_obj => |i| if (i.value(wasm).code.off == .none) .zero else .data,1312 inline .uav_exe, .uav_obj => |i| if (i.value(wasm).code.off == .none) .zero else .data,
...@@ -1326,6 +1335,10 @@ pub const DataSegment = extern struct {...@@ -1326,6 +1335,10 @@ pub const DataSegment = extern struct {
1326 };1335 };
1327 }1336 }
13281337
1338 pub fn isBss(id: Id, wasm: *const Wasm) bool {
1339 return id.category(wasm) == .zero;
1340 }
1341
1329 pub fn name(id: Id, wasm: *const Wasm) []const u8 {1342 pub fn name(id: Id, wasm: *const Wasm) []const u8 {
1330 return switch (unpack(id, wasm)) {1343 return switch (unpack(id, wasm)) {
1331 .__zig_error_name_table, .uav_exe, .uav_obj => ".data",1344 .__zig_error_name_table, .uav_exe, .uav_obj => ".data",
...@@ -1368,10 +1381,11 @@ pub const DataSegment = extern struct {...@@ -1368,10 +1381,11 @@ pub const DataSegment = extern struct {
1368 }1381 }
13691382
1370 pub fn isPassive(id: Id, wasm: *const Wasm) bool {1383 pub fn isPassive(id: Id, wasm: *const Wasm) bool {
1384 if (wasm.base.comp.config.import_memory and !id.isBss(wasm)) return true;
1371 return switch (unpack(id, wasm)) {1385 return switch (unpack(id, wasm)) {
1372 .__zig_error_name_table => true,1386 .__zig_error_name_table => false,
1373 .object => |i| i.ptr(wasm).flags.is_passive,1387 .object => |i| i.ptr(wasm).flags.is_passive,
1374 .uav_exe, .uav_obj, .nav_exe, .nav_obj => true,1388 .uav_exe, .uav_obj, .nav_exe, .nav_obj => false,
1375 };1389 };
1376 }1390 }
13771391
...@@ -3226,6 +3240,7 @@ pub fn uavSymbolIndex(wasm: *Wasm, ip_index: InternPool.Index) Allocator.Error!S...@@ -3226,6 +3240,7 @@ pub fn uavSymbolIndex(wasm: *Wasm, ip_index: InternPool.Index) Allocator.Error!S
3226 const gpa = comp.gpa;3240 const gpa = comp.gpa;
3227 const name = try wasm.internStringFmt("__anon_{d}", .{@intFromEnum(ip_index)});3241 const name = try wasm.internStringFmt("__anon_{d}", .{@intFromEnum(ip_index)});
3228 const gop = try wasm.symbol_table.getOrPut(gpa, name);3242 const gop = try wasm.symbol_table.getOrPut(gpa, name);
3243 gop.value_ptr.* = {};
3229 return @enumFromInt(gop.index);3244 return @enumFromInt(gop.index);
3230}3245}
32313246
...@@ -3238,6 +3253,7 @@ pub fn navSymbolIndex(wasm: *Wasm, nav_index: InternPool.Nav.Index) Allocator.Er...@@ -3238,6 +3253,7 @@ pub fn navSymbolIndex(wasm: *Wasm, nav_index: InternPool.Nav.Index) Allocator.Er
3238 const nav = ip.getNav(nav_index);3253 const nav = ip.getNav(nav_index);
3239 const name = try wasm.internString(nav.fqn.toSlice(ip));3254 const name = try wasm.internString(nav.fqn.toSlice(ip));
3240 const gop = try wasm.symbol_table.getOrPut(gpa, name);3255 const gop = try wasm.symbol_table.getOrPut(gpa, name);
3256 gop.value_ptr.* = {};
3241 return @enumFromInt(gop.index);3257 return @enumFromInt(gop.index);
3242}3258}
32433259
...@@ -3250,6 +3266,34 @@ pub fn errorNameTableSymbolIndex(wasm: *Wasm) Allocator.Error!SymbolTableIndex {...@@ -3250,6 +3266,34 @@ pub fn errorNameTableSymbolIndex(wasm: *Wasm) Allocator.Error!SymbolTableIndex {
3250 return @enumFromInt(gop.index);3266 return @enumFromInt(gop.index);
3251}3267}
32523268
3269pub fn stackPointerSymbolIndex(wasm: *Wasm) Allocator.Error!SymbolTableIndex {
3270 const comp = wasm.base.comp;
3271 assert(comp.config.output_mode == .Obj);
3272 const gpa = comp.gpa;
3273 const gop = try wasm.symbol_table.getOrPut(gpa, wasm.preloaded_strings.__stack_pointer);
3274 gop.value_ptr.* = {};
3275 return @enumFromInt(gop.index);
3276}
3277
3278pub fn tagNameSymbolIndex(wasm: *Wasm, ip_index: InternPool.Index) Allocator.Error!SymbolTableIndex {
3279 const comp = wasm.base.comp;
3280 assert(comp.config.output_mode == .Obj);
3281 const gpa = comp.gpa;
3282 const name = try wasm.internStringFmt("__zig_tag_name_{d}", .{@intFromEnum(ip_index)});
3283 const gop = try wasm.symbol_table.getOrPut(gpa, name);
3284 gop.value_ptr.* = {};
3285 return @enumFromInt(gop.index);
3286}
3287
3288pub fn symbolNameIndex(wasm: *Wasm, name: String) Allocator.Error!SymbolTableIndex {
3289 const comp = wasm.base.comp;
3290 assert(comp.config.output_mode == .Obj);
3291 const gpa = comp.gpa;
3292 const gop = try wasm.symbol_table.getOrPut(gpa, name);
3293 gop.value_ptr.* = {};
3294 return @enumFromInt(gop.index);
3295}
3296
3253pub fn refUavObj(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !UavsObjIndex {3297pub fn refUavObj(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !UavsObjIndex {
3254 const comp = wasm.base.comp;3298 const comp = wasm.base.comp;
3255 const gpa = comp.gpa;3299 const gpa = comp.gpa;
...@@ -3276,7 +3320,7 @@ pub fn refUavExe(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Ua...@@ -3276,7 +3320,7 @@ pub fn refUavExe(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Ua
3276 };3320 };
3277 }3321 }
3278 const uav_index: UavsExeIndex = @enumFromInt(gop.index);3322 const uav_index: UavsExeIndex = @enumFromInt(gop.index);
3279 wasm.data_segments.putAssumeCapacity(.pack(wasm, .{ .uav_exe = uav_index }), @as(u32, undefined));3323 try wasm.data_segments.put(gpa, .pack(wasm, .{ .uav_exe = uav_index }), @as(u32, undefined));
3280 return uav_index;3324 return uav_index;
3281}3325}
32823326
src/link/Wasm/Flush.zig+19-9
...@@ -643,10 +643,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -643,10 +643,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
643 var group_index: u32 = 0;643 var group_index: u32 = 0;
644 var offset: u32 = undefined;644 var offset: u32 = undefined;
645 for (segment_ids, segment_offsets) |segment_id, segment_offset| {645 for (segment_ids, segment_offsets) |segment_id, segment_offset| {
646 const segment = segment_id.ptr(wasm);646 if (!import_memory and segment_id.isBss(wasm)) {
647 const segment_payload = segment.payload.slice(wasm);
648 if (segment_payload.len == 0) continue;
649 if (!import_memory and wasm.isBss(segment.name)) {
650 // It counted for virtual memory but it does not go into the binary.647 // It counted for virtual memory but it does not go into the binary.
651 continue;648 continue;
652 }649 }
...@@ -655,7 +652,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -655,7 +652,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
655 group_index += 1;652 group_index += 1;
656 offset = 0;653 offset = 0;
657654
658 const flags: Object.DataSegmentFlags = if (segment.flags.is_passive) .passive else .active;655 const flags: Object.DataSegmentFlags = if (segment_id.isPassive(wasm)) .passive else .active;
659 try leb.writeUleb128(binary_writer, @intFromEnum(flags));656 try leb.writeUleb128(binary_writer, @intFromEnum(flags));
660 // when a segment is passive, it's initialized during runtime.657 // when a segment is passive, it's initialized during runtime.
661 if (flags != .passive) {658 if (flags != .passive) {
...@@ -666,8 +663,21 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -666,8 +663,21 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
666663
667 try binary_bytes.appendNTimes(gpa, 0, segment_offset - offset);664 try binary_bytes.appendNTimes(gpa, 0, segment_offset - offset);
668 offset = segment_offset;665 offset = segment_offset;
669 try binary_bytes.appendSlice(gpa, segment_payload);666
670 offset += @intCast(segment_payload.len);667 const code_start = binary_bytes.items.len;
668 append: {
669 const code = switch (segment_id.unpack(wasm)) {
670 .__zig_error_name_table => {
671 if (true) @panic("TODO lower zig error name table");
672 break :append;
673 },
674 .object => |i| i.ptr(wasm).payload,
675 inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code,
676 };
677 try binary_bytes.appendSlice(gpa, code.slice(wasm));
678 }
679 offset += @intCast(binary_bytes.items.len - code_start);
680
671 if (true) @panic("TODO apply data segment relocations");681 if (true) @panic("TODO apply data segment relocations");
672 }682 }
673 assert(group_index == f.data_segment_groups.items.len);683 assert(group_index == f.data_segment_groups.items.len);
...@@ -738,7 +748,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {...@@ -738,7 +748,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
738748
739fn emitNameSection(749fn emitNameSection(
740 wasm: *Wasm,750 wasm: *Wasm,
741 data_segments: *const std.AutoArrayHashMapUnmanaged(Wasm.DataSegment.Index, u32),751 data_segments: *const std.AutoArrayHashMapUnmanaged(Wasm.DataSegment.Id, u32),
742 binary_bytes: *std.ArrayListUnmanaged(u8),752 binary_bytes: *std.ArrayListUnmanaged(u8),
743) !void {753) !void {
744 const comp = wasm.base.comp;754 const comp = wasm.base.comp;
...@@ -801,7 +811,7 @@ fn emitNameSection(...@@ -801,7 +811,7 @@ fn emitNameSection(
801 try leb.writeUleb128(binary_bytes.writer(gpa), total_globals);811 try leb.writeUleb128(binary_bytes.writer(gpa), total_globals);
802812
803 for (data_segments.keys(), 0..) |ds, i| {813 for (data_segments.keys(), 0..) |ds, i| {
804 const name = ds.ptr(wasm).name.slice(wasm).?;814 const name = ds.name(wasm);
805 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(i)));815 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(i)));
806 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len)));816 try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len)));
807 try binary_bytes.appendSlice(gpa, name);817 try binary_bytes.appendSlice(gpa, name);