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