From 7051f8e73b875aca52cc2e56a8f296d847f8dfa8 Mon Sep 17 00:00:00 2001 From: Pavel Verigo Date: Tue, 18 Aug 2026 05:54:15 +0200 Subject: [PATCH] wasm: add --growable-table --- lib/compiler/Maker/Step/Compile.zig | 1 + lib/std/Build/Configuration.zig | 2 +- lib/std/Build/Serialize.zig | 1 + lib/std/Build/Step/Compile.zig | 1 + src/Compilation.zig | 3 +++ src/link.zig | 1 + src/link/Lld.zig | 7 +++++++ src/link/Wasm.zig | 5 ++++- src/main.zig | 7 +++++++ 9 files changed, 26 insertions(+), 2 deletions(-) diff --git a/lib/compiler/Maker/Step/Compile.zig b/lib/compiler/Maker/Step/Compile.zig index c487966999ca178d88b83332b0f953baa410a52e..1e60ad77a30a78bf0f903527430ac76b7af4fdd4 100644 --- a/lib/compiler/Maker/Step/Compile.zig +++ b/lib/compiler/Maker/Step/Compile.zig @@ -728,6 +728,7 @@ fn lowerZigArgs( try addBool(gpa, zig_args, "--import-symbols", conf_comp.flags.import_symbols); try addBool(gpa, zig_args, "--import-table", conf_comp.flags.import_table); try addBool(gpa, zig_args, "--export-table", conf_comp.flags.export_table); + try addBool(gpa, zig_args, "--growable-table", conf_comp.flags.growable_table); try addBool(gpa, zig_args, "--shared-memory", conf_comp.flags.shared_memory); { diff --git a/lib/std/Build/Configuration.zig b/lib/std/Build/Configuration.zig index 3221086488b403294a316e6ffde8f5dc0522c947..b53fe377189bd4f82a92f3927552b327f84cd9a4 100644 --- a/lib/std/Build/Configuration.zig +++ b/lib/std/Build/Configuration.zig @@ -953,6 +953,7 @@ pub const Step = extern struct { import_symbols: bool, import_table: bool, export_table: bool, + growable_table: bool, shared_memory: bool, link_eh_frame_hdr: bool, link_emit_relocs: bool, @@ -968,7 +969,6 @@ pub const Step = extern struct { force_load_objc: bool, discard_local_symbols: bool, mingw_unicode_entry_point: bool, - _: u1 = 0, }; pub const Flags2 = packed struct(u32) { diff --git a/lib/std/Build/Serialize.zig b/lib/std/Build/Serialize.zig index 995a69da87f9a6becfdb35f61683178b5e046c8b..e75dd2d5b10baa05d175d21f6c63c664ead99ad5 100644 --- a/lib/std/Build/Serialize.zig +++ b/lib/std/Build/Serialize.zig @@ -133,6 +133,7 @@ pub fn write(b: *std.Build, wc: *Configuration.Wip, writer: *std.Io.Writer) !voi .import_symbols = c.import_symbols, .import_table = c.import_table, .export_table = c.export_table, + .growable_table = c.growable_table, .shared_memory = c.shared_memory, .link_eh_frame_hdr = c.link_eh_frame_hdr, .link_emit_relocs = c.link_emit_relocs, diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index df4da47b01df0ae1bdb0ad19e090437f96063bb7..6d1c1ec4c44871ff1e8ad8f692777123e7f9c884 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -45,6 +45,7 @@ import_symbols: bool = false, /// (WebAssembly) import function table from the host environment import_table: bool = false, export_table: bool = false, +growable_table: bool = false, initial_memory: ?u64 = null, max_memory: ?u64 = null, shared_memory: bool = false, diff --git a/src/Compilation.zig b/src/Compilation.zig index 09a52629200253620e34890507178530d6bef6dc..3e8b2043a4d496800eacea61211e2a99eab37e11 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -1478,6 +1478,7 @@ pub const CreateOptions = struct { linker_import_symbols: bool = false, linker_import_table: bool = false, linker_export_table: bool = false, + linker_growable_table: bool = false, linker_initial_memory: ?u64 = null, linker_max_memory: ?u64 = null, linker_global_base: ?u64 = null, @@ -2183,6 +2184,7 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, .import_symbols = options.linker_import_symbols, .import_table = options.linker_import_table, .export_table = options.linker_export_table, + .growable_table = options.linker_growable_table, .initial_memory = options.linker_initial_memory, .max_memory = options.linker_max_memory, .global_base = options.linker_global_base, @@ -3434,6 +3436,7 @@ fn addNonIncrementalStuffToCacheManifest( man.hash.add(opts.import_symbols); man.hash.add(opts.import_table); man.hash.add(opts.export_table); + man.hash.add(opts.growable_table); // Mach-O specific stuff try link.File.MachO.hashAddFrameworks(man, opts.frameworks); diff --git a/src/link.zig b/src/link.zig index b72a8e8c5959cdce72036b29df359b6cbc286dd8..836621f3fea4a25a1f37d5d313d942f8229fcfad 100644 --- a/src/link.zig +++ b/src/link.zig @@ -444,6 +444,7 @@ pub const File = struct { import_symbols: bool, import_table: bool, export_table: bool, + growable_table: bool, initial_memory: ?u64, max_memory: ?u64, object_host_name: ?[]const u8, diff --git a/src/link/Lld.zig b/src/link/Lld.zig index 6a4d8db174fb7a485c0d85e15b688d20d80a5b71..b1ac4a2834bf7ba5992d658304e40e0ccf2a9a18 100644 --- a/src/link/Lld.zig +++ b/src/link/Lld.zig @@ -166,6 +166,8 @@ const Wasm = struct { import_table: bool, /// When true, will export the function table to the host environment. export_table: bool, + /// When true, remove maximum size from function table, allowing table to grow. + growable_table: bool, /// When defined, sets the initial memory size of the memory. initial_memory: ?u64, /// When defined, sets the maximum memory size of the memory. @@ -190,6 +192,7 @@ const Wasm = struct { }, .import_table = options.import_table, .export_table = options.export_table, + .growable_table = options.growable_table, .initial_memory = options.initial_memory, .max_memory = options.max_memory, .global_base = options.global_base, @@ -1465,6 +1468,10 @@ fn wasmLink(lld: *Lld, arena: Allocator) !void { try argv.append("--export-table"); } + if (wasm.growable_table) { + try argv.append("--growable-table"); + } + // For wasm-ld we only need to specify '--no-gc-sections' when the user explicitly // specified it as garbage collection is enabled by default. if (!base.gc_sections) { diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 1857259fa64bf354bf7ba65846ee65c3c413ccfe..c0aa2f1ea4f9a6c957c1d46799fe21dc56d0b0e2 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -75,6 +75,8 @@ initial_memory: ?u64, max_memory: ?u64, /// When true, will export the function table to the host environment. export_table: bool, +/// When true, remove maximum size from function table, allowing table to grow. +growable_table: bool, /// Output name of the file name: []const u8, /// List of relocatable files to be linked into the final binary. @@ -1535,7 +1537,7 @@ pub const TableImport = extern struct { return switch (unpack(r)) { .unresolved => unreachable, .__indirect_function_table => .{ - .flags = .{ .has_max = true, .is_shared = false }, + .flags = .{ .has_max = !wasm.growable_table, .is_shared = false }, .min = @intCast(wasm.flush_buffer.indirect_function_table.entries.len + 1), .max = @intCast(wasm.flush_buffer.indirect_function_table.entries.len + 1), }, @@ -3381,6 +3383,7 @@ pub fn createEmpty( .string_table = .empty, .string_bytes = .empty, .export_table = options.export_table, + .growable_table = options.growable_table, .import_symbols = options.import_symbols, .export_symbol_names = options.export_symbol_names, .global_base = options.global_base, diff --git a/src/main.zig b/src/main.zig index f57371bf05e6ddd60185e0d2ad7a6e300ae70fb4..733620bd34eb552cb1784a2f36bfb70cab1f864c 100644 --- a/src/main.zig +++ b/src/main.zig @@ -751,6 +751,7 @@ const usage_build_generic = \\ --import-symbols (WebAssembly) import missing symbols from the host environment \\ --import-table (WebAssembly) import function table from the host environment \\ --export-table (WebAssembly) export function table to the host environment + \\ --growable-table (WebAssembly) remove maximum size from function table, allowing table to grow \\ --initial-memory=[bytes] (WebAssembly) initial size of the linear memory \\ --max-memory=[bytes] (WebAssembly) maximum size of the linear memory \\ --shared-memory (WebAssembly) use shared linear memory @@ -985,6 +986,7 @@ fn buildOutputType( var linker_import_symbols: bool = false; var linker_import_table: bool = false; var linker_export_table: bool = false; + var linker_growable_table: bool = false; var linker_initial_memory: ?u64 = null; var linker_max_memory: ?u64 = null; var linker_global_base: ?u64 = null; @@ -1764,6 +1766,8 @@ fn buildOutputType( linker_import_table = true; } else if (mem.eql(u8, arg, "--export-table")) { linker_export_table = true; + } else if (mem.eql(u8, arg, "--growable-table")) { + linker_growable_table = true; } else if (prefixedIntArg(arg, "--initial-memory=")) |int| { linker_initial_memory = int; } else if (prefixedIntArg(arg, "--max-memory=")) |int| { @@ -2712,6 +2716,8 @@ fn buildOutputType( linker_import_table = true; } else if (mem.eql(u8, arg, "--export-table")) { linker_export_table = true; + } else if (mem.eql(u8, arg, "--growable-table")) { + linker_growable_table = true; } else if (mem.eql(u8, arg, "--no-entry")) { entry = .disabled; } else if (mem.eql(u8, arg, "--initial-memory")) { @@ -3674,6 +3680,7 @@ fn buildOutputType( .linker_import_symbols = linker_import_symbols, .linker_import_table = linker_import_table, .linker_export_table = linker_export_table, + .linker_growable_table = linker_growable_table, .linker_initial_memory = linker_initial_memory, .linker_max_memory = linker_max_memory, .linker_print_gc_sections = linker_print_gc_sections, -- 2.54.0