| ... | @@ -122,45 +122,71 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -122,45 +122,71 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 122 | | 122 | |
| 123 | const entry_name = if (wasm.entry_resolution.isNavOrUnresolved(wasm)) wasm.entry_name else .none; | 123 | const entry_name = if (wasm.entry_resolution.isNavOrUnresolved(wasm)) wasm.entry_name else .none; |
| 124 | | 124 | |
| 125 | // Detect any intrinsics that were called; they need to have dependencies on the symbols marked. | 125 | if (comp.zcu) |zcu| { |
| 126 | // Likewise detect `@tagName` calls so those functions can be included in the output and synthesized. | 126 | const ip: *const InternPool = &zcu.intern_pool; // No mutations allowed! |
| 127 | for (wasm.mir_instructions.items(.tag), wasm.mir_instructions.items(.data)) |tag, *data| switch (tag) { | 127 | |
| 128 | .call_intrinsic => { | 128 | // Detect any intrinsics that were called; they need to have dependencies on the symbols marked. |
| 129 | const symbol_name = try wasm.internString(@tagName(data.intrinsic)); | 129 | // Likewise detect `@tagName` calls so those functions can be included in the output and synthesized. |
| 130 | const i: Wasm.FunctionImport.Index = @enumFromInt(wasm.object_function_imports.getIndex(symbol_name) orelse { | 130 | for (wasm.mir_instructions.items(.tag), wasm.mir_instructions.items(.data)) |tag, *data| switch (tag) { |
| 131 | return diags.fail("missing compiler runtime intrinsic '{s}' (undefined linker symbol)", .{ | 131 | .call_intrinsic => { |
| 132 | @tagName(data.intrinsic), | 132 | const symbol_name = try wasm.internString(@tagName(data.intrinsic)); |
| | 133 | const i: Wasm.FunctionImport.Index = @enumFromInt(wasm.object_function_imports.getIndex(symbol_name) orelse { |
| | 134 | return diags.fail("missing compiler runtime intrinsic '{s}' (undefined linker symbol)", .{ |
| | 135 | @tagName(data.intrinsic), |
| | 136 | }); |
| 133 | }); | 137 | }); |
| 134 | }); | 138 | try wasm.markFunctionImport(symbol_name, i.value(wasm), i); |
| 135 | try wasm.markFunctionImport(symbol_name, i.value(wasm), i); | 139 | }, |
| 136 | }, | 140 | .call_tag_name => { |
| 137 | .call_tag_name => { | 141 | assert(ip.indexToKey(data.ip_index) == .enum_type); |
| 138 | const zcu = comp.zcu.?; | 142 | const gop = try wasm.zcu_funcs.getOrPut(gpa, data.ip_index); |
| 139 | const ip = &zcu.intern_pool; | 143 | if (!gop.found_existing) { |
| 140 | assert(ip.indexToKey(data.ip_index) == .enum_type); | 144 | wasm.tag_name_table_ref_count += 1; |
| 141 | const gop = try wasm.zcu_funcs.getOrPut(gpa, data.ip_index); | 145 | const int_tag_ty = Zcu.Type.fromInterned(data.ip_index).intTagType(zcu); |
| 142 | if (!gop.found_existing) { | 146 | gop.value_ptr.* = .{ .tag_name = .{ |
| 143 | wasm.tag_name_table_ref_count += 1; | 147 | .symbol_name = try wasm.internStringFmt("__zig_tag_name_{d}", .{@intFromEnum(data.ip_index)}), |
| 144 | const int_tag_ty = Zcu.Type.fromInterned(data.ip_index).intTagType(zcu); | 148 | .type_index = try wasm.internFunctionType(.Unspecified, &.{int_tag_ty.ip_index}, .slice_const_u8_sentinel_0, target), |
| 145 | gop.value_ptr.* = .{ .tag_name = .{ | 149 | .table_index = @intCast(wasm.tag_name_offs.items.len), |
| 146 | .symbol_name = try wasm.internStringFmt("__zig_tag_name_{d}", .{@intFromEnum(data.ip_index)}), | 150 | } }; |
| 147 | .type_index = try wasm.internFunctionType(.Unspecified, &.{int_tag_ty.ip_index}, .slice_const_u8_sentinel_0, target), | 151 | try wasm.functions.put(gpa, .fromZcuFunc(wasm, @enumFromInt(gop.index)), {}); |
| 148 | .table_index = @intCast(wasm.tag_name_offs.items.len), | 152 | const tag_names = ip.loadEnumType(data.ip_index).names; |
| 149 | } }; | 153 | for (tag_names.get(ip)) |tag_name| { |
| 150 | try wasm.functions.put(gpa, .fromZcuFunc(wasm, @enumFromInt(gop.index)), {}); | 154 | const slice = tag_name.toSlice(ip); |
| 151 | const tag_names = ip.loadEnumType(data.ip_index).names; | 155 | try wasm.tag_name_offs.append(gpa, @intCast(wasm.tag_name_bytes.items.len)); |
| 152 | for (tag_names.get(ip)) |tag_name| { | 156 | try wasm.tag_name_bytes.appendSlice(gpa, slice[0 .. slice.len + 1]); |
| 153 | const slice = tag_name.toSlice(ip); | 157 | } |
| 154 | try wasm.tag_name_offs.append(gpa, @intCast(wasm.tag_name_bytes.items.len)); | | |
| 155 | try wasm.tag_name_bytes.appendSlice(gpa, slice[0 .. slice.len + 1]); | | |
| 156 | } | 158 | } |
| | 159 | }, |
| | 160 | else => continue, |
| | 161 | }; |
| | 162 | |
| | 163 | { |
| | 164 | var i = wasm.function_imports_len_prelink; |
| | 165 | while (i < f.function_imports.entries.len) { |
| | 166 | const symbol_name = f.function_imports.keys()[i]; |
| | 167 | if (wasm.object_function_imports.getIndex(symbol_name)) |import_index_usize| { |
| | 168 | const import_index: Wasm.FunctionImport.Index = @enumFromInt(import_index_usize); |
| | 169 | try wasm.markFunctionImport(symbol_name, import_index.value(wasm), import_index); |
| | 170 | f.function_imports.swapRemoveAt(i); |
| | 171 | continue; |
| | 172 | } |
| | 173 | i += 1; |
| 157 | } | 174 | } |
| 158 | }, | 175 | } |
| 159 | else => continue, | | |
| 160 | }; | | |
| 161 | | 176 | |
| 162 | if (comp.zcu) |zcu| { | 177 | { |
| 163 | const ip: *const InternPool = &zcu.intern_pool; // No mutations allowed! | 178 | var i = wasm.data_imports_len_prelink; |
| | 179 | while (i < f.data_imports.entries.len) { |
| | 180 | const symbol_name = f.data_imports.keys()[i]; |
| | 181 | if (wasm.object_data_imports.getIndex(symbol_name)) |import_index_usize| { |
| | 182 | const import_index: Wasm.ObjectDataImport.Index = @enumFromInt(import_index_usize); |
| | 183 | try wasm.markDataImport(symbol_name, import_index.value(wasm), import_index); |
| | 184 | f.data_imports.swapRemoveAt(i); |
| | 185 | continue; |
| | 186 | } |
| | 187 | i += 1; |
| | 188 | } |
| | 189 | } |
| 164 | | 190 | |
| 165 | if (wasm.error_name_table_ref_count > 0) { | 191 | if (wasm.error_name_table_ref_count > 0) { |
| 166 | // Ensure Zcu error name structures are populated. | 192 | // Ensure Zcu error name structures are populated. |
| ... | @@ -437,7 +463,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -437,7 +463,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 437 | break :b i >= 1 and !wantSegmentMerge(wasm, segment_ids[i - 1], segment_id, category); | 463 | break :b i >= 1 and !wantSegmentMerge(wasm, segment_ids[i - 1], segment_id, category); |
| 438 | }; | 464 | }; |
| 439 | if (want_new_segment) { | 465 | if (want_new_segment) { |
| 440 | log.debug("new segment at 0x{x} {} {s} {}", .{ start_addr, segment_id, segment_id.name(wasm), category }); | 466 | log.debug("new segment group at 0x{x} {} {s} {}", .{ start_addr, segment_id, segment_id.name(wasm), category }); |
| 441 | try f.data_segment_groups.append(gpa, .{ | 467 | try f.data_segment_groups.append(gpa, .{ |
| 442 | .end_addr = @intCast(memory_ptr), | 468 | .end_addr = @intCast(memory_ptr), |
| 443 | .first_segment = first_segment, | 469 | .first_segment = first_segment, |
| ... | @@ -447,6 +473,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -447,6 +473,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 447 | | 473 | |
| 448 | const size = segment_id.size(wasm); | 474 | const size = segment_id.size(wasm); |
| 449 | segment_vaddr.* = @intCast(start_addr); | 475 | segment_vaddr.* = @intCast(start_addr); |
| | 476 | log.debug("0x{x} {d} {s}", .{ start_addr, @intFromEnum(segment_id), segment_id.name(wasm) }); |
| 450 | memory_ptr = start_addr + size; | 477 | memory_ptr = start_addr + size; |
| 451 | } | 478 | } |
| 452 | if (category != .zero) try f.data_segment_groups.append(gpa, .{ | 479 | if (category != .zero) try f.data_segment_groups.append(gpa, .{ |