cc,wasi: support WASI reactors via -mexec-model flag.

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
This commit is contained in:
Takeshi Yoneda 2021-06-09 17:07:06 +09:00
parent a6ae5a77da
commit bf568ec62a
6 changed files with 52 additions and 8 deletions

View File

@ -603,6 +603,11 @@ pub const ClangPreprocessorMode = enum {
stdout,
};
pub const WasiExecModel = enum {
command,
reactor,
};
pub const InitOptions = struct {
zig_lib_directory: Directory,
local_cache_directory: Directory,
@ -725,6 +730,8 @@ pub const InitOptions = struct {
test_filter: ?[]const u8 = null,
test_name_prefix: ?[]const u8 = null,
subsystem: ?std.Target.SubSystem = null,
/// WASI-only. Type of WASI execution model ("command" or "reactor").
wasi_exec_model: ?WasiExecModel = null,
};
fn addPackageTableToCacheHash(
@ -1340,6 +1347,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
.disable_lld_caching = options.disable_lld_caching,
.subsystem = options.subsystem,
.is_test = options.is_test,
.wasi_exec_model = options.wasi_exec_model,
});
errdefer bin_file.destroy();
comp.* = .{
@ -1441,9 +1449,14 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
.wasi_libc_crt_file = crt_file,
});
}
// TODO add logic deciding which crt1 we want here.
const crt_file: wasi_libc.CRTFile = if (comp.bin_file.options.wasi_exec_model) |exec_model| crt_file: {
switch (exec_model) {
.command => break :crt_file wasi_libc.CRTFile.crt1_command_o,
.reactor => break :crt_file wasi_libc.CRTFile.crt1_reactor_o,
}
} else .crt1_o;
comp.work_queue.writeAssumeCapacity(&[_]Job{
.{ .wasi_libc_crt_file = .crt1_o },
.{ .wasi_libc_crt_file = crt_file },
.{ .wasi_libc_crt_file = .libc_a },
});
}
@ -1868,7 +1881,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
for (keys[1..]) |key, i| {
err_msg.notes[i] = .{
.src_loc = key.nodeOffsetSrcLoc(values[i+1]),
.src_loc = key.nodeOffsetSrcLoc(values[i + 1]),
.msg = "also here",
};
}

View File

@ -5257,7 +5257,14 @@ jspd1("fxray-modes="),
.psl = false,
},
jspd1("iwithsysroot"),
joinpd1("mexec-model="),
.{
.name = "mexec-model=",
.syntax = .joined,
.zig_equivalent = .exec_model,
.pd1 = true,
.pd2 = false,
.psl = false,
},
joinpd1("mharden-sls="),
joinpd1("mhvx-length="),
jspd1("objc-isystem"),

View File

@ -118,6 +118,9 @@ pub const Options = struct {
version: ?std.builtin.Version,
libc_installation: ?*const LibCInstallation,
/// WASI-only. Type of WASI execution model ("command" or "reactor").
wasi_exec_model: ?Compilation.WasiExecModel = null,
pub fn effectiveOutputMode(options: Options) std.builtin.OutputMode {
return if (options.use_lld) .Obj else options.output_mode;
}

View File

@ -681,6 +681,12 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
// Put stack before globals so that stack overflow results in segfault immediately
// before corrupting globals. See https://github.com/ziglang/zig/issues/4496
try argv.append("--stack-first");
// Reactor execution model does not have _start so lld doesn't look for it.
if (self.base.options.wasi_exec_model) |exec_model| blk: {
if (exec_model != .reactor) break :blk;
try argv.append("--no-entry");
}
} else {
try argv.append("--no-entry"); // So lld doesn't look for _start.
try argv.append("--export-all");
@ -692,10 +698,11 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void {
});
if (target.os.tag == .wasi) {
if (self.base.options.link_libc and self.base.options.output_mode == .Exe) {
// TODO work out if we want standard crt, a reactor or a command
try argv.append(try comp.get_libc_crt_file(arena, "crt1.o"));
}
const crt_name = if (self.base.options.wasi_exec_model) |exec_model|
try std.fmt.allocPrint(arena, "crt1-{s}.o", .{@tagName(exec_model)})
else
"crt1.o";
try argv.append(try comp.get_libc_crt_file(arena, crt_name));
const is_exe_or_dyn_lib = self.base.options.output_mode == .Exe or
(self.base.options.output_mode == .Lib and self.base.options.link_mode == .Dynamic);

View File

@ -613,6 +613,7 @@ fn buildOutputType(
var subsystem: ?std.Target.SubSystem = null;
var major_subsystem_version: ?u32 = null;
var minor_subsystem_version: ?u32 = null;
var wasi_exec_model: ?Compilation.WasiExecModel = null;
var system_libs = std.ArrayList([]const u8).init(gpa);
defer system_libs.deinit();
@ -1254,6 +1255,13 @@ fn buildOutputType(
.framework => try frameworks.append(it.only_arg),
.nostdlibinc => want_native_include_dirs = false,
.strip => strip = true,
.exec_model => {
if (std.mem.eql(u8, it.only_arg, "reactor")) {
wasi_exec_model = Compilation.WasiExecModel.reactor;
} else if (std.mem.eql(u8, it.only_arg, "command")) {
wasi_exec_model = Compilation.WasiExecModel.command;
}
},
}
}
// Parse linker args.
@ -1969,6 +1977,7 @@ fn buildOutputType(
.test_name_prefix = test_name_prefix,
.disable_lld_caching = !have_enable_cache,
.subsystem = subsystem,
.wasi_exec_model = wasi_exec_model,
}) catch |err| {
fatal("unable to create compilation: {s}", .{@errorName(err)});
};
@ -3341,6 +3350,7 @@ pub const ClangArgIterator = struct {
red_zone,
no_red_zone,
strip,
exec_model,
};
const Args = struct {

View File

@ -336,6 +336,10 @@ const known_options = [_]KnownOpt{
.name = "dynamiclib",
.ident = "shared",
},
.{
.name = "mexec-model",
.ident = "exec_model",
}
};
const blacklisted_options = [_][]const u8{};