| ... | ... | @@ -36,9 +36,21 @@ data_imports: std.AutoArrayHashMapUnmanaged(String, Wasm.DataImportId) = .empty, |
| 36 | 36 | |
| 37 | 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 | 42 | /// For debug purposes only. |
| 40 | 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 | 54 | /// Index into `indirect_function_table`. |
| 43 | 55 | const IndirectFunctionTableIndex = enum(u32) { |
| 44 | 56 | _, |
| ... | ... | @@ -75,6 +87,7 @@ pub fn clear(f: *Flush) void { |
| 75 | 87 | f.data_segment_groups.clearRetainingCapacity(); |
| 76 | 88 | f.binary_bytes.clearRetainingCapacity(); |
| 77 | 89 | f.indirect_function_table.clearRetainingCapacity(); |
| 90 | f.func_types.clearRetainingCapacity(); |
| 78 | 91 | f.memory_layout_finished = false; |
| 79 | 92 | } |
| 80 | 93 | |
| ... | ... | @@ -87,6 +100,7 @@ pub fn deinit(f: *Flush, gpa: Allocator) void { |
| 87 | 100 | f.global_imports.deinit(gpa); |
| 88 | 101 | f.data_imports.deinit(gpa); |
| 89 | 102 | f.indirect_function_table.deinit(gpa); |
| 103 | f.func_types.deinit(gpa); |
| 90 | 104 | f.* = undefined; |
| 91 | 105 | } |
| 92 | 106 | |
| ... | ... | @@ -510,11 +524,17 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 510 | 524 | |
| 511 | 525 | const binary_writer = binary_bytes.writer(gpa); |
| 512 | 526 | |
| 513 | | // Type section |
| 514 | | if (wasm.func_types.entries.len != 0) { |
| 527 | // Type section. |
| 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 | 535 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 516 | | log.debug("Writing type section. Count: ({d})", .{wasm.func_types.entries.len}); |
| 517 | | for (wasm.func_types.keys()) |func_type| { |
| 536 | for (f.func_types.keys()) |func_type_index| { |
| 537 | const func_type = func_type_index.ptr(wasm); |
| 518 | 538 | try leb.writeUleb128(binary_writer, std.wasm.function_type); |
| 519 | 539 | const params = func_type.params.slice(wasm); |
| 520 | 540 | try leb.writeUleb128(binary_writer, @as(u32, @intCast(params.len))); |
| ... | ... | @@ -527,8 +547,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 527 | 547 | try leb.writeUleb128(binary_writer, @intFromEnum(ret_ty)); |
| 528 | 548 | } |
| 529 | 549 | } |
| 530 | | |
| 531 | | replaceVecSectionHeader(binary_bytes, header_offset, .type, @intCast(wasm.func_types.entries.len)); |
| 550 | replaceVecSectionHeader(binary_bytes, header_offset, .type, @intCast(f.func_types.entries.len)); |
| 532 | 551 | section_index += 1; |
| 533 | 552 | } |
| 534 | 553 | |
| ... | ... | @@ -553,7 +572,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 553 | 572 | try binary_writer.writeAll(name); |
| 554 | 573 | |
| 555 | 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 | 578 | total_imports += f.function_imports.entries.len; |
| 559 | 579 | |
| ... | ... | @@ -615,7 +635,8 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 615 | 635 | if (wasm.functions.count() != 0) { |
| 616 | 636 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |
| 617 | 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 | 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 | 1665 | .table_number_leb => reloc_leb_table(sliced_code, .fromObjectTable(wasm, pointee.table)), |
| 1645 | 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 | 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 | 1758 | leb.writeUnsignedFixed(5, code[0..5], @intFromEnum(index)); |
| 1738 | 1759 | } |
| 1739 | 1760 | |