| ... | @@ -76,7 +76,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -76,7 +76,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 76 | .function_index = Wasm.FunctionIndex.fromIpNav(wasm, nav_export.nav_index).?, | 76 | .function_index = Wasm.FunctionIndex.fromIpNav(wasm, nav_export.nav_index).?, |
| 77 | }); | 77 | }); |
| 78 | _ = f.missing_exports.swapRemove(nav_export.name); | 78 | _ = f.missing_exports.swapRemove(nav_export.name); |
| 79 | _ = wasm.function_imports.swapRemove(nav_export.name); | 79 | _ = f.function_imports.swapRemove(nav_export.name); |
| 80 | | 80 | |
| 81 | if (nav_export.name.toOptional() == entry_name) | 81 | if (nav_export.name.toOptional() == entry_name) |
| 82 | wasm.entry_resolution = .fromIpNav(wasm, nav_export.nav_index); | 82 | wasm.entry_resolution = .fromIpNav(wasm, nav_export.nav_index); |
| ... | @@ -86,7 +86,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -86,7 +86,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 86 | .global_index = Wasm.GlobalIndex.fromIpNav(wasm, nav_export.nav_index).?, | 86 | .global_index = Wasm.GlobalIndex.fromIpNav(wasm, nav_export.nav_index).?, |
| 87 | }); | 87 | }); |
| 88 | _ = f.missing_exports.swapRemove(nav_export.name); | 88 | _ = f.missing_exports.swapRemove(nav_export.name); |
| 89 | _ = wasm.global_imports.swapRemove(nav_export.name); | 89 | _ = f.global_imports.swapRemove(nav_export.name); |
| 90 | } | 90 | } |
| 91 | } | 91 | } |
| 92 | | 92 | |
| ... | @@ -104,11 +104,11 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -104,11 +104,11 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 104 | } | 104 | } |
| 105 | | 105 | |
| 106 | if (!allow_undefined) { | 106 | if (!allow_undefined) { |
| 107 | for (wasm.function_imports.keys(), wasm.function_imports.values()) |name, function_import_id| { | 107 | for (f.function_imports.keys(), f.function_imports.values()) |name, function_import_id| { |
| 108 | const src_loc = function_import_id.sourceLocation(wasm); | 108 | const src_loc = function_import_id.sourceLocation(wasm); |
| 109 | src_loc.addError(wasm, "undefined function: {s}", .{name.slice(wasm)}); | 109 | src_loc.addError(wasm, "undefined function: {s}", .{name.slice(wasm)}); |
| 110 | } | 110 | } |
| 111 | for (wasm.global_imports.keys(), wasm.global_imports.values()) |name, global_import_id| { | 111 | for (f.global_imports.keys(), f.global_imports.values()) |name, global_import_id| { |
| 112 | const src_loc = global_import_id.sourceLocation(wasm); | 112 | const src_loc = global_import_id.sourceLocation(wasm); |
| 113 | src_loc.addError(wasm, "undefined global: {s}", .{name.slice(wasm)}); | 113 | src_loc.addError(wasm, "undefined global: {s}", .{name.slice(wasm)}); |
| 114 | } | 114 | } |
| ... | @@ -391,12 +391,18 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -391,12 +391,18 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 391 | section_index += 1; | 391 | section_index += 1; |
| 392 | } | 392 | } |
| 393 | | 393 | |
| | 394 | if (!is_obj) { |
| | 395 | // TODO: sort function_imports by ref count descending for optimal LEB encodings |
| | 396 | // TODO: sort global_imports by ref count descending for optimal LEB encodings |
| | 397 | // TODO: sort output functions by ref count descending for optimal LEB encodings |
| | 398 | } |
| | 399 | |
| 394 | // Import section | 400 | // Import section |
| 395 | { | 401 | { |
| 396 | var total_imports: usize = 0; | 402 | var total_imports: usize = 0; |
| 397 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 403 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 398 | | 404 | |
| 399 | for (wasm.function_imports.values()) |id| { | 405 | for (f.function_imports.values()) |id| { |
| 400 | const module_name = id.moduleName(wasm).slice(wasm); | 406 | const module_name = id.moduleName(wasm).slice(wasm); |
| 401 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(module_name.len))); | 407 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(module_name.len))); |
| 402 | try binary_writer.writeAll(module_name); | 408 | try binary_writer.writeAll(module_name); |
| ... | @@ -408,7 +414,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -408,7 +414,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 408 | try binary_writer.writeByte(@intFromEnum(std.wasm.ExternalKind.function)); | 414 | try binary_writer.writeByte(@intFromEnum(std.wasm.ExternalKind.function)); |
| 409 | try leb.writeUleb128(binary_writer, @intFromEnum(id.functionType(wasm))); | 415 | try leb.writeUleb128(binary_writer, @intFromEnum(id.functionType(wasm))); |
| 410 | } | 416 | } |
| 411 | total_imports += wasm.function_imports.entries.len; | 417 | total_imports += f.function_imports.entries.len; |
| 412 | | 418 | |
| 413 | for (wasm.table_imports.values()) |id| { | 419 | for (wasm.table_imports.values()) |id| { |
| 414 | const table_import = id.value(wasm); | 420 | const table_import = id.value(wasm); |
| ... | @@ -441,7 +447,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -441,7 +447,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 441 | total_imports += 1; | 447 | total_imports += 1; |
| 442 | } | 448 | } |
| 443 | | 449 | |
| 444 | for (wasm.global_imports.values()) |id| { | 450 | for (f.global_imports.values()) |id| { |
| 445 | const module_name = id.moduleName(wasm).slice(wasm); | 451 | const module_name = id.moduleName(wasm).slice(wasm); |
| 446 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(module_name.len))); | 452 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(module_name.len))); |
| 447 | try binary_writer.writeAll(module_name); | 453 | try binary_writer.writeAll(module_name); |
| ... | @@ -455,7 +461,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -455,7 +461,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 455 | try leb.writeUleb128(binary_writer, @intFromEnum(@as(std.wasm.Valtype, global_type.valtype))); | 461 | try leb.writeUleb128(binary_writer, @intFromEnum(@as(std.wasm.Valtype, global_type.valtype))); |
| 456 | try binary_writer.writeByte(@intFromBool(global_type.mutable)); | 462 | try binary_writer.writeByte(@intFromBool(global_type.mutable)); |
| 457 | } | 463 | } |
| 458 | total_imports += wasm.global_imports.entries.len; | 464 | total_imports += f.global_imports.entries.len; |
| 459 | | 465 | |
| 460 | if (total_imports > 0) { | 466 | if (total_imports > 0) { |
| 461 | replaceVecSectionHeader(binary_bytes, header_offset, .import, @intCast(total_imports)); | 467 | replaceVecSectionHeader(binary_bytes, header_offset, .import, @intCast(total_imports)); |
| ... | @@ -757,6 +763,7 @@ fn emitNameSection( | ... | @@ -757,6 +763,7 @@ fn emitNameSection( |
| 757 | data_segments: *const std.AutoArrayHashMapUnmanaged(Wasm.DataSegment.Id, u32), | 763 | data_segments: *const std.AutoArrayHashMapUnmanaged(Wasm.DataSegment.Id, u32), |
| 758 | binary_bytes: *std.ArrayListUnmanaged(u8), | 764 | binary_bytes: *std.ArrayListUnmanaged(u8), |
| 759 | ) !void { | 765 | ) !void { |
| | 766 | const f = &wasm.flush_buffer; |
| 760 | const comp = wasm.base.comp; | 767 | const comp = wasm.base.comp; |
| 761 | const gpa = comp.gpa; | 768 | const gpa = comp.gpa; |
| 762 | | 769 | |
| ... | @@ -771,16 +778,16 @@ fn emitNameSection( | ... | @@ -771,16 +778,16 @@ fn emitNameSection( |
| 771 | const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | 778 | const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| 772 | defer replaceHeader(binary_bytes, sub_offset, @intFromEnum(std.wasm.NameSubsection.function)); | 779 | defer replaceHeader(binary_bytes, sub_offset, @intFromEnum(std.wasm.NameSubsection.function)); |
| 773 | | 780 | |
| 774 | const total_functions: u32 = @intCast(wasm.function_imports.entries.len + wasm.functions.entries.len); | 781 | const total_functions: u32 = @intCast(f.function_imports.entries.len + wasm.functions.entries.len); |
| 775 | try leb.writeUleb128(binary_bytes.writer(gpa), total_functions); | 782 | try leb.writeUleb128(binary_bytes.writer(gpa), total_functions); |
| 776 | | 783 | |
| 777 | for (wasm.function_imports.keys(), 0..) |name_index, function_index| { | 784 | for (f.function_imports.keys(), 0..) |name_index, function_index| { |
| 778 | const name = name_index.slice(wasm); | 785 | const name = name_index.slice(wasm); |
| 779 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(function_index))); | 786 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(function_index))); |
| 780 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len))); | 787 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len))); |
| 781 | try binary_bytes.appendSlice(gpa, name); | 788 | try binary_bytes.appendSlice(gpa, name); |
| 782 | } | 789 | } |
| 783 | for (wasm.functions.keys(), wasm.function_imports.entries.len..) |resolution, function_index| { | 790 | for (wasm.functions.keys(), f.function_imports.entries.len..) |resolution, function_index| { |
| 784 | const name = resolution.name(wasm).?; | 791 | const name = resolution.name(wasm).?; |
| 785 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(function_index))); | 792 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(function_index))); |
| 786 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len))); | 793 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len))); |
| ... | @@ -792,16 +799,16 @@ fn emitNameSection( | ... | @@ -792,16 +799,16 @@ fn emitNameSection( |
| 792 | const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | 799 | const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| 793 | defer replaceHeader(binary_bytes, sub_offset, @intFromEnum(std.wasm.NameSubsection.global)); | 800 | defer replaceHeader(binary_bytes, sub_offset, @intFromEnum(std.wasm.NameSubsection.global)); |
| 794 | | 801 | |
| 795 | const total_globals: u32 = @intCast(wasm.global_imports.entries.len + wasm.globals.entries.len); | 802 | const total_globals: u32 = @intCast(f.global_imports.entries.len + wasm.globals.entries.len); |
| 796 | try leb.writeUleb128(binary_bytes.writer(gpa), total_globals); | 803 | try leb.writeUleb128(binary_bytes.writer(gpa), total_globals); |
| 797 | | 804 | |
| 798 | for (wasm.global_imports.keys(), 0..) |name_index, global_index| { | 805 | for (f.global_imports.keys(), 0..) |name_index, global_index| { |
| 799 | const name = name_index.slice(wasm); | 806 | const name = name_index.slice(wasm); |
| 800 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(global_index))); | 807 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(global_index))); |
| 801 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len))); | 808 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len))); |
| 802 | try binary_bytes.appendSlice(gpa, name); | 809 | try binary_bytes.appendSlice(gpa, name); |
| 803 | } | 810 | } |
| 804 | for (wasm.globals.keys(), wasm.global_imports.entries.len..) |resolution, global_index| { | 811 | for (wasm.globals.keys(), f.global_imports.entries.len..) |resolution, global_index| { |
| 805 | const name = resolution.name(wasm).?; | 812 | const name = resolution.name(wasm).?; |
| 806 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(global_index))); | 813 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(global_index))); |
| 807 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len))); | 814 | try leb.writeUleb128(binary_bytes.writer(gpa), @as(u32, @intCast(name.len))); |
| ... | @@ -813,7 +820,7 @@ fn emitNameSection( | ... | @@ -813,7 +820,7 @@ fn emitNameSection( |
| 813 | const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes); | 820 | const sub_offset = try reserveCustomSectionHeader(gpa, binary_bytes); |
| 814 | defer replaceHeader(binary_bytes, sub_offset, @intFromEnum(std.wasm.NameSubsection.data_segment)); | 821 | defer replaceHeader(binary_bytes, sub_offset, @intFromEnum(std.wasm.NameSubsection.data_segment)); |
| 815 | | 822 | |
| 816 | const total_globals: u32 = @intCast(wasm.global_imports.entries.len + wasm.globals.entries.len); | 823 | const total_globals: u32 = @intCast(f.global_imports.entries.len + wasm.globals.entries.len); |
| 817 | try leb.writeUleb128(binary_bytes.writer(gpa), total_globals); | 824 | try leb.writeUleb128(binary_bytes.writer(gpa), total_globals); |
| 818 | | 825 | |
| 819 | for (data_segments.keys(), 0..) |ds, i| { | 826 | for (data_segments.keys(), 0..) |ds, i| { |
| ... | @@ -1356,7 +1363,7 @@ fn emitSegmentInfo(wasm: *Wasm, binary_bytes: *std.ArrayList(u8)) !void { | ... | @@ -1356,7 +1363,7 @@ fn emitSegmentInfo(wasm: *Wasm, binary_bytes: *std.ArrayList(u8)) !void { |
| 1356 | // .FUNCTION_INDEX_LEB => if (symbol.flags.undefined) | 1363 | // .FUNCTION_INDEX_LEB => if (symbol.flags.undefined) |
| 1357 | // @intFromEnum(symbol.pointee.function_import) | 1364 | // @intFromEnum(symbol.pointee.function_import) |
| 1358 | // else | 1365 | // else |
| 1359 | // @intFromEnum(symbol.pointee.function) + wasm.function_imports.items.len, | 1366 | // @intFromEnum(symbol.pointee.function) + f.function_imports.items.len, |
| 1360 | // .TABLE_NUMBER_LEB => if (symbol.flags.undefined) | 1367 | // .TABLE_NUMBER_LEB => if (symbol.flags.undefined) |
| 1361 | // @intFromEnum(symbol.pointee.table_import) | 1368 | // @intFromEnum(symbol.pointee.table_import) |
| 1362 | // else | 1369 | // else |
| ... | @@ -1371,7 +1378,7 @@ fn emitSegmentInfo(wasm: *Wasm, binary_bytes: *std.ArrayList(u8)) !void { | ... | @@ -1371,7 +1378,7 @@ fn emitSegmentInfo(wasm: *Wasm, binary_bytes: *std.ArrayList(u8)) !void { |
| 1371 | // .GLOBAL_INDEX_I32, .GLOBAL_INDEX_LEB => if (symbol.flags.undefined) | 1378 | // .GLOBAL_INDEX_I32, .GLOBAL_INDEX_LEB => if (symbol.flags.undefined) |
| 1372 | // @intFromEnum(symbol.pointee.global_import) | 1379 | // @intFromEnum(symbol.pointee.global_import) |
| 1373 | // else | 1380 | // else |
| 1374 | // @intFromEnum(symbol.pointee.global) + wasm.global_imports.items.len, | 1381 | // @intFromEnum(symbol.pointee.global) + f.global_imports.items.len, |
| 1375 | // | 1382 | // |
| 1376 | // .MEMORY_ADDR_I32, | 1383 | // .MEMORY_ADDR_I32, |
| 1377 | // .MEMORY_ADDR_I64, | 1384 | // .MEMORY_ADDR_I64, |