From aa9a9ad3d3e3968494a0d1c5d6e3980b4ea136f0 Mon Sep 17 00:00:00 2001 From: Mahdi Sharifi Date: Wed, 24 Jan 2024 15:15:34 +0330 Subject: [PATCH] Make Kivi independent from Zig's std --- src/core/ByteMap.zig | 22 +- src/core/Kivi.zig | 1 - src/core/Math.zig | 32 +++ src/core/Mmap.zig | 69 +++--- src/core/Syscall.zig | 221 ++++++++++++++++++ src/core/Wyhash.zig | 33 ++- src/core/main.zig | 5 +- .../js/runtimes/nodejs/functions/common.zig | 2 +- .../js/runtimes/nodejs/functions/del.zig | 3 - .../js/runtimes/nodejs/functions/get.zig | 1 - .../js/runtimes/nodejs/functions/rm.zig | 1 - .../js/runtimes/nodejs/functions/set.zig | 1 - src/drivers/js/runtimes/nodejs/main.zig | 3 +- .../js/runtimes/nodejs/napi-bindings.zig | 3 + .../js/runtimes/nodejs/symbols-win.zig | 55 +++++ src/drivers/js/runtimes/nodejs/symbols.zig | 74 +----- 16 files changed, 393 insertions(+), 133 deletions(-) create mode 100644 src/core/Math.zig create mode 100644 src/core/Syscall.zig create mode 100644 src/drivers/js/runtimes/nodejs/symbols-win.zig diff --git a/src/core/ByteMap.zig b/src/core/ByteMap.zig index 0fbdf61..688661f 100644 --- a/src/core/ByteMap.zig +++ b/src/core/ByteMap.zig @@ -1,8 +1,8 @@ /// This is Byte(u8) hashmap implementation that relies on the caller to handle allocations and lifetimes. -const std = @import("std"); const memsimd = @import("memsimd"); const builtin = @import("builtin"); const Wyhash = @import("./Wyhash.zig"); +const Math = @import("Math.zig"); const Mmap = @import("./Mmap.zig"); // Key == null and value == null : empty slot @@ -12,6 +12,19 @@ const Entry = struct { value: ?[]u8 = null, }; +// pub const CrtlEmpty: u8 = 0b10000000; +// pub const CrtlDeleted: u8 = 0b11111110; +// pub const CrtlSentinel: u8 = 0b11111111; +// const Crtl = packed struct(u8) { +// Empty: u8 = CrtlEmpty, +// }; +// fn h1(hash: usize) usize { +// return hash >> 7; +// } +// fn h2(hash: usize) Crtl { +// return hash & 0x7f; +// } + fn nosimd_eql_byte(a: []const u8, b: []const u8) bool { return memsimd.nosimd.eql(u8, a, b); } @@ -38,11 +51,10 @@ const ByteMap = @This(); table: []Entry, table_size: usize, -var collisions: usize = 0; var hasher = Wyhash.init(0); pub fn init(self: *ByteMap, allocator: *Mmap, size_arg: usize) !void { - self.table_size = try std.math.ceilPowerOfTwo(usize, size_arg); + self.table_size = @intCast(Math.ceilPowerOfTwo(@intCast(size_arg))); self.table = try allocator.alloc(Entry, self.table_size); for (0..self.table_size) |idx| { @@ -88,7 +100,6 @@ fn find_entry(self: *ByteMap, key: []const u8, comptime insertion: bool) ?*Entry return entry; } else { index += 1; - collisions += 1; } } @@ -129,6 +140,5 @@ pub fn put(self: *ByteMap, key: []u8, value: []u8) !void { pub fn deinit(self: *ByteMap) void { _ = self; // autofix - std.debug.print("Collisions: {any}\n", .{collisions}); - collisions = 0; + // collisions = 0; } diff --git a/src/core/Kivi.zig b/src/core/Kivi.zig index 6f53b24..1f01ce6 100644 --- a/src/core/Kivi.zig +++ b/src/core/Kivi.zig @@ -1,4 +1,3 @@ -const std = @import("std"); const MMap = @import("Mmap.zig"); const memsimd = @import("memsimd"); const ByteMap = @import("ByteMap.zig"); diff --git a/src/core/Math.zig b/src/core/Math.zig new file mode 100644 index 0000000..bc31fc5 --- /dev/null +++ b/src/core/Math.zig @@ -0,0 +1,32 @@ +const Math = @This(); + +pub fn alignBackward(comptime T: type, addr: T, alignment: T) T { + // TODO: Panic + // assert(isValidAlignGeneric(T, alignment)); + + // 000010000 // example alignment + // 000001111 // subtract 1 + // 111110000 // binary not + return addr & ~(alignment - 1); +} + +pub fn alignForward(comptime T: type, addr: T, alignment: T) T { + // TODO: Panic + // assert(isValidAlignGeneric(T, alignment)); + + return alignBackward(T, addr + (alignment - 1), alignment); +} + +pub fn ceilPowerOfTwo(n_arg: u64) u64 { + var n = n_arg; + n -= 1; + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + n |= n >> 32; + n += 1; + + return n; +} diff --git a/src/core/Mmap.zig b/src/core/Mmap.zig index b282ff0..c26a8c0 100644 --- a/src/core/Mmap.zig +++ b/src/core/Mmap.zig @@ -1,20 +1,19 @@ -const std = @import("std"); const builtin = @import("builtin"); +const Syscall = @import("Syscall.zig"); +const Math = @import("Math.zig"); -const maxU32 = std.math.maxInt(u32); -const maxU64 = std.math.maxInt(u64); const is_windows: bool = builtin.os.tag == .windows; -var empty_freelist = FreelistNode{ .len = 0, .next = null }; const FreelistNode = packed struct { len: usize, next: ?*FreelistNode, }; +var empty_freelist = FreelistNode{ .len = 0, .next = null }; cursor: usize, freelist: *FreelistNode, -mem: []align(std.mem.page_size) u8, -page_size: usize, +mem: []align(Syscall.page_size) u8, +mprotect_size: usize, protected_mem_cursor: usize, const Mmap = @This(); @@ -27,37 +26,39 @@ pub fn byte_slice_cast(comptime T: type, value: []u8) []T { } fn mprotect(self: *Mmap) !void { - const protected_mem_cursor = self.protected_mem_cursor + self.page_size; + const protected_mem_cursor = self.protected_mem_cursor + self.mprotect_size; if (!is_windows) { - try std.os.mprotect(@alignCast(self.mem[self.protected_mem_cursor..protected_mem_cursor]), std.os.PROT.READ | std.os.PROT.WRITE); + try Syscall.mprotect(@alignCast(self.mem[self.protected_mem_cursor..protected_mem_cursor]), Syscall.PROT.READ | Syscall.PROT.WRITE); } else { + const std = @import("std"); _ = try std.os.windows.VirtualAlloc(@ptrCast(@alignCast(self.mem)), protected_mem_cursor, std.os.windows.MEM_COMMIT, std.os.windows.PAGE_READWRITE); } self.protected_mem_cursor = protected_mem_cursor; } -pub fn init(total_size: usize, page_size: usize) !Mmap { - var mem: []align(std.mem.page_size) u8 = undefined; - const size = std.mem.alignForward(usize, total_size, std.mem.page_size); +pub fn init(total_size: usize, mprotect_size: usize) !Mmap { + var mem: []align(Syscall.page_size) u8 = undefined; + const size = Math.alignForward(usize, total_size, Syscall.page_size); if (!is_windows) { - mem = try std.os.mmap( + mem = try Syscall.mmap( null, size, - std.os.PROT.NONE, - std.os.MAP.ANONYMOUS | std.os.MAP.PRIVATE, + Syscall.PROT.NONE, + Syscall.MAP.ANONYMOUS | Syscall.MAP.PRIVATE, -1, 0, ); } else { + const std = @import("std"); const lpvoid = try std.os.windows.VirtualAlloc(null, size, std.os.windows.MEM_RESERVE, std.os.windows.PAGE_NOACCESS); mem.len = size; mem.ptr = @alignCast(@ptrCast(lpvoid)); } - var mmap = Mmap{ .mem = mem, .cursor = 0, .protected_mem_cursor = 0, .freelist = &empty_freelist, .page_size = std.mem.alignForward(usize, page_size, std.mem.page_size) }; + var mmap = Mmap{ .mem = mem, .cursor = 0, .protected_mem_cursor = 0, .freelist = &empty_freelist, .mprotect_size = Math.alignForward(usize, mprotect_size, Syscall.page_size) }; mmap.mprotect() catch unreachable; return mmap; @@ -87,7 +88,7 @@ pub fn alloc_byte(self: *Mmap, size: usize) ![]u8 { const starting_pos = self.cursor; var ending_pos: usize = starting_pos + 16; if (size > 16) { - ending_pos += std.mem.alignForward(usize, size - 16, 8); + ending_pos += Math.alignForward(usize, size - 16, 8); } if (ending_pos > self.protected_mem_cursor) { @@ -110,30 +111,28 @@ pub fn alloc(self: *Mmap, comptime T: type, n: usize) ![]T { } pub fn free(self: *Mmap, data: []u8) void { - _ = self; // autofix - _ = data; // autofix - // const freelist = @as(*FreelistNode, @alignCast(@ptrCast(data.ptr))); - - // if (data.len > 16) { - // freelist.len = @intCast(std.mem.alignForward(usize, data.len, 8)); - // } else { - // freelist.len = 16; - // } - - // if (self.freelist.len != 0) { - // freelist.next = self.freelist; - // } else { - // freelist.next = null; - // } - - // self.freelist = freelist; - return; + const freelist = @as(*FreelistNode, @alignCast(@ptrCast(data.ptr))); + + if (data.len > 16) { + freelist.len = @intCast(Math.alignForward(usize, data.len, 8)); + } else { + freelist.len = 16; + } + + if (self.freelist.len != 0) { + freelist.next = self.freelist; + } else { + freelist.next = null; + } + + self.freelist = freelist; } pub fn deinit(self: *Mmap) void { if (!is_windows) { - std.os.munmap(self.mem); + Syscall.unmap(self.mem); } else { + const std = @import("std"); std.os.windows.VirtualFree(@alignCast(@ptrCast(self.mem.ptr)), 0, std.os.windows.MEM_RELEASE); } } diff --git a/src/core/Syscall.zig b/src/core/Syscall.zig new file mode 100644 index 0000000..10ee3f0 --- /dev/null +++ b/src/core/Syscall.zig @@ -0,0 +1,221 @@ +const builtin = @import("builtin"); + +const Syscall = @This(); + +pub const page_size = switch (builtin.cpu.arch) { + .wasm32, .wasm64 => 64 * 1024, + .aarch64 => switch (builtin.os.tag) { + .macos, .ios, .watchos, .tvos => 16 * 1024, + else => 4 * 1024, + }, + .sparc64 => 8 * 1024, + else => 4 * 1024, +}; + +pub const SyscallType = enum(usize) { + read = 0, + write = 1, + open = 2, + close = 3, + stat = 4, + fstat = 5, + lstat = 6, + poll = 7, + lseek = 8, + mmap = 9, + mprotect = 10, + munmap = 11, + brk = 12, +}; + +const SyscallErr = enum(u16) { + /// No error occurred. + /// Same code used for `NSROK`. + SUCCESS = 0, + /// Operation not permitted + PERM = 1, + /// No such file or directory + NOENT = 2, + /// No such process + SRCH = 3, + /// Interrupted system call + INTR = 4, + /// I/O error + IO = 5, + /// No such device or address + NXIO = 6, + /// Arg list too long + @"2BIG" = 7, + /// Exec format error + NOEXEC = 8, + /// Bad file number + BADF = 9, + /// No child processes + CHILD = 10, + /// Try again + /// Also means: WOULDBLOCK: operation would block + AGAIN = 11, + /// Out of memory + NOMEM = 12, + /// Permission denied + ACCES = 13, + /// Bad address + FAULT = 14, + /// Block device required + NOTBLK = 15, + /// Device or resource busy + BUSY = 16, + /// File exists + EXIST = 17, +}; + +pub const PROT = struct { + /// page can not be accessed + pub const NONE = 0x0; + /// page can be read + pub const READ = 0x1; + /// page can be written + pub const WRITE = 0x2; + /// page can be executed + pub const EXEC = 0x4; + /// page may be used for atomic ops + pub const SEM = 0x8; + /// mprotect flag: extend change to start of growsdown vma + pub const GROWSDOWN = 0x01000000; + /// mprotect flag: extend change to end of growsup vma + pub const GROWSUP = 0x02000000; +}; +pub const MAP = struct { + /// Share changes + pub const SHARED = 0x01; + /// Changes are private + pub const PRIVATE = 0x02; + /// share + validate extension flags + pub const SHARED_VALIDATE = 0x03; + /// Mask for type of mapping + pub const TYPE = 0x0f; + /// Interpret addr exactly + pub const FIXED = 0x10; + /// don't use a file + pub const ANONYMOUS = 0x20; + // MAP_ 0x0100 - 0x4000 flags are per architecture + /// populate (prefault) pagetables + pub const POPULATE = 0x8000; + /// do not block on IO + pub const NONBLOCK = 0x10000; + /// give out an address that is best suited for process/thread stacks + pub const STACK = 0x20000; + /// create a huge page mapping + pub const HUGETLB = 0x40000; + /// perform synchronous page faults for the mapping + pub const SYNC = 0x80000; + /// MAP_FIXED which doesn't unmap underlying mapping + pub const FIXED_NOREPLACE = 0x100000; + /// For anonymous mmap, memory could be uninitialized + pub const UNINITIALIZED = 0x4000000; +}; + +pub fn get_syserr(r: usize) SyscallErr { + @setRuntimeSafety(false); + const signed_r = @as(isize, @bitCast(r)); + const int = if (signed_r > -4096 and signed_r < 0) -signed_r else 0; + return @as(SyscallErr, @enumFromInt(int)); +} + +fn syscall(syscall_type: SyscallType, args: anytype) usize { + @setRuntimeSafety(false); + return switch (args.len) { + 1 => asm volatile ("syscall" + : [ret] "={rax}" (-> usize), + : [syscall_type] "{rax}" (syscall_type), + [a0] "{rdi}" (args[0]), + : "rcx", "r11", "memory" + ), + 2 => asm volatile ("syscall" + : [ret] "={rax}" (-> usize), + : [syscall_type] "{rax}" (syscall_type), + [a0] "{rdi}" (args[0]), + [a1] "{rsi}" (args[1]), + : "rcx", "r11", "memory" + ), + 3 => asm volatile ("syscall" + : [ret] "={rax}" (-> usize), + : [syscall_type] "{rax}" (syscall_type), + [a0] "{rdi}" (args[0]), + [a1] "{rsi}" (args[1]), + [a2] "{rdx}" (args[2]), + : "rcx", "r11", "memory" + ), + 4 => asm volatile ("syscall" + : [ret] "={rax}" (-> usize), + : [syscall_type] "{rax}" (syscall_type), + [a0] "{rdi}" (args[0]), + [a1] "{rsi}" (args[1]), + [a2] "{rdx}" (args[2]), + [a3] "{r10}" (args[3]), + : "rcx", "r11", "memory" + ), + 5 => asm volatile ("syscall" + : [ret] "={rax}" (-> usize), + : [syscall_type] "{rax}" (syscall_type), + [a0] "{rdi}" (args[0]), + [a1] "{rsi}" (args[1]), + [a2] "{rdx}" (args[2]), + [a3] "{r10}" (args[3]), + [a4] "{r8}" (args[4]), + : "rcx", "r11", "memory" + ), + 6 => asm volatile ("syscall" + : [ret] "={rax}" (-> usize), + : [syscall_type] "{rax}" (syscall_type), + [a0] "{rdi}" (args[0]), + [a1] "{rsi}" (args[1]), + [a2] "{rdx}" (args[2]), + [a3] "{r10}" (args[3]), + [a4] "{r8}" (args[4]), + [a5] "{r9}" (args[5]), + : "rcx", "r11", "memory" + ), + else => @compileError("Invalid number of arguments to syscall!"), + }; +} + +pub fn mmap( + ptr: ?[*]align(page_size) u8, + length: usize, + prot: u32, + flags: u32, + fd: i32, + offset: u64, +) ![]align(page_size) u8 { + @setRuntimeSafety(false); + const res = syscall(.mmap, .{ + @intFromPtr(ptr), + length, + prot, + flags, + @as(usize, @bitCast(@as(isize, fd))), + @as(u64, @bitCast(offset)), + }); + + if (get_syserr(res) == .SUCCESS) { + return @as([*]align(page_size) u8, @ptrFromInt(res))[0..length]; + } + return error.FailedToAllocateMmap; +} + +pub fn mprotect(memory: []align(page_size) u8, protection: u32) !void { + @setRuntimeSafety(false); + // TODO: Panic + // assert(isAligned(memory.len, page_size)); + + const res = syscall(.mprotect, .{ @intFromPtr(memory.ptr), memory.len, protection }); + if (get_syserr(res) != .SUCCESS) { + return error.FailedToMprotect; + } +} + +pub fn unmap(memory: []align(page_size) const u8) void { + @setRuntimeSafety(false); + _ = syscall(.munmap, .{ @intFromPtr(memory.ptr), memory.len }); +} diff --git a/src/core/Wyhash.zig b/src/core/Wyhash.zig index f8a7671..3c2e426 100644 --- a/src/core/Wyhash.zig +++ b/src/core/Wyhash.zig @@ -1,4 +1,4 @@ -const std = @import("std"); +const builtin = @import("builtin"); const Wyhash = @This(); @@ -105,7 +105,8 @@ inline fn shallowCopy(self: *Wyhash) Wyhash { } inline fn smallKey(self: *Wyhash, input: []const u8) void { - std.debug.assert(input.len <= 16); + // TODO: Panic + // std.debug.assert(input.len <= 16); if (input.len >= 4) { const end = input.len - 4; @@ -129,10 +130,26 @@ inline fn round(self: *Wyhash, input: *const [48]u8) void { } } +pub const Endian = enum { + big, + little, +}; +const native_endian = builtin.cpu.arch.endian(); +pub inline fn readInt(comptime T: type, buffer: *const [@divExact(@typeInfo(T).Int.bits, 8)]u8, endian: Endian) T { + const value: T = @bitCast(buffer.*); + return if (@intFromEnum(endian) == @intFromEnum(native_endian)) value else @byteSwap(value); +} + inline fn read(comptime bytes: usize, data: []const u8) u64 { - std.debug.assert(bytes <= 8); - const T = std.meta.Int(.unsigned, 8 * bytes); - return @as(u64, std.mem.readInt(T, data[0..bytes], .little)); + // TODO: Panic + // std.debug.assert(bytes <= 8); + + return @as(u64, readInt(@Type(.{ + .Int = .{ + .signedness = .unsigned, + .bits = 8 * bytes, + }, + }), data[0..bytes], .little)); } inline fn mum(a: *u64, b: *u64) void { @@ -156,8 +173,10 @@ inline fn final0(self: *Wyhash) void { // used instead). We use an index into a slice to for comptime processing as opposed to if we // used pointers. inline fn final1(self: *Wyhash, input_lb: []const u8, start_pos: usize) void { - std.debug.assert(input_lb.len >= 16); - std.debug.assert(input_lb.len - start_pos <= 48); + // TODO: Panic + // std.debug.assert(input_lb.len >= 16); + // std.debug.assert(input_lb.len - start_pos <= 48); + const input = input_lb[start_pos..]; var i: usize = 0; diff --git a/src/core/main.zig b/src/core/main.zig index 7a6ac3e..88f40ea 100644 --- a/src/core/main.zig +++ b/src/core/main.zig @@ -1,16 +1,17 @@ -const std = @import("std"); const builtin = @import("builtin"); pub const Kivi = @import("Kivi.zig"); // For debug info in FFI -const is_debug = builtin.mode == std.builtin.Mode.Debug; +const is_debug = builtin.mode == .Debug; pub export fn dump_stack_trace() void { if (is_debug) { + const std = @import("std"); std.debug.dumpCurrentStackTrace(@returnAddress()); } } pub export fn setup_debug_handlers() void { if (is_debug) { + const std = @import("std"); std.debug.maybeEnableSegfaultHandler(); } } diff --git a/src/drivers/js/runtimes/nodejs/functions/common.zig b/src/drivers/js/runtimes/nodejs/functions/common.zig index ed2124d..d1f29f0 100644 --- a/src/drivers/js/runtimes/nodejs/functions/common.zig +++ b/src/drivers/js/runtimes/nodejs/functions/common.zig @@ -1,6 +1,6 @@ const Kivi = @import("Kivi"); const ntypes = @import("../napi-bindings.zig"); -const symbols = @import("../symbols.zig"); +const symbols = @import("../symbols.zig").Symbols; pub fn get_null(env: ntypes.napi_env) ntypes.napi_value { var null_value: ntypes.napi_value = undefined; diff --git a/src/drivers/js/runtimes/nodejs/functions/del.zig b/src/drivers/js/runtimes/nodejs/functions/del.zig index cedb0de..717ffe4 100644 --- a/src/drivers/js/runtimes/nodejs/functions/del.zig +++ b/src/drivers/js/runtimes/nodejs/functions/del.zig @@ -1,9 +1,6 @@ const Kivi = @import("Kivi"); const common = @import("common.zig"); const ntypes = @import("../napi-bindings.zig"); -const symbols = @import("../symbols.zig"); - -const std = @import("std"); pub export fn kivi_del_js(env: ntypes.napi_env, info: ntypes.napi_callback_info) ntypes.napi_value { const args = common.parse_args(env, info, 2) catch { diff --git a/src/drivers/js/runtimes/nodejs/functions/get.zig b/src/drivers/js/runtimes/nodejs/functions/get.zig index 58b2218..0db9a40 100644 --- a/src/drivers/js/runtimes/nodejs/functions/get.zig +++ b/src/drivers/js/runtimes/nodejs/functions/get.zig @@ -1,7 +1,6 @@ const Kivi = @import("Kivi"); const common = @import("common.zig"); const ntypes = @import("../napi-bindings.zig"); -const symbols = @import("../symbols.zig"); pub export fn kivi_get_js(env: ntypes.napi_env, info: ntypes.napi_callback_info) ntypes.napi_value { const args = common.parse_args(env, info, 2) catch { diff --git a/src/drivers/js/runtimes/nodejs/functions/rm.zig b/src/drivers/js/runtimes/nodejs/functions/rm.zig index 27b0d63..92ee5a4 100644 --- a/src/drivers/js/runtimes/nodejs/functions/rm.zig +++ b/src/drivers/js/runtimes/nodejs/functions/rm.zig @@ -1,7 +1,6 @@ const Kivi = @import("Kivi"); const common = @import("common.zig"); const ntypes = @import("../napi-bindings.zig"); -const symbols = @import("../symbols.zig"); pub export fn kivi_rm_js(env: ntypes.napi_env, info: ntypes.napi_callback_info) ntypes.napi_value { const args = common.parse_args(env, info, 2) catch { diff --git a/src/drivers/js/runtimes/nodejs/functions/set.zig b/src/drivers/js/runtimes/nodejs/functions/set.zig index 9694cfa..4558bac 100644 --- a/src/drivers/js/runtimes/nodejs/functions/set.zig +++ b/src/drivers/js/runtimes/nodejs/functions/set.zig @@ -1,7 +1,6 @@ const Kivi = @import("Kivi"); const common = @import("common.zig"); const ntypes = @import("../napi-bindings.zig"); -const symbols = @import("../symbols.zig"); pub export fn kivi_set_js(env: ntypes.napi_env, info: ntypes.napi_callback_info) ntypes.napi_value { const args = common.parse_args(env, info, 3) catch { diff --git a/src/drivers/js/runtimes/nodejs/main.zig b/src/drivers/js/runtimes/nodejs/main.zig index 25312a8..7483cd8 100644 --- a/src/drivers/js/runtimes/nodejs/main.zig +++ b/src/drivers/js/runtimes/nodejs/main.zig @@ -1,7 +1,6 @@ -const std = @import("std"); const Kivi = @import("Kivi"); const ntypes = @import("napi-bindings.zig"); -const symbols = @import("symbols.zig"); +const symbols = @import("symbols.zig").Symbols; const common = @import("functions/common.zig"); pub const set = @import("functions/set.zig"); diff --git a/src/drivers/js/runtimes/nodejs/napi-bindings.zig b/src/drivers/js/runtimes/nodejs/napi-bindings.zig index df415e1..a836942 100644 --- a/src/drivers/js/runtimes/nodejs/napi-bindings.zig +++ b/src/drivers/js/runtimes/nodejs/napi-bindings.zig @@ -1,3 +1,6 @@ +// Written by hand +pub fn init_symbols() void {} + pub const ptrdiff_t = c_long; pub const wchar_t = c_int; pub const max_align_t = extern struct { diff --git a/src/drivers/js/runtimes/nodejs/symbols-win.zig b/src/drivers/js/runtimes/nodejs/symbols-win.zig new file mode 100644 index 0000000..de27303 --- /dev/null +++ b/src/drivers/js/runtimes/nodejs/symbols-win.zig @@ -0,0 +1,55 @@ +pub const c = @import("napi-bindings.zig"); + +pub var napi_create_string_utf8: *const @TypeOf(c.napi_create_string_utf8) = undefined; +pub var napi_create_uint32: *const @TypeOf(c.napi_create_uint32) = undefined; +pub var napi_define_properties: *const @TypeOf(c.napi_define_properties) = undefined; +pub var napi_get_arraybuffer_info: *const @TypeOf(c.napi_get_arraybuffer_info) = undefined; +pub var napi_get_buffer_info: *const @TypeOf(c.napi_get_buffer_info) = undefined; +pub var napi_get_cb_info: *const @TypeOf(c.napi_get_cb_info) = undefined; +pub var napi_get_null: *const @TypeOf(c.napi_get_null) = undefined; +pub var napi_get_undefined: *const @TypeOf(c.napi_get_undefined) = undefined; +pub var napi_get_value_string_utf8: *const @TypeOf(c.napi_get_value_string_utf8) = undefined; +pub var napi_throw_error: *const @TypeOf(c.napi_throw_error) = undefined; +pub var napi_get_element: *const @TypeOf(c.napi_get_element) = undefined; +pub var napi_get_array_length: *const @TypeOf(c.napi_get_array_length) = undefined; +pub var napi_create_array_with_length: *const @TypeOf(c.napi_create_array_with_length) = undefined; +pub var napi_set_element: *const @TypeOf(c.napi_set_element) = undefined; +pub var napi_get_named_property: *const @TypeOf(c.napi_get_named_property) = undefined; +pub var napi_get_boolean: *const @TypeOf(c.napi_get_boolean) = undefined; +pub var napi_is_buffer: *const @TypeOf(c.napi_is_buffer) = undefined; +pub var napi_is_arraybuffer: *const @TypeOf(c.napi_is_arraybuffer) = undefined; +pub var napi_create_buffer_copy: *const @TypeOf(c.napi_create_buffer_copy) = undefined; + +const std = @import("std"); +const kernel32 = std.os.windows.kernel32; +var windows_handle: ?std.os.windows.HMODULE = null; +fn load_sym(comptime T: type, name: []const u8) T { + return @ptrCast(@alignCast(kernel32.GetProcAddress(windows_handle.?, name.ptr).?)); +} + +pub fn init_symbols() void { + windows_handle = kernel32.GetModuleHandleW(null); + if (windows_handle == null) { + // TODO: Panic + } + + napi_create_string_utf8 = load_sym(*const @TypeOf(c.napi_create_string_utf8), "napi_create_string_utf8"); + napi_create_uint32 = load_sym(*const @TypeOf(c.napi_create_uint32), "napi_create_uint32"); + napi_define_properties = load_sym(*const @TypeOf(c.napi_define_properties), "napi_define_properties"); + napi_get_arraybuffer_info = load_sym(*const @TypeOf(c.napi_get_arraybuffer_info), "napi_get_arraybuffer_info"); + napi_get_buffer_info = load_sym(*const @TypeOf(c.napi_get_buffer_info), "napi_get_buffer_info"); + napi_get_cb_info = load_sym(*const @TypeOf(c.napi_get_cb_info), "napi_get_cb_info"); + napi_get_null = load_sym(*const @TypeOf(c.napi_get_null), "napi_get_null"); + napi_get_undefined = load_sym(*const @TypeOf(c.napi_get_undefined), "napi_get_undefined"); + napi_get_value_string_utf8 = load_sym(*const @TypeOf(c.napi_get_value_string_utf8), "napi_get_value_string_utf8"); + napi_throw_error = load_sym(*const @TypeOf(c.napi_throw_error), "napi_throw_error"); + napi_get_element = load_sym(*const @TypeOf(c.napi_get_element), "napi_get_element"); + napi_get_array_length = load_sym(*const @TypeOf(c.napi_get_array_length), "napi_get_array_length"); + napi_create_array_with_length = load_sym(*const @TypeOf(c.napi_create_array_with_length), "napi_create_array_with_length"); + napi_set_element = load_sym(*const @TypeOf(c.napi_set_element), "napi_set_element"); + napi_get_named_property = load_sym(*const @TypeOf(c.napi_get_named_property), "napi_get_named_property"); + napi_get_boolean = load_sym(*const @TypeOf(c.napi_get_boolean), "napi_get_boolean"); + napi_is_buffer = load_sym(*const @TypeOf(c.napi_is_buffer), "napi_is_buffer"); + napi_is_arraybuffer = load_sym(*const @TypeOf(c.napi_is_arraybuffer), "napi_is_arraybuffer"); + napi_create_buffer_copy = load_sym(*const @TypeOf(c.napi_create_buffer_copy), "napi_create_buffer_copy"); +} diff --git a/src/drivers/js/runtimes/nodejs/symbols.zig b/src/drivers/js/runtimes/nodejs/symbols.zig index 3e60d53..613ccd6 100644 --- a/src/drivers/js/runtimes/nodejs/symbols.zig +++ b/src/drivers/js/runtimes/nodejs/symbols.zig @@ -1,77 +1,5 @@ -const std = @import("std"); const builtin = @import("builtin"); -pub const c = @import("napi-bindings.zig"); -pub var napi_create_string_utf8: *const @TypeOf(c.napi_create_string_utf8) = undefined; -pub var napi_create_uint32: *const @TypeOf(c.napi_create_uint32) = undefined; -pub var napi_define_properties: *const @TypeOf(c.napi_define_properties) = undefined; -pub var napi_get_arraybuffer_info: *const @TypeOf(c.napi_get_arraybuffer_info) = undefined; -pub var napi_get_buffer_info: *const @TypeOf(c.napi_get_buffer_info) = undefined; -pub var napi_get_cb_info: *const @TypeOf(c.napi_get_cb_info) = undefined; -pub var napi_get_null: *const @TypeOf(c.napi_get_null) = undefined; -pub var napi_get_undefined: *const @TypeOf(c.napi_get_undefined) = undefined; -pub var napi_get_value_string_utf8: *const @TypeOf(c.napi_get_value_string_utf8) = undefined; -pub var napi_throw_error: *const @TypeOf(c.napi_throw_error) = undefined; -pub var napi_get_element: *const @TypeOf(c.napi_get_element) = undefined; -pub var napi_get_array_length: *const @TypeOf(c.napi_get_array_length) = undefined; -pub var napi_create_array_with_length: *const @TypeOf(c.napi_create_array_with_length) = undefined; -pub var napi_set_element: *const @TypeOf(c.napi_set_element) = undefined; -pub var napi_get_named_property: *const @TypeOf(c.napi_get_named_property) = undefined; -pub var napi_get_boolean: *const @TypeOf(c.napi_get_boolean) = undefined; -pub var napi_is_buffer: *const @TypeOf(c.napi_is_buffer) = undefined; -pub var napi_is_arraybuffer: *const @TypeOf(c.napi_is_arraybuffer) = undefined; -pub var napi_create_buffer_copy: *const @TypeOf(c.napi_create_buffer_copy) = undefined; - -const kernel32 = std.os.windows.kernel32; const is_windows = builtin.target.os.tag == .windows; -var windows_handle: ?std.os.windows.HMODULE = null; -fn load_sym(comptime T: type, name: []const u8) T { - return @ptrCast(@alignCast(kernel32.GetProcAddress(windows_handle.?, name.ptr).?)); -} - -pub fn init_symbols() void { - if (is_windows) { - windows_handle = kernel32.GetModuleHandleW(null); - if (windows_handle == null) { - std.debug.panic("Failed to get the module handle!", .{}); - } - napi_create_string_utf8 = load_sym(*const @TypeOf(c.napi_create_string_utf8), "napi_create_string_utf8"); - napi_create_uint32 = load_sym(*const @TypeOf(c.napi_create_uint32), "napi_create_uint32"); - napi_define_properties = load_sym(*const @TypeOf(c.napi_define_properties), "napi_define_properties"); - napi_get_arraybuffer_info = load_sym(*const @TypeOf(c.napi_get_arraybuffer_info), "napi_get_arraybuffer_info"); - napi_get_buffer_info = load_sym(*const @TypeOf(c.napi_get_buffer_info), "napi_get_buffer_info"); - napi_get_cb_info = load_sym(*const @TypeOf(c.napi_get_cb_info), "napi_get_cb_info"); - napi_get_null = load_sym(*const @TypeOf(c.napi_get_null), "napi_get_null"); - napi_get_undefined = load_sym(*const @TypeOf(c.napi_get_undefined), "napi_get_undefined"); - napi_get_value_string_utf8 = load_sym(*const @TypeOf(c.napi_get_value_string_utf8), "napi_get_value_string_utf8"); - napi_throw_error = load_sym(*const @TypeOf(c.napi_throw_error), "napi_throw_error"); - napi_get_element = load_sym(*const @TypeOf(c.napi_get_element), "napi_get_element"); - napi_get_array_length = load_sym(*const @TypeOf(c.napi_get_array_length), "napi_get_array_length"); - napi_create_array_with_length = load_sym(*const @TypeOf(c.napi_create_array_with_length), "napi_create_array_with_length"); - napi_set_element = load_sym(*const @TypeOf(c.napi_set_element), "napi_set_element"); - napi_get_named_property = load_sym(*const @TypeOf(c.napi_get_named_property), "napi_get_named_property"); - napi_get_boolean = load_sym(*const @TypeOf(c.napi_get_boolean), "napi_get_boolean"); - napi_is_buffer = load_sym(*const @TypeOf(c.napi_is_buffer), "napi_is_buffer"); - napi_is_arraybuffer = load_sym(*const @TypeOf(c.napi_is_arraybuffer), "napi_is_arraybuffer"); - napi_create_buffer_copy = load_sym(*const @TypeOf(c.napi_create_buffer_copy), "napi_create_buffer_copy"); - } else { - napi_create_string_utf8 = c.napi_create_string_utf8; - napi_create_uint32 = c.napi_create_uint32; - napi_define_properties = c.napi_define_properties; - napi_get_arraybuffer_info = c.napi_get_arraybuffer_info; - napi_get_buffer_info = c.napi_get_buffer_info; - napi_get_cb_info = c.napi_get_cb_info; - napi_get_null = c.napi_get_null; - napi_get_undefined = c.napi_get_undefined; - napi_get_value_string_utf8 = c.napi_get_value_string_utf8; - napi_throw_error = c.napi_throw_error; - napi_get_element = c.napi_get_element; - napi_get_array_length = c.napi_get_array_length; - napi_create_array_with_length = c.napi_create_array_with_length; - napi_set_element = c.napi_set_element; - napi_is_buffer = c.napi_is_buffer; - napi_is_arraybuffer = c.napi_is_arraybuffer; - napi_create_buffer_copy = c.napi_create_buffer_copy; - } -} +pub const Symbols = if (is_windows) @import("symbols-win.zig") else @import("napi-bindings.zig");