From 4b8a7f477436a64fea9c12f53b5502ce04439c0d Mon Sep 17 00:00:00 2001 From: Nathan Craddock Date: Thu, 18 Jan 2024 21:20:13 -0700 Subject: [PATCH 1/4] Remove shared from buildLuau function --- build.zig | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/build.zig b/build.zig index ea9f3b4..27775f7 100644 --- a/build.zig +++ b/build.zig @@ -50,7 +50,7 @@ pub fn build(b: *Build) void { } const lib = switch (lang) { - .luau => buildLuau(b, target, optimize, upstream, shared, luau_use_4_vector), + .luau => buildLuau(b, target, optimize, upstream, luau_use_4_vector), else => buildLua(b, target, optimize, upstream, lang, shared), }; @@ -205,17 +205,13 @@ fn installHeader(cs: *Build.Step.Compile, src_path: Build.LazyPath, dest_rel_pat } /// Luau has diverged enough from Lua (C++, project structure, ...) that it is easier to separate the build logic -fn buildLuau(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, upstream: *Build.Dependency, shared: bool, luau_use_4_vector: bool) *Step.Compile { - const lib_opts = .{ +fn buildLuau(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, upstream: *Build.Dependency, luau_use_4_vector: bool) *Step.Compile { + const lib = b.addStaticLibrary(.{ .name = "luau", .target = target, .optimize = optimize, .version = std.SemanticVersion{ .major = 0, .minor = 607, .patch = 0 }, - }; - const lib = if (shared) - b.addSharedLibrary(lib_opts) - else - b.addStaticLibrary(lib_opts); + }); lib.addIncludePath(upstream.path("Common/include")); lib.addIncludePath(upstream.path("Compiler/include")); From 2308ddaadc891c49ec013b870ae72f1080f45de2 Mon Sep 17 00:00:00 2001 From: Nathan Craddock Date: Thu, 18 Jan 2024 21:28:05 -0700 Subject: [PATCH 2/4] Use addCSourceFiles This is simpler than looping over the files --- build.zig | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/build.zig b/build.zig index 27775f7..313a48c 100644 --- a/build.zig +++ b/build.zig @@ -182,9 +182,13 @@ fn buildLua(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.Optim .lua54 => &lua_54_source_files, else => unreachable, }; - for (lua_source_files) |file| { - lib.addCSourceFile(.{ .file = upstream.path(file), .flags = &flags }); - } + + lib.addCSourceFiles(.{ + .dependency = upstream, + .files = lua_source_files, + .flags = &flags, + }); + lib.linkLibC(); installHeader(lib, upstream.path("src/lua.h"), "lua.h"); @@ -226,9 +230,11 @@ fn buildLuau(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.Opti if (luau_use_4_vector) "-DLUA_VECTOR_SIZE=4" else "", }; - for (luau_source_files) |file| { - lib.addCSourceFile(.{ .file = upstream.path(file), .flags = &flags }); - } + lib.addCSourceFiles(.{ + .dependency = upstream, + .files = &luau_source_files, + .flags = &flags, + }); lib.addCSourceFile(.{ .file = .{ .path = "src/luau.cpp" }, .flags = &flags }); lib.linkLibCpp(); From 41a615699103595a8e0d0e68315bb646d4adee3b Mon Sep 17 00:00:00 2001 From: Nathan Craddock Date: Thu, 18 Jan 2024 21:38:33 -0700 Subject: [PATCH 3/4] Remove duplication in Lua source file arrays --- build.zig | 97 +++---------------------------------------------------- 1 file changed, 5 insertions(+), 92 deletions(-) diff --git a/build.zig b/build.zig index 313a48c..4a40bfa 100644 --- a/build.zig +++ b/build.zig @@ -176,7 +176,7 @@ fn buildLua(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.Optim }; const lua_source_files = switch (lang) { - .lua51 => &lua_51_source_files, + .lua51 => &lua_base_source_files, .lua52 => &lua_52_source_files, .lua53 => &lua_53_source_files, .lua54 => &lua_54_source_files, @@ -246,7 +246,7 @@ fn buildLuau(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.Opti return lib; } -const lua_51_source_files = [_][]const u8{ +const lua_base_source_files = [_][]const u8{ "src/lapi.c", "src/lcode.c", "src/ldebug.c", @@ -278,110 +278,23 @@ const lua_51_source_files = [_][]const u8{ "src/linit.c", }; -const lua_52_source_files = [_][]const u8{ - "src/lapi.c", - "src/lcode.c", +const lua_52_source_files = lua_base_source_files ++ [_][]const u8{ "src/lctype.c", - "src/ldebug.c", - "src/ldo.c", - "src/ldump.c", - "src/lfunc.c", - "src/lgc.c", - "src/llex.c", - "src/lmem.c", - "src/lobject.c", - "src/lopcodes.c", - "src/lparser.c", - "src/lstate.c", - "src/lstring.c", - "src/ltable.c", - "src/ltm.c", - "src/lundump.c", - "src/lvm.c", - "src/lzio.c", - "src/lauxlib.c", - "src/lbaselib.c", "src/lbitlib.c", "src/lcorolib.c", - "src/ldblib.c", - "src/liolib.c", - "src/lmathlib.c", - "src/loslib.c", - "src/lstrlib.c", - "src/ltablib.c", - "src/loadlib.c", - "src/linit.c", }; -const lua_53_source_files = [_][]const u8{ - "src/lapi.c", - "src/lcode.c", +const lua_53_source_files = lua_base_source_files ++ [_][]const u8{ "src/lctype.c", - "src/ldebug.c", - "src/ldo.c", - "src/ldump.c", - "src/lfunc.c", - "src/lgc.c", - "src/llex.c", - "src/lmem.c", - "src/lobject.c", - "src/lopcodes.c", - "src/lparser.c", - "src/lstate.c", - "src/lstring.c", - "src/ltable.c", - "src/ltm.c", - "src/lundump.c", - "src/lvm.c", - "src/lzio.c", - "src/lauxlib.c", - "src/lbaselib.c", "src/lbitlib.c", "src/lcorolib.c", - "src/ldblib.c", - "src/liolib.c", - "src/lmathlib.c", - "src/loslib.c", - "src/lstrlib.c", - "src/ltablib.c", "src/lutf8lib.c", - "src/loadlib.c", - "src/linit.c", }; -const lua_54_source_files = [_][]const u8{ - "src/lapi.c", - "src/lcode.c", +const lua_54_source_files = lua_base_source_files ++ [_][]const u8{ "src/lctype.c", - "src/ldebug.c", - "src/ldo.c", - "src/ldump.c", - "src/lfunc.c", - "src/lgc.c", - "src/llex.c", - "src/lmem.c", - "src/lobject.c", - "src/lopcodes.c", - "src/lparser.c", - "src/lstate.c", - "src/lstring.c", - "src/ltable.c", - "src/ltm.c", - "src/lundump.c", - "src/lvm.c", - "src/lzio.c", - "src/lauxlib.c", - "src/lbaselib.c", "src/lcorolib.c", - "src/ldblib.c", - "src/liolib.c", - "src/lmathlib.c", - "src/loadlib.c", - "src/loslib.c", - "src/lstrlib.c", - "src/ltablib.c", "src/lutf8lib.c", - "src/linit.c", }; const luau_source_files = [_][]const u8{ From 87695fcf185b9a543b9e3f6bbbe01fc2fe87928d Mon Sep 17 00:00:00 2001 From: Nathan Craddock Date: Fri, 19 Jan 2024 22:14:47 -0700 Subject: [PATCH 4/4] Add initial LuaJIT support Adds the latest release of LuaJIT v2.1 and all necessary build file changes to build as a static library. This has only been tested on aarch64 macos. Many LuaJIT flags are missing from the build config. Even if it works, it may not be working perfectly. Uses the Lua 51 library bindings, so some additional LuaJIT functions may be missing. These will be audited and added at a later time. Part of #19 --- build.zig | 261 ++++++++++++++++++++++++++++++++++++++++++++++++++ build.zig.zon | 5 + src/lib51.zig | 2 + src/tests.zig | 57 +++++------ 4 files changed, 298 insertions(+), 27 deletions(-) diff --git a/build.zig b/build.zig index 4a40bfa..ddb23aa 100644 --- a/build.zig +++ b/build.zig @@ -8,6 +8,7 @@ pub const Language = enum { lua52, lua53, lua54, + luajit, luau, }; @@ -34,6 +35,7 @@ pub fn build(b: *Build) void { .lua52 => .{ .path = "src/lib52.zig" }, .lua53 => .{ .path = "src/lib53.zig" }, .lua54 => .{ .path = "src/lib54.zig" }, + .luajit => .{ .path = "src/lib51.zig" }, .luau => .{ .path = "src/libluau.zig" }, }, }); @@ -50,6 +52,7 @@ pub fn build(b: *Build) void { } const lib = switch (lang) { + .luajit => buildLuaJIT(b, target, optimize, upstream, shared), .luau => buildLuau(b, target, optimize, upstream, luau_use_4_vector), else => buildLua(b, target, optimize, upstream, lang, shared), }; @@ -118,6 +121,7 @@ pub fn build(b: *Build) void { .lua52 => .{ .path = "src/lib52.zig" }, .lua53 => .{ .path = "src/lib53.zig" }, .lua54 => .{ .path = "src/lib54.zig" }, + .luajit => .{ .path = "src/lib51.zig" }, .luau => .{ .path = "src/libluau.zig" }, }, }); @@ -131,6 +135,7 @@ pub fn build(b: *Build) void { .lua52 => "docs/lua52", .lua53 => "docs/lua53", .lua54 => "docs/lua54", + .luajit => "docs/luajit", .luau => "docs/luau", }, }); @@ -246,6 +251,187 @@ fn buildLuau(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.Opti return lib; } +fn buildLuaJIT(b: *Build, target: Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, upstream: *Build.Dependency, shared: bool) *Step.Compile { + // TODO: extract this to the main build function because it is shared between all specialized build functions + const lib_opts = .{ + .name = "lua", + .target = target, + .optimize = optimize, + }; + const lib: *Step.Compile = if (shared) + b.addSharedLibrary(lib_opts) + else + b.addStaticLibrary(lib_opts); + + // Compile minilua interpreter used at build time to generate files + const minilua = b.addExecutable(.{ + .name = "minilua", + .target = target, // TODO ensure this is the host + .optimize = .ReleaseSafe, + }); + minilua.linkLibC(); + minilua.root_module.sanitize_c = false; + minilua.addCSourceFile(.{.file = upstream.path("src/host/minilua.c")}); + + // Generate the buildvm_arch.h file using minilua + const dynasm_run = b.addRunArtifact(minilua); + dynasm_run.addFileArg(upstream.path("dynasm/dynasm.lua")); + + // TODO: Many more flags to figure out + if (target.result.cpu.arch.endian() == .little) { + dynasm_run.addArgs(&.{ "-D", "ENDIAN_LE" }); + } else { + dynasm_run.addArgs(&.{ "-D", "ENDIAN_BE" }); + } + + if (target.result.ptrBitWidth() == 64) dynasm_run.addArgs(&.{ "-D", "P64" }); + dynasm_run.addArgs(&.{ "-D", "JIT", "-D", "FFI" }); + + if (target.result.abi.floatAbi() == .hard) { + dynasm_run.addArgs(&.{ "-D", "FPU", "-D", "HFABI" }); + } + + if (target.result.os.tag == .windows) dynasm_run.addArgs(&.{ "-D", "WIN" }); + + dynasm_run.addArg("-o"); + const buildvm_arch_h = dynasm_run.addOutputFileArg("buildvm_arch.h"); + + dynasm_run.addFileArg(upstream.path(switch(target.result.cpu.arch) { + .x86 => "src/vm_x86.dasc", + .x86_64 => "src/vm_x64.dasc", + .arm, .armeb => "src/vm_arm.dasc", + .aarch64, .aarch64_be => "src/vm_arm64.dasc", + .powerpc, .powerpcle => "src/vm_ppc.dasc", + .mips, .mipsel => "src/vm_mips.dasc", + .mips64, .mips64el => "src/vm_mips64.dasc", + else => @panic("Unsupported architecture"), + })); + + // Generate luajit.h using minilua + const genversion_run = b.addRunArtifact(minilua); + genversion_run.addFileArg(upstream.path("src/host/genversion.lua")); + genversion_run.addFileArg(upstream.path("src/luajit_rolling.h")); + genversion_run.addFileArg(upstream.path(".relver")); + const luajit_h = genversion_run.addOutputFileArg("luajit.h"); + + // Compile the buildvm executable used to generate other files + const buildvm = b.addExecutable(.{ + .name = "buildvm", + .target = target, // TODO ensure this is the host + .optimize = .ReleaseSafe, + }); + buildvm.linkLibC(); + buildvm.root_module.sanitize_c = false; + + // Needs to run after the buildvm_arch.h and luajit.h files are generated + buildvm.step.dependOn(&dynasm_run.step); + buildvm.step.dependOn(&genversion_run.step); + + buildvm.addCSourceFiles(.{ + .dependency = upstream, + .files = &.{ "src/host/buildvm_asm.c", "src/host/buildvm_fold.c", "src/host/buildvm_lib.c", "src/host/buildvm_peobj.c", "src/host/buildvm.c" }, + }); + + buildvm.addIncludePath(upstream.path("src")); + buildvm.addIncludePath(upstream.path("src/host")); + buildvm.addIncludePath(buildvm_arch_h.dirname()); + buildvm.addIncludePath(luajit_h.dirname()); + + // Use buildvm to generate files and headers used in the final vm + const buildvm_bcdef = b.addRunArtifact(buildvm); + buildvm_bcdef.addArgs(&.{ "-m", "bcdef", "-o" }); + const bcdef_header = buildvm_bcdef.addOutputFileArg("lj_bcdef.h"); + for (luajit_lib) |file| { + buildvm_bcdef.addFileArg(upstream.path(file)); + } + + const buildvm_ffdef = b.addRunArtifact(buildvm); + buildvm_ffdef.addArgs(&.{ "-m", "ffdef", "-o" }); + const ffdef_header = buildvm_ffdef.addOutputFileArg("lj_ffdef.h"); + for (luajit_lib) |file| { + buildvm_ffdef.addFileArg(upstream.path(file)); + } + + const buildvm_libdef = b.addRunArtifact(buildvm); + buildvm_libdef.addArgs(&.{ "-m", "libdef", "-o" }); + const libdef_header = buildvm_libdef.addOutputFileArg("lj_libdef.h"); + for (luajit_lib) |file| { + buildvm_libdef.addFileArg(upstream.path(file)); + } + + const buildvm_recdef = b.addRunArtifact(buildvm); + buildvm_recdef.addArgs(&.{ "-m", "recdef", "-o" }); + const recdef_header = buildvm_recdef.addOutputFileArg("lj_recdef.h"); + for (luajit_lib) |file| { + buildvm_recdef.addFileArg(upstream.path(file)); + } + + const buildvm_folddef = b.addRunArtifact(buildvm); + buildvm_folddef.addArgs(&.{ "-m", "folddef", "-o" }); + const folddef_header = buildvm_folddef.addOutputFileArg("lj_folddef.h"); + for (luajit_lib) |file| { + buildvm_folddef.addFileArg(upstream.path(file)); + } + + const buildvm_ljvm = b.addRunArtifact(buildvm); + buildvm_ljvm.addArg("-m"); + + if (target.result.os.tag == .windows) { + buildvm_ljvm.addArg("peobj"); + } else if (target.result.isDarwin()) { + buildvm_ljvm.addArg("machasm"); + } else { + buildvm_ljvm.addArg("elfasm"); + } + + buildvm_ljvm.addArg("-o"); + if (target.result.os.tag == .windows) { + const ljvm_ob = buildvm_ljvm.addOutputFileArg("lj_vm. o"); + lib.addObjectFile(ljvm_ob); + } else { + const ljvm_asm = buildvm_ljvm.addOutputFileArg("lj_vm.S"); + lib.addAssemblyFile(ljvm_asm); + } + + // Finally build LuaJIT after generating all the files + lib.step.dependOn(&genversion_run.step); + lib.step.dependOn(&buildvm_bcdef.step); + lib.step.dependOn(&buildvm_ffdef.step); + lib.step.dependOn(&buildvm_libdef.step); + lib.step.dependOn(&buildvm_recdef.step); + lib.step.dependOn(&buildvm_folddef.step); + lib.step.dependOn(&buildvm_ljvm.step); + + lib.linkLibC(); + + lib.defineCMacro("LUAJIT_UNWIND_EXTERNAL", null); + lib.linkSystemLibrary("unwind"); + lib.root_module.unwind_tables = true; + + lib.addIncludePath(upstream.path("src")); + lib.addIncludePath(luajit_h.dirname()); + lib.addIncludePath(bcdef_header.dirname()); + lib.addIncludePath(ffdef_header.dirname()); + lib.addIncludePath(libdef_header.dirname()); + lib.addIncludePath(recdef_header.dirname()); + lib.addIncludePath(folddef_header.dirname()); + + lib.addCSourceFiles(.{ + .dependency = upstream, + .files = &luajit_vm, + }); + + lib.root_module.sanitize_c = false; + + installHeader(lib, upstream.path("src/lua.h"), "lua.h"); + installHeader(lib, upstream.path("src/lualib.h"), "lualib.h"); + installHeader(lib, upstream.path("src/lauxlib.h"), "lauxlib.h"); + installHeader(lib, upstream.path("src/luaconf.h"), "luaconf.h"); + installHeader(lib, luajit_h, "luajit.h"); + + return lib; +} + const lua_base_source_files = [_][]const u8{ "src/lapi.c", "src/lcode.c", @@ -297,6 +483,81 @@ const lua_54_source_files = lua_base_source_files ++ [_][]const u8{ "src/lutf8lib.c", }; +const luajit_lib = [_][]const u8 { + "src/lib_base.c", + "src/lib_math.c", + "src/lib_bit.c", + "src/lib_string.c", + "src/lib_table.c", + "src/lib_io.c", + "src/lib_os.c", + "src/lib_package.c", + "src/lib_debug.c", + "src/lib_jit.c", + "src/lib_ffi.c", + "src/lib_buffer.c", +}; + +const luajit_vm = luajit_lib ++ [_][]const u8{ + "src/lj_assert.c", + "src/lj_gc.c", + "src/lj_err.c", + "src/lj_char.c", + "src/lj_bc.c", + "src/lj_obj.c", + "src/lj_buf.c", + "src/lj_str.c", + "src/lj_tab.c", + "src/lj_func.c", + "src/lj_udata.c", + "src/lj_meta.c", + "src/lj_debug.c", + "src/lj_prng.c", + "src/lj_state.c", + "src/lj_dispatch.c", + "src/lj_vmevent.c", + "src/lj_vmmath.c", + "src/lj_strscan.c", + "src/lj_strfmt.c", + "src/lj_strfmt_num.c", + "src/lj_serialize.c", + "src/lj_api.c", + "src/lj_profile.c", + "src/lj_lex.c", + "src/lj_parse.c", + "src/lj_bcread.c", + "src/lj_bcwrite.c", + "src/lj_load.c", + "src/lj_ir.c", + "src/lj_opt_mem.c", + "src/lj_opt_fold.c", + "src/lj_opt_narrow.c", + "src/lj_opt_dce.c", + "src/lj_opt_loop.c", + "src/lj_opt_split.c", + "src/lj_opt_sink.c", + "src/lj_mcode.c", + "src/lj_snap.c", + "src/lj_record.c", + "src/lj_crecord.c", + "src/lj_ffrecord.c", + "src/lj_asm.c", + "src/lj_trace.c", + "src/lj_gdbjit.c", + "src/lj_ctype.c", + "src/lj_cdata.c", + "src/lj_cconv.c", + "src/lj_ccall.c", + "src/lj_ccallback.c", + "src/lj_carith.c", + "src/lj_clib.c", + "src/lj_cparse.c", + "src/lj_lib.c", + "src/lj_alloc.c", + "src/lib_aux.c", + "src/lib_init.c", +}; + const luau_source_files = [_][]const u8{ "Compiler/src/BuiltinFolding.cpp", "Compiler/src/Builtins.cpp", diff --git a/build.zig.zon b/build.zig.zon index 5a6e7e4..87fb0be 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -29,6 +29,11 @@ .hash = "1220f93ada1fa077ab096bf88a5b159ad421dbf6a478edec78ddb186d0c21d3476d9", }, + .luajit = .{ + .url = "https://github.com/LuaJIT/LuaJIT/archive/c525bcb9024510cad9e170e12b6209aedb330f83.tar.gz", + .hash = "1220ae2d84cfcc2a7aa670661491f21bbed102d335de18ce7d36866640fd9dfcc33a", + }, + .luau = .{ .url = "https://github.com/luau-lang/luau/archive/refs/tags/0.607.tar.gz", .hash = "122003818ff2aa912db37d4bbda314ff9ff70d03d9243af4b639490be98e2bfa7cb6", diff --git a/src/lib51.zig b/src/lib51.zig index 4ed0698..3f67dd7 100644 --- a/src/lib51.zig +++ b/src/lib51.zig @@ -7,6 +7,8 @@ const c = @cImport({ @cInclude("lua.h"); @cInclude("lualib.h"); @cInclude("lauxlib.h"); + + if (lang == .luajit) @cInclude("luajit.h"); }); const config = @import("config"); diff --git a/src/tests.zig b/src/tests.zig index 7efd4b5..569d68b 100644 --- a/src/tests.zig +++ b/src/tests.zig @@ -34,21 +34,21 @@ inline fn langIn(langs: anytype) bool { /// toInteger that always returns an error union inline fn toInteger(lua: *Lua, index: i32) !ziglua.Integer { - if (ziglua.lang == .lua51) { + if (ziglua.lang == .lua51 or ziglua.lang == .luajit) { return lua.toInteger(index); } else return try lua.toInteger(index); } /// toNumber that always returns an error union inline fn toNumber(lua: *Lua, index: i32) !ziglua.Number { - if (ziglua.lang == .lua51) { + if (ziglua.lang == .lua51 or ziglua.lang == .luajit) { return lua.toNumber(index); } else return try lua.toNumber(index); } /// getGlobal that always returns an error union inline fn getGlobal(lua: *Lua, name: [:0]const u8) !ziglua.LuaType { - if (ziglua.lang == .lua51 or ziglua.lang == .lua52) { + if (langIn(.{ .lua51, .lua52, .luajit })) { lua.getGlobal(name); return lua.typeOf(-1); } @@ -204,6 +204,9 @@ test "standard library loading" { .lua52 => lua.open(.{ .base = true, .coroutine = true, .package = true, .string = true, .table = true, .math = true, .io = true, .os = true, .debug = true, .bit = true }), .lua53, .lua54 => lua.open(.{ .base = true, .coroutine = true, .package = true, .string = true, .utf8 = true, .table = true, .math = true, .io = true, .os = true, .debug = true }), .luau => lua.open(.{ .base = true, .coroutine = true, .package = true, .string = true, .utf8 = true, .table = true, .math = true, .io = true, .os = true, .debug = true }), + .luajit => { + // TODO: why do tests crash? + }, } } @@ -222,12 +225,12 @@ test "standard library loading" { lua.openDebug(); // TODO: why do these fail in lua51? Debugger shows it is on line with LUA_ENVIRONINDEX - if (ziglua.lang != .luau and ziglua.lang != .lua51) { + if (ziglua.lang != .luau and ziglua.lang != .lua51 and ziglua.lang != .luajit) { lua.openPackage(); lua.openIO(); } - if (ziglua.lang != .lua51) lua.openCoroutine(); - if (ziglua.lang != .lua51 and ziglua.lang != .lua52) lua.openUtf8(); + if (ziglua.lang != .lua51 and ziglua.lang != .luajit) lua.openCoroutine(); + if (ziglua.lang != .lua51 and ziglua.lang != .lua52 and ziglua.lang != .luajit) lua.openUtf8(); } } @@ -584,7 +587,7 @@ test "calling a function with cProtectedCall" { } test "version" { - if (ziglua.lang == .lua51 or ziglua.lang == .luau) return; + if (ziglua.lang == .lua51 or ziglua.lang == .luau or ziglua.lang == .luajit) return; var lua = try Lua.init(&testing.allocator); defer lua.deinit(); @@ -635,7 +638,7 @@ test "string buffers" { try expectEqualStrings("abcdefghijklmnopqrstuvwxyz", try lua.toBytes(-1)); lua.pop(1); - if (ziglua.lang == .lua51) return; + if (ziglua.lang == .lua51 or ziglua.lang == .luajit) return; buffer.init(lua); b = buffer.prep(); @@ -662,7 +665,7 @@ test "string buffers" { } test "global table" { - if (ziglua.lang == .lua51 or ziglua.lang == .luau) return; + if (langIn(.{ .lua51, .luajit, .luau })) return; var lua = try Lua.init(&testing.allocator); defer lua.deinit(); @@ -722,7 +725,7 @@ test "function registration" { var lua = try Lua.init(&testing.allocator); defer lua.deinit(); - if (ziglua.lang == .lua51 or ziglua.lang == .luau) { + if (langIn(.{ .lua51, .luajit, .luau })) { // register all functions as part of a table const funcs = [_]ziglua.FnReg{ .{ .name = "add", .func = ziglua.wrap(add) }, @@ -851,7 +854,7 @@ test "garbage collector" { _ = lua.gcCount(); _ = lua.gcCountB(); - if (ziglua.lang != .lua51) _ = lua.gcIsRunning(); + if (ziglua.lang != .lua51 and ziglua.lang != .luajit) _ = lua.gcIsRunning(); if (ziglua.lang != .lua54) lua.gcStep(); if (langIn(.{ .lua51, .lua52, .lua53 })) { @@ -951,7 +954,7 @@ test "table access" { if (ziglua.lang == .lua53 or ziglua.lang == .lua54) lua.setIndex(-2, index) else lua.rawSetIndex(-2, index); } - if (ziglua.lang != .lua51 and ziglua.lang != .luau) { + if (!langIn(.{ .lua51, .luajit, .luau })) { try expectEqual(5, lua.rawLen(-1)); try expectEqual(5, lua.lenRaiseErr(-1)); } @@ -1045,7 +1048,7 @@ test "dump and load" { }.inner; // now load the function back onto the stack - if (ziglua.lang == .lua51) { + if (ziglua.lang == .lua51 or ziglua.lang == .luajit) { try lua.load(ziglua.wrap(reader), &buffer, "function"); } else { try lua.load(ziglua.wrap(reader), &buffer, "function", .binary); @@ -1180,7 +1183,7 @@ test "table traversal" { } test "registry" { - if (ziglua.lang == .lua51 or ziglua.lang == .luau) return; + if (langIn(.{ .lua51, .luajit, .luau })) return; var lua = try Lua.init(&testing.allocator); defer lua.deinit(); @@ -1392,11 +1395,11 @@ test "resuming" { var i: i32 = 1; while (i <= 5) : (i += 1) { - try expectEqual(.yield, if (ziglua.lang == .lua51) try thread.resumeThread(0) else try thread.resumeThread(lua, 0)); + try expectEqual(.yield, if (ziglua.lang == .lua51 or ziglua.lang == .luajit) try thread.resumeThread(0) else try thread.resumeThread(lua, 0)); try expectEqual(i, thread.toInteger(-1)); lua.pop(lua.getTop()); } - try expectEqual(.ok, if (ziglua.lang == .lua51) try thread.resumeThread(0) else try thread.resumeThread(lua, 0)); + try expectEqual(.ok, if (ziglua.lang == .lua51 or ziglua.lang == .luajit) try thread.resumeThread(0) else try thread.resumeThread(lua, 0)); try expectEqualStrings("done", try thread.toBytes(-1)); } @@ -1599,7 +1602,7 @@ test "loadBuffer" { var lua = try Lua.init(&testing.allocator); defer lua.deinit(); - if (ziglua.lang == .lua51) { + if (ziglua.lang == .lua51 or ziglua.lang == .luajit) { _ = try lua.loadBuffer("global = 10", "chunkname"); } else _ = try lua.loadBuffer("global = 10", "chunkname", .text); @@ -1679,7 +1682,7 @@ test "metatables" { try lua.newMetatable("mt"); - if (ziglua.lang != .lua51 and ziglua.lang != .luau) { + if (!langIn(.{ .lua51, .luajit, .luau })) { _ = lua.getMetatableRegistry("mt"); try expect(lua.compare(1, 2, .eq)); lua.pop(1); @@ -1690,7 +1693,7 @@ test "metatables" { lua.setField(1, "__len"); lua.newTable(); - if (ziglua.lang != .lua51 and ziglua.lang != .luau) { + if (!langIn(.{ .lua51, .luajit, .luau })) { lua.setMetatableRegistry("mt"); } else { _ = lua.getField(ziglua.registry_index, "mt"); @@ -1740,7 +1743,7 @@ test "args and errors" { } test "traceback" { - if (ziglua.lang == .lua51 or ziglua.lang == .luau) return; + if (langIn(.{ .lua51, .luajit, .luau })) return; var lua = try Lua.init(&testing.allocator); defer lua.deinit(); @@ -1761,7 +1764,7 @@ test "traceback" { } test "getSubtable" { - if (ziglua.lang == .lua51 or ziglua.lang == .luau) return; + if (langIn(.{ .lua51, .luajit, .luau })) return; var lua = try Lua.init(&testing.allocator); defer lua.deinit(); @@ -1809,7 +1812,7 @@ test "userdata" { { var t = if (ziglua.lang == .lua54) lua.newUserdata(Type, 0) else lua.newUserdata(Type); - if (ziglua.lang == .lua51 or ziglua.lang == .luau) { + if (langIn(.{ .lua51, .luajit, .luau })) { _ = lua.getField(ziglua.registry_index, "Type"); lua.setMetatable(-2); } else lua.setMetatableRegistry("Type"); @@ -1822,7 +1825,7 @@ test "userdata" { try lua.protectedCall(1, 1, 0); } - if (ziglua.lang == .lua51 or ziglua.lang == .luau) return; + if (langIn(.{ .lua51, .luajit, .luau })) return; const testUdata = ziglua.wrap(struct { fn inner(l: *Lua) i32 { @@ -1866,7 +1869,7 @@ test "userdata slices" { // create an array of 10 const slice = if (ziglua.lang == .lua54) lua.newUserdataSlice(Integer, 10, 0) else lua.newUserdataSlice(Integer, 10); - if (ziglua.lang == .lua51 or ziglua.lang == .luau) { + if (langIn(.{ .lua51, .luajit, .luau })) { _ = lua.getField(ziglua.registry_index, "FixedArray"); lua.setMetatable(-2); } else lua.setMetatableRegistry("FixedArray"); @@ -1879,7 +1882,7 @@ test "userdata slices" { fn inner(l: *Lua) i32 { _ = l.checkUserdataSlice(Integer, 1, "FixedArray"); - if (ziglua.lang != .lua51 and ziglua.lang != .luau) _ = l.testUserdataSlice(Integer, 1, "FixedArray") catch unreachable; + if (!langIn(.{ .lua51, .luajit, .luau })) _ = l.testUserdataSlice(Integer, 1, "FixedArray") catch unreachable; const arr = l.toUserdataSlice(Integer, 1) catch unreachable; for (arr, 1..) |item, index| { @@ -1943,7 +1946,7 @@ test "objectLen" { // Debug Library test "debug interface" { - if (ziglua.lang == .lua51 or ziglua.lang == .luau) return; + if (langIn(.{ .lua51, .luajit, .luau })) return; var lua = try Lua.init(&testing.allocator); defer lua.deinit(); @@ -2143,7 +2146,7 @@ test "debug upvalues" { try lua.protectedCall(1, 1, 0); try expectEqual(7, try toNumber(&lua, -1)); - if (ziglua.lang == .lua51 or ziglua.lang == .luau) return; + if (langIn(.{ .lua51, .luajit, .luau })) return; lua.pop(1);