| ... | @@ -36,9 +36,21 @@ data_imports: std.AutoArrayHashMapUnmanaged(String, Wasm.DataImportId) = .empty, | ... | @@ -36,9 +36,21 @@ data_imports: std.AutoArrayHashMapUnmanaged(String, Wasm.DataImportId) = .empty, |
| 36 | | 36 | |
| 37 | indirect_function_table: std.AutoArrayHashMapUnmanaged(Wasm.OutputFunctionIndex, void) = .empty, | 37 | indirect_function_table: std.AutoArrayHashMapUnmanaged(Wasm.OutputFunctionIndex, void) = .empty, |
| 38 | | 38 | |
| | 39 | /// A subset of the full interned function type list created only during flush. |
| | 40 | func_types: std.AutoArrayHashMapUnmanaged(Wasm.FunctionType.Index, void) = .empty, |
| | 41 | |
| 39 | /// For debug purposes only. | 42 | /// For debug purposes only. |
| 40 | memory_layout_finished: bool = false, | 43 | memory_layout_finished: bool = false, |
| 41 | | 44 | |
| | 45 | /// Index into `func_types`. |
| | 46 | pub const FuncTypeIndex = enum(u32) { |
| | 47 | _, |
| | 48 | |
| | 49 | pub fn fromTypeIndex(i: Wasm.FunctionType.Index, f: *const Flush) FuncTypeIndex { |
| | 50 | return @enumFromInt(f.func_types.getIndex(i).?); |
| | 51 | } |
| | 52 | }; |
| | 53 | |
| 42 | /// Index into `indirect_function_table`. | 54 | /// Index into `indirect_function_table`. |
| 43 | const IndirectFunctionTableIndex = enum(u32) { | 55 | const IndirectFunctionTableIndex = enum(u32) { |
| 44 | _, | 56 | _, |
| ... | @@ -75,6 +87,7 @@ pub fn clear(f: *Flush) void { | ... | @@ -75,6 +87,7 @@ pub fn clear(f: *Flush) void { |
| 75 | f.data_segment_groups.clearRetainingCapacity(); | 87 | f.data_segment_groups.clearRetainingCapacity(); |
| 76 | f.binary_bytes.clearRetainingCapacity(); | 88 | f.binary_bytes.clearRetainingCapacity(); |
| 77 | f.indirect_function_table.clearRetainingCapacity(); | 89 | f.indirect_function_table.clearRetainingCapacity(); |
| | 90 | f.func_types.clearRetainingCapacity(); |
| 78 | f.memory_layout_finished = false; | 91 | f.memory_layout_finished = false; |
| 79 | } | 92 | } |
| 80 | | 93 | |
| ... | @@ -87,6 +100,7 @@ pub fn deinit(f: *Flush, gpa: Allocator) void { | ... | @@ -87,6 +100,7 @@ pub fn deinit(f: *Flush, gpa: Allocator) void { |
| 87 | f.global_imports.deinit(gpa); | 100 | f.global_imports.deinit(gpa); |
| 88 | f.data_imports.deinit(gpa); | 101 | f.data_imports.deinit(gpa); |
| 89 | f.indirect_function_table.deinit(gpa); | 102 | f.indirect_function_table.deinit(gpa); |
| | 103 | f.func_types.deinit(gpa); |
| 90 | f.* = undefined; | 104 | f.* = undefined; |
| 91 | } | 105 | } |
| 92 | | 106 | |
| ... | @@ -510,11 +524,17 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -510,11 +524,17 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 510 | | 524 | |
| 511 | const binary_writer = binary_bytes.writer(gpa); | 525 | const binary_writer = binary_bytes.writer(gpa); |
| 512 | | 526 | |
| 513 | // Type section | 527 | // Type section. |
| 514 | if (wasm.func_types.entries.len != 0) { | 528 | for (f.function_imports.values()) |id| { |
| | 529 | try f.func_types.put(gpa, id.functionType(wasm), {}); |
| | 530 | } |
| | 531 | for (wasm.functions.keys()) |function| { |
| | 532 | try f.func_types.put(gpa, function.typeIndex(wasm), {}); |
| | 533 | } |
| | 534 | if (f.func_types.entries.len != 0) { |
| 515 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 535 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 516 | log.debug("Writing type section. Count: ({d})", .{wasm.func_types.entries.len}); | 536 | for (f.func_types.keys()) |func_type_index| { |
| 517 | for (wasm.func_types.keys()) |func_type| { | 537 | const func_type = func_type_index.ptr(wasm); |
| 518 | try leb.writeUleb128(binary_writer, std.wasm.function_type); | 538 | try leb.writeUleb128(binary_writer, std.wasm.function_type); |
| 519 | const params = func_type.params.slice(wasm); | 539 | const params = func_type.params.slice(wasm); |
| 520 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(params.len))); | 540 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(params.len))); |
| ... | @@ -527,8 +547,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -527,8 +547,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 527 | try leb.writeUleb128(binary_writer, @intFromEnum(ret_ty)); | 547 | try leb.writeUleb128(binary_writer, @intFromEnum(ret_ty)); |
| 528 | } | 548 | } |
| 529 | } | 549 | } |
| 530 | | 550 | replaceVecSectionHeader(binary_bytes, header_offset, .type, @intCast(f.func_types.entries.len)); |
| 531 | replaceVecSectionHeader(binary_bytes, header_offset, .type, @intCast(wasm.func_types.entries.len)); | | |
| 532 | section_index += 1; | 551 | section_index += 1; |
| 533 | } | 552 | } |
| 534 | | 553 | |
| ... | @@ -553,7 +572,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -553,7 +572,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 553 | try binary_writer.writeAll(name); | 572 | try binary_writer.writeAll(name); |
| 554 | | 573 | |
| 555 | try binary_writer.writeByte(@intFromEnum(std.wasm.ExternalKind.function)); | 574 | try binary_writer.writeByte(@intFromEnum(std.wasm.ExternalKind.function)); |
| 556 | try leb.writeUleb128(binary_writer, @intFromEnum(id.functionType(wasm))); | 575 | const type_index: FuncTypeIndex = .fromTypeIndex(id.functionType(wasm), f); |
| | 576 | try leb.writeUleb128(binary_writer, @intFromEnum(type_index)); |
| 557 | } | 577 | } |
| 558 | total_imports += f.function_imports.entries.len; | 578 | total_imports += f.function_imports.entries.len; |
| 559 | | 579 | |
| ... | @@ -615,7 +635,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -615,7 +635,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 615 | if (wasm.functions.count() != 0) { | 635 | if (wasm.functions.count() != 0) { |
| 616 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 636 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 617 | for (wasm.functions.keys()) |function| { | 637 | for (wasm.functions.keys()) |function| { |
| 618 | try leb.writeUleb128(binary_writer, @intFromEnum(function.typeIndex(wasm))); | 638 | const index: FuncTypeIndex = .fromTypeIndex(function.typeIndex(wasm), f); |
| | 639 | try leb.writeUleb128(binary_writer, @intFromEnum(index)); |
| 619 | } | 640 | } |
| 620 | | 641 | |
| 621 | replaceVecSectionHeader(binary_bytes, header_offset, .function, @intCast(wasm.functions.count())); | 642 | replaceVecSectionHeader(binary_bytes, header_offset, .function, @intCast(wasm.functions.count())); |
| ... | @@ -1644,7 +1665,7 @@ fn applyRelocs(code: []u8, code_offset: u32, relocs: Wasm.ObjectRelocation.Itera | ... | @@ -1644,7 +1665,7 @@ fn applyRelocs(code: []u8, code_offset: u32, relocs: Wasm.ObjectRelocation.Itera |
| 1644 | .table_number_leb => reloc_leb_table(sliced_code, .fromObjectTable(wasm, pointee.table)), | 1665 | .table_number_leb => reloc_leb_table(sliced_code, .fromObjectTable(wasm, pointee.table)), |
| 1645 | .table_import_number_leb => reloc_leb_table(sliced_code, .fromSymbolName(wasm, pointee.symbol_name)), | 1666 | .table_import_number_leb => reloc_leb_table(sliced_code, .fromSymbolName(wasm, pointee.symbol_name)), |
| 1646 | | 1667 | |
| 1647 | .type_index_leb => reloc_leb_type(sliced_code, pointee.type_index), | 1668 | .type_index_leb => reloc_leb_type(sliced_code, .fromTypeIndex(pointee.type_index, &wasm.flush_buffer)), |
| 1648 | } | 1669 | } |
| 1649 | } | 1670 | } |
| 1650 | } | 1671 | } |
| ... | @@ -1733,7 +1754,7 @@ fn reloc_leb_table(code: []u8, table: Wasm.TableIndex) void { | ... | @@ -1733,7 +1754,7 @@ fn reloc_leb_table(code: []u8, table: Wasm.TableIndex) void { |
| 1733 | leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(table)); | 1754 | leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(table)); |
| 1734 | } | 1755 | } |
| 1735 | | 1756 | |
| 1736 | fn reloc_leb_type(code: []u8, index: Wasm.FunctionType.Index) void { | 1757 | fn reloc_leb_type(code: []u8, index: FuncTypeIndex) void { |
| 1737 | leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(index)); | 1758 | leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(index)); |
| 1738 | } | 1759 | } |
| 1739 | | 1760 | |