Skip to content

Commit

Permalink
Expose Luau bytecode loading API, add example
Browse files Browse the repository at this point in the history
  • Loading branch information
nurpax committed Jan 3, 2024
1 parent 7f1e80c commit 4145fb3
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 2 deletions.
6 changes: 5 additions & 1 deletion build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,14 @@ pub fn build(b: *Build) void {
test_step.dependOn(&run_tests.step);

// Examples
const examples = [_]struct { []const u8, []const u8 }{
var common_examples = [_]struct { []const u8, []const u8 }{
.{ "interpreter", "examples/interpreter.zig" },
.{ "zig-function", "examples/zig-fn.zig" },
};
const luau_examples = [_]struct { []const u8, []const u8 }{
.{ "luau-bytecode", "examples/luau-bytecode.zig" },
};
const examples = if (lua_version == .luau) &common_examples ++ luau_examples else &common_examples;

for (examples) |example| {
const exe = b.addExecutable(.{
Expand Down
35 changes: 35 additions & 0 deletions examples/luau-bytecode.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! Run Luau bytecode

// How to recompile `test.luau.bin` bytecode binary:
//
// luau-compile --binary test.luau > test.bc
//
// This may be required if the Luau version gets upgraded.

const std = @import("std");

// The ziglua module is made available in build.zig
const ziglua = @import("ziglua");

pub fn main() anyerror!void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
defer _ = gpa.deinit();

// Initialize The Lua vm and get a reference to the main thread
var lua = try ziglua.Lua.init(allocator);
defer lua.deinit();

// Open all Lua standard libraries
lua.openLibs();

// Load bytecode
const filename = "examples/test.luau.bin";
const bc = std.fs.cwd().readFileAlloc(allocator, filename, std.math.maxInt(u32)) catch {
std.log.err("failed to open bytecode {s}", .{filename});
return;
};
defer allocator.free(bc);
try lua.loadBytecode("...", bc);
try lua.protectedCall(0, 0, 0);
}
13 changes: 13 additions & 0 deletions examples/test.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--!strict

function ispositive(x : number) : string
if x > 0 then
return "yes"
else
return "no"
end
end

local result : string
result = ispositive(1)
print("result is positive:", result)
Binary file added examples/test.luau.bin
Binary file not shown.
8 changes: 7 additions & 1 deletion src/zigluau/lib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1143,8 +1143,14 @@ pub const Lua = struct {

// luau_compile uses malloc to allocate the bytecode on the heap
defer zig_luau_free(bytecode);
try lua.loadBytecode("...", bytecode[0..size]);
}

if (c.luau_load(lua.state, "...", bytecode, size, 0) != 0) return error.Fail;
/// Loads bytecode binary (as compiled with f.ex. 'luau-compile --binary')
/// See https://luau-lang.org/getting-started
/// See also condsiderations for binary bytecode compatibility/safety: https://github.com/luau-lang/luau/issues/493#issuecomment-1185054665
pub fn loadBytecode(lua: *Lua, chunkname: [:0]const u8, bytecode: []const u8) !void {
if (c.luau_load(lua.state, chunkname.ptr, bytecode.ptr, bytecode.len, 0) != 0) return error.Fail;
}

/// If the registry already has the key `key`, returns an error
Expand Down

0 comments on commit 4145fb3

Please sign in to comment.