| ... | @@ -1255,6 +1255,9 @@ fn parseAtom(self: *Wasm, atom: *Atom, kind: Kind) !void { | ... | @@ -1255,6 +1255,9 @@ fn parseAtom(self: *Wasm, atom: *Atom, kind: Kind) !void { |
| 1255 | } | 1255 | } |
| 1256 | | 1256 | |
| 1257 | fn allocateAtoms(self: *Wasm) !void { | 1257 | fn allocateAtoms(self: *Wasm) !void { |
| | 1258 | // first sort the data segments |
| | 1259 | try sortDataSegments(self); |
| | 1260 | |
| 1258 | var it = self.atoms.iterator(); | 1261 | var it = self.atoms.iterator(); |
| 1259 | while (it.next()) |entry| { | 1262 | while (it.next()) |entry| { |
| 1260 | const segment = &self.segments.items[entry.key_ptr.*]; | 1263 | const segment = &self.segments.items[entry.key_ptr.*]; |
| ... | @@ -1278,6 +1281,36 @@ fn allocateAtoms(self: *Wasm) !void { | ... | @@ -1278,6 +1281,36 @@ fn allocateAtoms(self: *Wasm) !void { |
| 1278 | } | 1281 | } |
| 1279 | } | 1282 | } |
| 1280 | | 1283 | |
| | 1284 | fn sortDataSegments(self: *Wasm) !void { |
| | 1285 | var new_mapping: std.StringArrayHashMapUnmanaged(u32) = .{}; |
| | 1286 | try new_mapping.ensureUnusedCapacity(self.base.allocator, self.data_segments.count()); |
| | 1287 | errdefer new_mapping.deinit(self.base.allocator); |
| | 1288 | |
| | 1289 | const keys = try self.base.allocator.dupe([]const u8, self.data_segments.keys()); |
| | 1290 | defer self.base.allocator.free(keys); |
| | 1291 | |
| | 1292 | const SortContext = struct { |
| | 1293 | fn sort(_: void, lhs: []const u8, rhs: []const u8) bool { |
| | 1294 | return order(lhs) <= order(rhs); |
| | 1295 | } |
| | 1296 | |
| | 1297 | fn order(name: []const u8) u8 { |
| | 1298 | if (mem.startsWith(u8, name, ".rodata")) return 0; |
| | 1299 | if (mem.startsWith(u8, name, ".data")) return 1; |
| | 1300 | if (mem.startsWith(u8, name, ".text")) return 2; |
| | 1301 | return 3; |
| | 1302 | } |
| | 1303 | }; |
| | 1304 | |
| | 1305 | std.sort.sort([]const u8, keys, {}, SortContext.sort); |
| | 1306 | for (keys) |key| { |
| | 1307 | const segment_index = self.data_segments.get(key).?; |
| | 1308 | new_mapping.putAssumeCapacity(key, segment_index); |
| | 1309 | } |
| | 1310 | self.data_segments.deinit(self.base.allocator); |
| | 1311 | self.data_segments = new_mapping; |
| | 1312 | } |
| | 1313 | |
| 1281 | fn setupImports(self: *Wasm) !void { | 1314 | fn setupImports(self: *Wasm) !void { |
| 1282 | log.debug("Merging imports", .{}); | 1315 | log.debug("Merging imports", .{}); |
| 1283 | var discarded_it = self.discarded.keyIterator(); | 1316 | var discarded_it = self.discarded.keyIterator(); |
| ... | @@ -2337,8 +2370,13 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void { | ... | @@ -2337,8 +2370,13 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void { |
| 2337 | } | 2370 | } |
| 2338 | } | 2371 | } |
| 2339 | // data segments are already 'ordered' | 2372 | // data segments are already 'ordered' |
| 2340 | for (self.data_segments.keys()) |key, index| { | 2373 | var data_segment_index: u32 = 0; |
| 2341 | segments.appendAssumeCapacity(.{ .index = @intCast(u32, index), .name = key }); | 2374 | for (self.data_segments.keys()) |key| { |
| | 2375 | // bss section is not emitted when this condition holds true, so we also |
| | 2376 | // do not output a name for it. |
| | 2377 | if (!self.base.options.import_memory and std.mem.eql(u8, key, ".bss")) continue; |
| | 2378 | segments.appendAssumeCapacity(.{ .index = data_segment_index, .name = key }); |
| | 2379 | data_segment_index += 1; |
| 2342 | } | 2380 | } |
| 2343 | | 2381 | |
| 2344 | std.sort.sort(Name, funcs.values(), {}, Name.lessThan); | 2382 | std.sort.sort(Name, funcs.values(), {}, Name.lessThan); |