summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.zig29
-rw-r--r--src/main.zig7
-rw-r--r--src/mods/Parser.zig2
-rw-r--r--src/mods/ir.zig279
-rw-r--r--src/mods/mods.zig5
5 files changed, 317 insertions, 5 deletions
diff --git a/build.zig b/build.zig
index 6e17bb6..0fbbc59 100644
--- a/build.zig
+++ b/build.zig
@@ -55,14 +55,22 @@ pub fn build(b: *std.Build) void {
}, .flags = &[_][]const u8{ "-D_GLFW_X11", "-Wall", "-Wextra" } });
glfw.linkLibC();
+ const mods = b.addModule("mods", .{
+ .root_source_file = b.path("src/mods/mods.zig"),
+ .target = target,
+ .optimize = optimize,
+ });
+
const exe = b.addExecutable(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.name = "sideros",
});
+ exe.root_module.addImport("mods", mods);
exe.addIncludePath(b.path("ext/glfw/include"));
+
exe.linkSystemLibrary("vulkan");
compileAllShaders(b, exe);
exe.linkLibrary(glfw);
@@ -70,6 +78,27 @@ pub fn build(b: *std.Build) void {
b.installArtifact(exe);
+ // TODO: This does not generate documentation correctly?
+ const install_docs = b.addInstallDirectory(.{
+ .source_dir = exe.getEmittedDocs(),
+ .install_dir = .prefix,
+ .install_subdir = "docs",
+ });
+ const docs_step = b.step("docs", "Generate documentation");
+ docs_step.dependOn(&install_docs.step);
+
+ // NOTE: This is a hack to generate documentation
+ const mods_lib = b.addStaticLibrary(.{
+ .root_module = mods,
+ .name = "mods",
+ });
+ const mods_docs = b.addInstallDirectory(.{
+ .source_dir = mods_lib.getEmittedDocs(),
+ .install_dir = .prefix,
+ .install_subdir = "docs/mods",
+ });
+ docs_step.dependOn(&mods_docs.step);
+
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
diff --git a/src/main.zig b/src/main.zig
index 97aa5bf..e8ff1d1 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -5,9 +5,8 @@ const window = @import("rendering/window.zig");
const config = @import("config");
const Renderer = @import("rendering/renderer_vulkan.zig");
const math = @import("math.zig");
-const Parser = @import("mods/Parser.zig");
-const vm = @import("mods/vm.zig");
-const wasm = @import("mods/wasm.zig");
+const mods = @import("mods");
+
const components = @import("ecs/components.zig");
const entities = @import("ecs/entities.zig");
@@ -30,7 +29,7 @@ pub fn main() !void {
// const file = try std.fs.cwd().openFile("assets/core.wasm", .{});
// const all = try file.readToEndAlloc(allocator, 1_000_000); // 1 MB
- // var parser = Parser{
+ // var parser = mods.Parser{
// .bytes = all,
// .byte_idx = 0,
// .allocator = allocator,
diff --git a/src/mods/Parser.zig b/src/mods/Parser.zig
index 29f18d8..d9f7ccf 100644
--- a/src/mods/Parser.zig
+++ b/src/mods/Parser.zig
@@ -144,7 +144,7 @@ fn parseReftype(self: *Parser) !std.wasm.RefType {
// NOTE: Parsing of Valtype can be improved but it makes it less close to spec so...
// TODO: Do we really need Valtype?
-const Valtype = union(enum) {
+pub const Valtype = union(enum) {
val: std.wasm.Valtype,
ref: std.wasm.RefType,
};
diff --git a/src/mods/ir.zig b/src/mods/ir.zig
new file mode 100644
index 0000000..ecb8d31
--- /dev/null
+++ b/src/mods/ir.zig
@@ -0,0 +1,279 @@
+const std = @import("std");
+const Parser = @import("Parser.zig");
+
+const Allocator = std.mem.Allocator;
+
+const DIndex = packed struct {
+ first: u32,
+ second: u32,
+};
+comptime {
+ // TODO: is this too big? we could do with 32 bits and a bit more indirection
+ std.debug.assert(@sizeOf(Index) == 8);
+}
+/// packed union has no tag
+const Index = packed union {
+ u32: u32,
+ i32: i32,
+ u64: u64,
+ i64: i64,
+ f32: f32,
+ f64: f64,
+ di: DIndex,
+};
+
+
+opcodes: []Opcode,
+/// Indices means something different depending on the Opcode.
+/// Read the docs of each opcode to know what the index means.
+indices: []Index,
+
+select_valtypes: []Parser.Valtype,
+
+/// Opcodes
+pub const Opcode = enum(u8) {
+ // CONTROL INSTRUCTIONS
+ // The rest of instructions should be implemented in terms of these ones
+ @"unreachable" = 0x00,
+ nop = 0x01,
+ /// Index: `u64`. Meaning: the next instruction pointer
+ br = 0x0C,
+ /// Index: `u64`. Meaning: the next instruction pointer
+ br_if = 0x0D,
+ /// TODO: this instruction (could be also implemented in terms of br and br_if)
+ br_table = 0x0E,
+ @"return" = 0x0F,
+ /// Index: `u64`. Meaning: The function index to call
+ call = 0x10,
+ /// TODO: index (is it enough with using a double index here? if we consider it enough then the other indices should use u32)
+ call_indirect = 0x11,
+
+ // REFERENCE INSTRUCTIONS
+ // This should be resolved at parse time and therefore not part of IR
+
+ // PARAMETRIC INSTRUCTIONS
+ // Select with no valtypes should be resolved at parse time
+ drop = 0x1A,
+ /// Index: `DIndex`. Meaning:
+ /// `first` is the index into `select_valtypes` array and
+ /// `second` is the number of valtypes
+ select = 0x1C,
+
+ // VARIABLE INSTRUCTIONS
+ /// Index: `u32`. Meaing: index into local variables
+ localget = 0x20,
+ /// Index: `u32`. Meaing: index into local variables
+ localset = 0x21,
+ /// Index: `u32`. Meaing: index into local variables
+ localtee = 0x22,
+ /// Index: `u32`. Meaing: index into global variables
+ globalget = 0x23,
+ /// Index: `u32`. Meaing: index into global variables
+ globalset = 0x24,
+
+ // TABLE INSTRUCTIONS
+ /// Index: `u32`. Meaning: index into table index
+ tableget = 0x25,
+ /// Index: `u32`. Meaning: index into table index
+ tableset = 0x26,
+ /// TODO: table operation. Value in wasm: 0xFC. Note wher is 0x27?
+ tableop = 0xF0,
+
+ // MEMORY INSTRUCTIONS
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32load = 0x28,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load = 0x29,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ f32load = 0x2A,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ f64load = 0x2B,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32load8_s = 0x2C,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32load8_u = 0x2D,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32load16_s = 0x2E,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32load16_u = 0x2F,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load8_s = 0x30,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load8_u = 0x31,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load16_s = 0x32,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load16_u = 0x33,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load32_s = 0x34,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64load32_u = 0x35,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32store = 0x36,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64store = 0x37,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ f32store = 0x38,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ f64store = 0x39,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32store8 = 0x3A,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i32store16 = 0x3B,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64store8 = 0x3C,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64store16 = 0x3D,
+ /// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
+ i64store32 = 0x3E,
+ memorysize = 0x3F,
+ memorygrow = 0x40,
+ /// TODO: memory operation. Value in wasm: 0xFC
+ memoryop = 0xF1,
+
+ // NUMERIC INSTRUCTION
+ /// Index: `i32`. Meaning: constant
+ i32const = 0x41,
+ /// Index: `i64`. Meaning: constant
+ i64const = 0x42,
+ /// Index: `f32`. Meaning: constant
+ f32const = 0x43,
+ /// Index: `f64`. Meaning: constant
+ f64const = 0x44,
+ i32eqz = 0x45,
+ i32eq = 0x46,
+ i32ne = 0x47,
+ i32lt_s = 0x48,
+ i32lt_u = 0x49,
+ i32gt_s = 0x4A,
+ i32gt_u = 0x4B,
+ i32le_s = 0x4C,
+ i32le_u = 0x4D,
+ i32ge_s = 0x4E,
+ i32ge_u = 0x4F,
+ i64eqz = 0x50,
+ i64eq = 0x51,
+ i64ne = 0x52,
+ i64lt_s = 0x53,
+ i64lt_u = 0x54,
+ i64gt_s = 0x55,
+ i64gt_u = 0x56,
+ i64le_s = 0x57,
+ i64le_u = 0x58,
+ i64ge_s = 0x59,
+ i64ge_u = 0x5A,
+ f32eq = 0x5B,
+ f32ne = 0x5C,
+ f32lt = 0x5D,
+ f32gt = 0x5E,
+ f32le = 0x5F,
+ f32ge = 0x60,
+ f64eq = 0x61,
+ f64ne = 0x62,
+ f64lt = 0x63,
+ f64gt = 0x64,
+ f64le = 0x65,
+ f64ge = 0x66,
+ i32clz = 0x67,
+ i32ctz = 0x68,
+ i32popcnt = 0x69,
+ i32add = 0x6A,
+ i32sub = 0x6B,
+ i32mul = 0x6C,
+ i32div_s = 0x6D,
+ i32div_u = 0x6E,
+ i32rem_s = 0x6F,
+ i32rem_u = 0x70,
+ i32and = 0x71,
+ i32or = 0x72,
+ i32xor = 0x73,
+ i32shl = 0x74,
+ i32shr_s = 0x75,
+ i32shr_u = 0x76,
+ i32rotl = 0x77,
+ i32rotr = 0x78,
+ i64clz = 0x79,
+ i64ctz = 0x7A,
+ i64popcnt = 0x7B,
+ i64add = 0x7C,
+ i64sub = 0x7D,
+ i64mul = 0x7E,
+ i64div_s = 0x7F,
+ i64div_u = 0x80,
+ i64rem_s = 0x81,
+ i64rem_u = 0x82,
+ i64and = 0x83,
+ i64or = 0x84,
+ i64xor = 0x85,
+ i64shl = 0x86,
+ i64shr_s = 0x87,
+ i64shr_u = 0x88,
+ i64rotl = 0x89,
+ i64rotr = 0x8A,
+ f32abs = 0x8B,
+ f32neg = 0x8C,
+ f32ceil = 0x8D,
+ f32floor = 0x8E,
+ f32trunc = 0x8F,
+ f32nearest = 0x90,
+ f32sqrt = 0x91,
+ f32add = 0x92,
+ f32sub = 0x93,
+ f32mul = 0x94,
+ f32div = 0x95,
+ f32min = 0x96,
+ f32max = 0x97,
+ f32copysign = 0x98,
+ f64abs = 0x99,
+ f64neg = 0x9A,
+ f64ceil = 0x9B,
+ f64floor = 0x9C,
+ f64trunc = 0x9D,
+ f64nearest = 0x9E,
+ f64sqrt = 0x9F,
+ f64add = 0xA0,
+ f64sub = 0xA1,
+ f64mul = 0xA2,
+ f64div = 0xA3,
+ f64min = 0xA4,
+ f64max = 0xA5,
+ f64copysign = 0xA6,
+ i32wrap_i64 = 0xA7,
+ i32trunc_f32_s = 0xA8,
+ i32trunc_f32_u = 0xA9,
+ i32trunc_f64_s = 0xAA,
+ i32trunc_f64_u = 0xAB,
+ i64extend_i32_s = 0xAC,
+ i64extend_i32_u = 0xAD,
+ i64trunc_f32_s = 0xAE,
+ i64trunc_f32_u = 0xAF,
+ i64trunc_f64_s = 0xB0,
+ i64trunc_f64_u = 0xB1,
+ f32convert_i32_s = 0xB2,
+ f32convert_i32_u = 0xB3,
+ f32convert_i64_s = 0xB4,
+ f32convert_i64_u = 0xB5,
+ f32demote_f64 = 0xB6,
+ f64convert_i32_s = 0xB7,
+ f64convert_i32_u = 0xB8,
+ f64convert_i64_s = 0xB9,
+ f64convert_i64_u = 0xBA,
+ f64promote_f32 = 0xBB,
+ i32reinterpret_f32 = 0xBC,
+ i64reinterpret_f64 = 0xBD,
+ f32reinterpret_i32 = 0xBE,
+ f64reinterpret_i64 = 0xBF,
+ i32extend8_s = 0xC0,
+ i32extend16_s = 0xC1,
+ i64extend8_s = 0xC2,
+ i64extend16_s = 0xC3,
+ i64extend32_s = 0xC4,
+ /// TODO: saturation truncation instructions. Value in wasm: 0xFC
+ sattrunc = 0xF2,
+
+ // VECTOR INSTRUCTIONS
+ /// TODO: vector instructions. Value in wasm: 0xFC. Note: there are opcodes available lol
+ vecinst = 0xF3,
+
+};
+
diff --git a/src/mods/mods.zig b/src/mods/mods.zig
new file mode 100644
index 0000000..9d845e1
--- /dev/null
+++ b/src/mods/mods.zig
@@ -0,0 +1,5 @@
+pub const Parser = @import("Parser.zig");
+pub const VM = @import("vm.zig");
+// TODO: is this really needed?
+pub const Wasm = @import("wasm.zig");
+pub const IR = @import("ir.zig");