Commit d2cdfb9490
Changed files (5)
lib
std
lib/std/build.zig
@@ -1439,6 +1439,10 @@ pub const LibExeObjStep = struct {
disable_sanitize_c: bool,
sanitize_thread: bool,
rdynamic: bool,
+ import_memory: bool = false,
+ initial_memory: ?u64 = null,
+ max_memory: ?u64 = null,
+ global_base: ?u64 = null,
c_std: Builder.CStd,
override_lib_dir: ?[]const u8,
main_pkg_path: ?[]const u8,
@@ -2431,6 +2435,18 @@ pub const LibExeObjStep = struct {
if (self.rdynamic) {
try zig_args.append("-rdynamic");
}
+ if (self.import_memory) {
+ try zig_args.append("--import-memory");
+ }
+ if (self.initial_memory) |initial_memory| {
+ try zig_args.append(builder.fmt("--initial-memory={d}", .{initial_memory}));
+ }
+ if (self.max_memory) |max_memory| {
+ try zig_args.append(builder.fmt("--max-memory={d}", .{max_memory}));
+ }
+ if (self.global_base) |global_base| {
+ try zig_args.append(builder.fmt("--global-base={d}", .{global_base}));
+ }
if (self.code_model != .default) {
try zig_args.append("-mcmodel");
src/link/Wasm.zig
@@ -681,6 +681,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
try man.addOptionalFile(compiler_rt_path);
man.hash.addOptional(self.base.options.stack_size_override);
man.hash.addListOfBytes(self.base.options.extra_lld_args);
+ man.hash.add(self.base.options.import_memory);
+ man.hash.addOptional(self.base.options.initial_memory);
+ man.hash.addOptional(self.base.options.max_memory);
+ man.hash.addOptional(self.base.options.global_base);
// We don't actually care whether it's a cache hit or miss; we just need the digest and the lock.
_ = try man.hit();
@@ -754,6 +758,25 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
}
}
+ if (self.base.options.import_memory) {
+ try argv.append("--import-memory");
+ }
+
+ if (self.base.options.initial_memory) |initial_memory| {
+ const arg = try std.fmt.allocPrint(arena, "--initial-memory={d}", .{initial_memory});
+ try argv.append(arg);
+ }
+
+ if (self.base.options.max_memory) |max_memory| {
+ const arg = try std.fmt.allocPrint(arena, "--max-memory={d}", .{max_memory});
+ try argv.append(arg);
+ }
+
+ if (self.base.options.global_base) |global_base| {
+ const arg = try std.fmt.allocPrint(arena, "--global-base={d}", .{global_base});
+ try argv.append(arg);
+ }
+
if (self.base.options.output_mode == .Exe) {
// Increase the default stack size to a more reasonable value of 1MB instead of
// the default of 1 Wasm page being 64KB, unless overridden by the user.
src/Compilation.zig
@@ -716,6 +716,10 @@ pub const InitOptions = struct {
linker_gc_sections: ?bool = null,
linker_allow_shlib_undefined: ?bool = null,
linker_bind_global_refs_locally: ?bool = null,
+ linker_import_memory: ?bool = null,
+ linker_initial_memory: ?u64 = null,
+ linker_max_memory: ?u64 = null,
+ linker_global_base: ?u64 = null,
each_lib_rpath: ?bool = null,
disable_c_depfile: bool = false,
linker_z_nodelete: bool = false,
@@ -1401,6 +1405,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
.function_sections = options.function_sections,
.allow_shlib_undefined = options.linker_allow_shlib_undefined,
.bind_global_refs_locally = options.linker_bind_global_refs_locally orelse false,
+ .import_memory = options.linker_import_memory orelse false,
+ .initial_memory = options.linker_initial_memory,
+ .max_memory = options.linker_max_memory,
+ .global_base = options.linker_global_base,
.z_nodelete = options.linker_z_nodelete,
.z_notext = options.linker_z_notext,
.z_defs = options.linker_z_defs,
src/link.zig
@@ -82,6 +82,10 @@ pub const Options = struct {
nxcompat: bool,
dynamicbase: bool,
bind_global_refs_locally: bool,
+ import_memory: bool,
+ initial_memory: ?u64,
+ max_memory: ?u64,
+ global_base: ?u64,
is_native_os: bool,
is_native_abi: bool,
pic: bool,
src/main.zig
@@ -332,7 +332,7 @@ const usage_build_generic =
\\ -mno-red-zone Force-disable the "red-zone"
\\ -fomit-frame-pointer Omit the stack frame pointer
\\ -fno-omit-frame-pointer Store the stack frame pointer
- \\ -mexec-model=[value] Execution model (WASI only)
+ \\ -mexec-model=[value] (WASI) Execution model
\\ --name [name] Override root name (not a file path)
\\ -O [mode] Choose what to optimize for
\\ Debug (default) Optimizations off, safety on
@@ -424,6 +424,10 @@ const usage_build_generic =
\\ --image-base [addr] Set base address for executable image
\\ -framework [name] (Darwin) link against framework
\\ -F[dir] (Darwin) add search path for frameworks
+ \\ --import-memory (WebAssembly) import memory from the environment
+ \\ --initial-memory=[bytes] (WebAssembly) initial size of the linear memory
+ \\ --max-memory=[bytes] (WebAssembly) maximum size of the linear memory
+ \\ --global-base=[addr] (WebAssembly) where to start to place global data
\\
\\Test Options:
\\ --test-filter [text] Skip tests that do not match filter
@@ -609,6 +613,10 @@ fn buildOutputType(
var linker_gc_sections: ?bool = null;
var linker_allow_shlib_undefined: ?bool = null;
var linker_bind_global_refs_locally: ?bool = null;
+ var linker_import_memory: ?bool = null;
+ var linker_initial_memory: ?u64 = null;
+ var linker_max_memory: ?u64 = null;
+ var linker_global_base: ?u64 = null;
var linker_z_nodelete = false;
var linker_z_notext = false;
var linker_z_defs = false;
@@ -1125,6 +1133,14 @@ fn buildOutputType(
} else {
warn("unsupported linker extension flag: -z {s}", .{z_arg});
}
+ } else if (mem.eql(u8, arg, "--import-memory")) {
+ linker_import_memory = true;
+ } else if (mem.startsWith(u8, arg, "--initial-memory=")) {
+ linker_initial_memory = parseIntSuffix(arg, "--initial-memory=".len);
+ } else if (mem.startsWith(u8, arg, "--max-memory=")) {
+ linker_max_memory = parseIntSuffix(arg, "--max-memory=".len);
+ } else if (mem.startsWith(u8, arg, "--global-base=")) {
+ linker_global_base = parseIntSuffix(arg, "--global-base=".len);
} else if (mem.eql(u8, arg, "-Bsymbolic")) {
linker_bind_global_refs_locally = true;
} else if (mem.eql(u8, arg, "--debug-compile-errors")) {
@@ -1453,6 +1469,14 @@ fn buildOutputType(
linker_allow_shlib_undefined = false;
} else if (mem.eql(u8, arg, "-Bsymbolic")) {
linker_bind_global_refs_locally = true;
+ } else if (mem.eql(u8, arg, "--import-memory")) {
+ linker_import_memory = true;
+ } else if (mem.startsWith(u8, arg, "--initial-memory=")) {
+ linker_initial_memory = parseIntSuffix(arg, "--initial-memory=".len);
+ } else if (mem.startsWith(u8, arg, "--max-memory=")) {
+ linker_max_memory = parseIntSuffix(arg, "--max-memory=".len);
+ } else if (mem.startsWith(u8, arg, "--global-base=")) {
+ linker_global_base = parseIntSuffix(arg, "--global-base=".len);
} else if (mem.eql(u8, arg, "-z")) {
i += 1;
if (i >= linker_args.items.len) {
@@ -2148,6 +2172,10 @@ fn buildOutputType(
.linker_gc_sections = linker_gc_sections,
.linker_allow_shlib_undefined = linker_allow_shlib_undefined,
.linker_bind_global_refs_locally = linker_bind_global_refs_locally,
+ .linker_import_memory = linker_import_memory,
+ .linker_initial_memory = linker_initial_memory,
+ .linker_max_memory = linker_max_memory,
+ .linker_global_base = linker_global_base,
.linker_z_nodelete = linker_z_nodelete,
.linker_z_notext = linker_z_notext,
.linker_z_defs = linker_z_defs,
@@ -4371,3 +4399,9 @@ pub fn cmdChangelist(
}
try bw.flush();
}
+
+fn parseIntSuffix(arg: []const u8, prefix_len: usize) u64 {
+ return std.fmt.parseUnsigned(u64, arg[prefix_len..], 0) catch |err| {
+ fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) });
+ };
+}