From 98cbb47031e12e02f91bffc9950efb17498e8a03 Mon Sep 17 00:00:00 2001 From: luccie-cmd Date: Wed, 6 Aug 2025 11:40:32 +0200 Subject: [PATCH] [MODS/WASM] Add some more instructions --- modding/log.zig | 8 +++---- src/mods/Parser.zig | 1 + src/mods/vm.zig | 54 +++++++++++++++++++++++++++++++-------------- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/modding/log.zig b/modding/log.zig index acaa787..3ccdee6 100644 --- a/modding/log.zig +++ b/modding/log.zig @@ -1,19 +1,19 @@ pub extern fn logErr( string: *const u8, len: u64, -) void; +) callconv(.c) void; pub extern fn logWarn( string: *const u8, len: u64, -) void; +) callconv(.c) void; pub extern fn logInfo( string: *const u8, len: u64, -) void; +) callconv(.c) void; pub extern fn logDebug( string: *const u8, len: u64, -) void; +) callconv(.c) void; diff --git a/src/mods/Parser.zig b/src/mods/Parser.zig index 0a18b2d..7327f0d 100644 --- a/src/mods/Parser.zig +++ b/src/mods/Parser.zig @@ -25,6 +25,7 @@ const PAGE_SIZE = 65536; pub const Error = error{ OutOfMemory, + DivideBy0, Overflow, invalid_instruction, invalid_magic, diff --git a/src/mods/vm.zig b/src/mods/vm.zig index cb1c355..ee621b2 100644 --- a/src/mods/vm.zig +++ b/src/mods/vm.zig @@ -105,7 +105,7 @@ pub const Runtime = struct { std.log.warn("Growing memory is not yet supported, usign the minimum memory\n", .{}); } const memory = try allocator.alloc(u8, max); - std.crypto.secureZero(u8, memory); + @memset(memory, 0); @memcpy(memory[0..module.data.len], module.data); return Runtime{ .module = module, @@ -124,6 +124,7 @@ pub const Runtime = struct { loop: while (frame.program_counter < frame.code.opcodes.len) { const opcode: IR.Opcode = frame.code.opcodes[frame.program_counter]; const index = frame.code.indices[frame.program_counter]; + // std.debug.print("Executing at {X} {any} \n", .{frame.program_counter, opcode}); switch (opcode) { .@"unreachable" => { std.debug.panic("Reached unreachable statement at IR counter {any}\n", .{frame.program_counter}); @@ -225,11 +226,7 @@ pub const Runtime = struct { // TODO(ernesto): This code is repeated... .i32_load => { - const offsetVal = self.stack.pop().?.i32; - if (offsetVal < 0) { - std.debug.panic("offsetVal is negative (val: {any} arg: {any})\n", .{ offsetVal, index.memarg }); - } - const start = index.memarg.offset + @as(u32, @intCast(offsetVal)); + const start = index.memarg.offset + @as(u32, @intCast(self.stack.pop().?.i32)); const end = start + @sizeOf(i32); try self.stack.append(.{ .i32 = std.mem.littleToNative(i32, std.mem.bytesAsValue(i32, self.memory[start..end]).*) }); }, @@ -252,10 +249,16 @@ pub const Runtime = struct { .i32_load8_u => { const start = index.memarg.offset + @as(u32, @intCast(self.stack.pop().?.i32)); const end = start + @sizeOf(u8); - try self.stack.append(.{ .i32 = std.mem.littleToNative(u8, std.mem.bytesAsValue(u8, self.memory[start..end]).*) }); + const raw_value = std.mem.readInt(u8, @as(*const [1]u8, @ptrCast(self.memory[start..end])), std.builtin.Endian.little); + try self.stack.append(.{ .i32 = @intCast(@as(u32, raw_value)) }); }, .i32_load16_s => @panic("UNIMPLEMENTED"), - .i32_load16_u => @panic("UNIMPLEMENTED"), + .i32_load16_u => { + const start = index.memarg.offset + @as(u32, @intCast(self.stack.pop().?.i32)); + const end = start + @sizeOf(u16); + const raw_value = std.mem.readInt(u16, @as(*const [2]u8, @ptrCast(self.memory[start..end])), std.builtin.Endian.little); + try self.stack.append(.{ .i32 = @intCast(@as(u32, raw_value)) }); + }, .i64_load8_s => @panic("UNIMPLEMENTED"), .i64_load8_u => @panic("UNIMPLEMENTED"), .i64_load16_s => @panic("UNIMPLEMENTED"), @@ -265,7 +268,7 @@ pub const Runtime = struct { const start = index.memarg.offset + @as(u32, @intCast(self.stack.pop().?.i32)); const end = start + @sizeOf(u32); const raw_value = std.mem.readInt(u32, @as(*const [4]u8, @ptrCast(self.memory[start..end])), std.builtin.Endian.little); - try self.stack.append(.{ .i64 = @intCast(@as(u64, raw_value)) }); // Zero-extend + try self.stack.append(.{ .i64 = @intCast(@as(u64, raw_value)) }); }, .i32_store => { const val = std.mem.nativeToLittle(i32, self.stack.pop().?.i32); @@ -282,7 +285,7 @@ pub const Runtime = struct { const val = std.mem.nativeToLittle(i64, self.stack.pop().?.i64); const offsetVal = self.stack.pop().?.i32; if (offsetVal < 0) { - std.debug.panic("offsetVal is negative (val: {any} ip: {any} prev: {any} next: {any})\n", .{ offsetVal, frame.program_counter, frame.code.opcodes[frame.program_counter - 1], frame.code.opcodes[frame.program_counter + 1] }); + std.debug.panic("offsetVal is negative (val: {any})\n", .{offsetVal}); } const offset: u64 = @intCast(offsetVal); const start: usize = @intCast(@as(u64, index.memarg.offset) + offset); @@ -344,9 +347,14 @@ pub const Runtime = struct { .f64_const => @panic("UNIMPLEMENTED"), .i32_eqz => { - try self.stack.append(Value{ .i32 = @intCast(@as(u1, @bitCast(self.stack.pop().?.i32 == 0))) }); + const val = self.stack.pop().?.i32; + try self.stack.append(Value{ .i32 = @intFromBool(val == 0) }); + }, + .i32_eq => { + const a = self.stack.pop().?.i32; + const b = self.stack.pop().?.i32; + try self.stack.append(Value{ .i32 = @intCast(@as(u1, @bitCast(a == b))) }); }, - .i32_eq => @panic("UNIMPLEMENTED"), .i32_ne => { const a = self.stack.pop().?.i32; const b = self.stack.pop().?.i32; @@ -378,7 +386,8 @@ pub const Runtime = struct { }, .i64_eqz => { - try self.stack.append(Value{ .i32 = @intCast(@as(u1, @bitCast(self.stack.pop().?.i64 == 0))) }); + const val = self.stack.pop().?.i64; + try self.stack.append(Value{ .i64 = @intFromBool(val == 0) }); }, .i64_eq => @panic("UNIMPLEMENTED"), .i64_ne => @panic("UNIMPLEMENTED"), @@ -439,13 +448,24 @@ pub const Runtime = struct { try self.stack.append(Value{ .i32 = @bitCast(b_unsigned / a_unsigned) }); }, .i32_rem_s => @panic("UNIMPLEMENTED"), - .i32_rem_u => @panic("UNIMPLEMENTED"), + .i32_rem_u => { + const divisor = self.stack.pop().?.i32; + const dividend = self.stack.pop().?.i32; + if (divisor == 0) { + std.debug.panic("Divide by 0\n", .{}); + } + try self.stack.append(Value{ .i32 = dividend - divisor * @divTrunc(dividend, divisor) }); + }, .i32_or => { const a = self.stack.pop().?.i32; const b = self.stack.pop().?.i32; try self.stack.append(Value{ .i32 = a | b }); }, - .i32_xor => @panic("UNIMPLEMENTED"), + .i32_xor => { + const a = self.stack.pop().?.i32; + const b = self.stack.pop().?.i32; + try self.stack.append(Value{ .i32 = a ^ b }); + }, .i32_shl => { const a = self.stack.pop().?.i32; const b = self.stack.pop().?.i32; @@ -586,7 +606,9 @@ pub const Runtime = struct { pub fn call(self: *Runtime, allocator: Allocator, function: usize, parameters: []Value) AllocationError!void { const f = self.module.functions[function]; - reverseSlice(parameters); + if (parameters.len > 1){ + reverseSlice(parameters); + } switch (f.typ) { .internal => { const ir: IR = f.typ.internal.ir;