[MAIN]: Rewrote init_mods to load tar archives and run main.wasm
This commit is contained in:
parent
f0af9b9955
commit
120da3e3cd
4 changed files with 84 additions and 25 deletions
BIN
assets/mods/core.tar
Normal file
BIN
assets/mods/core.tar
Normal file
Binary file not shown.
Binary file not shown.
|
|
@ -103,9 +103,6 @@ pub const Runtime = struct {
|
|||
pub fn init(allocator: Allocator, module: Module, global_runtime: *wasm.GlobalRuntime) !Runtime {
|
||||
// if memory max is not set the memory is allowed to grow but it is not supported at the moment
|
||||
const max = module.memory.max orelse module.memory.min;
|
||||
if (module.memory.max == null) {
|
||||
std.log.warn("Growing memory is not yet supported, usign the minimum memory\n", .{});
|
||||
}
|
||||
const memory = try allocator.alloc(u8, max);
|
||||
@memset(memory, 0);
|
||||
@memcpy(memory[0..module.data.len], module.data);
|
||||
|
|
@ -336,8 +333,12 @@ pub const Runtime = struct {
|
|||
.memorysize => @panic("UNIMPLEMENTED"),
|
||||
.memorygrow => {
|
||||
const newPages = self.stack.pop().?.i32;
|
||||
const newSize = (self.memory.len / Parser.PAGE_SIZE) + @as(usize, @intCast(newPages));
|
||||
if (self.module.memory.max != null and newSize > self.module.memory.max.?){
|
||||
std.debug.panic("Mod failed to stay within memory range\n", .{});
|
||||
}
|
||||
const oldPages: i32 = @intCast(self.memory.len / Parser.PAGE_SIZE);
|
||||
self.memory = try allocator.realloc(self.memory, self.memory.len + @as(usize, @intCast(newPages * Parser.PAGE_SIZE)));
|
||||
self.memory = try allocator.realloc(self.memory, newSize * Parser.PAGE_SIZE);
|
||||
try self.stack.append(.{ .i32 = oldPages });
|
||||
},
|
||||
.memoryinit => @panic("UNIMPLEMENTED"),
|
||||
|
|
|
|||
100
src/sideros.zig
100
src/sideros.zig
|
|
@ -21,32 +21,82 @@ var camera: rendering.Camera = .{
|
|||
};
|
||||
var input: ecs.Input = .{ .key_pressed = .{false} ** @intFromEnum(ecs.Input.KeyCode.menu) };
|
||||
var resources: ecs.Resources = undefined;
|
||||
const ModInfo = struct {
|
||||
name: []const u8,
|
||||
runtime: mods.Runtime,
|
||||
modIdx: u32,
|
||||
};
|
||||
var loadedMods: std.ArrayListUnmanaged(ModInfo) = .{};
|
||||
|
||||
fn openOrCreateDir(fs: std.fs.Dir, path: []const u8) !std.fs.Dir {
|
||||
var dir: std.fs.Dir = undefined;
|
||||
dir = fs.openDir(path, .{.iterate = true}) catch |err| {
|
||||
if (err == std.fs.Dir.OpenError.FileNotFound) {
|
||||
try fs.makeDir(path);
|
||||
dir = try fs.openDir(path, .{.iterate = true});
|
||||
return dir;
|
||||
} else {
|
||||
return err;
|
||||
}
|
||||
};
|
||||
return dir;
|
||||
}
|
||||
|
||||
fn untarToDirAndGetFile(fs: std.fs.Dir, name: []const u8) !std.fs.File {
|
||||
var modDir = try openOrCreateDir(fs,name);
|
||||
defer modDir.close();
|
||||
var buffer: [1024]u8 = undefined;
|
||||
var tarFile = try fs.openFile(try std.fmt.bufPrint(&buffer, "{s}.tar", .{name}), .{});
|
||||
defer tarFile.close();
|
||||
const tarData = try tarFile.readToEndAlloc(allocator, 1_000_000);
|
||||
var tarReader = std.io.Reader.fixed(tarData);
|
||||
try std.tar.pipeToFileSystem(modDir, &tarReader, .{});
|
||||
return try fs.openFile(try std.fmt.bufPrint(&buffer, "{s}/main.wasm", .{name}), .{});
|
||||
}
|
||||
|
||||
fn init_mods() void {
|
||||
var global_runtime = mods.GlobalRuntime.init(allocator);
|
||||
|
||||
const file = std.fs.cwd().openFile("assets/mods/core.wasm", .{}) catch @panic("Couldn't open assets/mods/core.wasm");
|
||||
// const file = std.fs.cwd().openFile("./test.wasm", .{}) catch @panic("Couldn't open test.wasm");
|
||||
const all = file.readToEndAlloc(allocator, 1_000_000) catch @panic("Unable to read the file"); // 1 MB
|
||||
defer allocator.free(all);
|
||||
var parser = mods.Parser.init(allocator, all) catch @panic("Failed to init parser");
|
||||
defer parser.deinit();
|
||||
parser.parseModule() catch |err| {
|
||||
std.debug.panic("[ERROR]: error {any} at byte {x}(0x{x})\n", .{ err, parser.byte_idx, parser.bytes[parser.byte_idx] });
|
||||
};
|
||||
const module = parser.module();
|
||||
var modsDir = std.fs.cwd().openDir("./assets/mods", .{.iterate = true}) catch @panic("Failed to open assets/mods");
|
||||
defer modsDir.close();
|
||||
|
||||
for (0..parser.globalTypes.len) |i| {
|
||||
global_runtime.addGlobal(@intCast(i), parser.globalTypes[i], parser.globalValues[i]) catch @panic("Failed to add runtime global");
|
||||
var modsDirIter = modsDir.iterate();
|
||||
while (modsDirIter.next() catch @panic("Failed to get next iteration of mods directory")) |entry| {
|
||||
if (entry.kind != std.fs.File.Kind.file){
|
||||
std.debug.panic("TODO: Search recursively for mods\n", .{});
|
||||
}
|
||||
const extension = entry.name.ptr[entry.name.len - 4..entry.name.len];
|
||||
if (!std.mem.eql(u8, extension, ".tar")){
|
||||
std.debug.print("[WARNING]: Found non tar extension in mods directory\n", .{});
|
||||
continue;
|
||||
}
|
||||
const fullDir = std.fmt.allocPrint(allocator, "assets/mods/{s}", .{entry.name.ptr[0..entry.name.len - 4]}) catch @panic("Failed to allocate for fullDir");
|
||||
var global_runtime = mods.GlobalRuntime.init(allocator);
|
||||
|
||||
var file = untarToDirAndGetFile(std.fs.cwd(), fullDir) catch @panic("Failed to load mod");
|
||||
defer file.close();
|
||||
const all = file.readToEndAlloc(allocator, 1_000_000) catch @panic("Unable to read main file");
|
||||
defer allocator.free(all);
|
||||
var parser = mods.Parser.init(allocator, all) catch @panic("Failed to init parser");
|
||||
defer parser.deinit();
|
||||
parser.parseModule() catch |err| {
|
||||
std.debug.panic("[ERROR]: error {any} at byte {x}(0x{x})\n", .{ err, parser.byte_idx, parser.bytes[parser.byte_idx] });
|
||||
};
|
||||
const module = parser.module();
|
||||
|
||||
for (0..parser.globalTypes.len) |i| {
|
||||
global_runtime.addGlobal(@intCast(i), parser.globalTypes[i], parser.globalValues[i]) catch @panic("Failed to add runtime global");
|
||||
}
|
||||
|
||||
var runtime = mods.Runtime.init(allocator, module, &global_runtime) catch @panic("Failed to init runtime");
|
||||
|
||||
const modIdx: u32 = @intCast(loadedMods.items.len);
|
||||
var parameters = [_]mods.VM.Value{.{ .i32 = @intCast(modIdx) }};
|
||||
runtime.externalCall(allocator, .init, ¶meters) catch @panic("Failed to call to init");
|
||||
const result = runtime.stack.pop().?;
|
||||
std.debug.print("Result of {s} init: {any}\n", .{fullDir, result});
|
||||
loadedMods.append(allocator, .{.name = fullDir, .runtime = runtime, .modIdx = modIdx}) catch @panic("Failed to append to loadedMods");
|
||||
std.fs.cwd().deleteTree(fullDir) catch std.debug.panic("Failed to delete {s}", .{fullDir});
|
||||
}
|
||||
|
||||
var runtime = mods.Runtime.init(allocator, module, &global_runtime) catch @panic("Failed to init runtime");
|
||||
defer runtime.deinit(allocator);
|
||||
|
||||
var parameters = [_]mods.VM.Value{.{ .i32 = 17 }};
|
||||
runtime.externalCall(allocator, .init, ¶meters) catch @panic("Failed to call to init");
|
||||
const result = runtime.stack.pop().?;
|
||||
std.debug.print("Result of init: {any}\n", .{result});
|
||||
}
|
||||
|
||||
export fn sideros_init(init: api.GameInit) callconv(.c) void {
|
||||
|
|
@ -71,6 +121,14 @@ export fn sideros_update(gameUpdate: api.GameUpdate) callconv(.c) void {
|
|||
}
|
||||
|
||||
export fn sideros_cleanup() callconv(.c) void {
|
||||
for (loadedMods.items) |info| {
|
||||
var runtime = info.runtime;
|
||||
// runtime.externalCall(allocator, .deinit, &.{});
|
||||
// const result = runtime.stack.pop().?;
|
||||
// std.debug.print("Result of {s} init: {any}\n", .{info.name, result});
|
||||
runtime.deinit(allocator);
|
||||
}
|
||||
loadedMods.deinit(allocator);
|
||||
renderer.deinit();
|
||||
pool.deinit();
|
||||
if (gpa.deinit() != .ok) @panic("Memory leaked");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue