8000 Add compilation/loading for bytecode by bjcscat · Pull Request #120 · luau-lang/lute · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Add compilation/loading for bytecode #120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ target_include_directories(Lute.VM PUBLIC vm/include ${LIBUV_INCLUDE_DIR})

target_link_libraries(Lute.Runtime PRIVATE Luau.CLI.lib Luau.Compiler Luau.Config Luau.CodeGen Luau.VM uv_a)
target_link_libraries(Lute.Fs PRIVATE Lute.Runtime Luau.VM uv_a)
target_link_libraries(Lute.Luau PRIVATE Lute.Runtime Luau.VM uv_a Luau.Analysis Luau.Ast)
target_link_libraries(Lute.Luau PRIVATE Lute.Runtime Luau.VM uv_a Luau.Analysis Luau.Ast Luau.Compiler)
target_link_libraries(Lute.Net PRIVATE Lute.Runtime Luau.VM uv_a ${WOLFSSL_LIBRARY} libcurl uWS)
target_link_libraries(Lute.Task PRIVATE Lute.Runtime Luau.VM uv_a)
target_link_libraries(Lute.VM PRIVATE Lute.Runtime Luau.VM uv_a)
Expand Down
7 changes: 7 additions & 0 deletions examples/compile.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
local luau = require("@lute/luau")

local bytecode_container = luau.compile("return \"Hello, world!\"")

print(`Bytecode is {#bytecode_container["bytecode"]} bytes long`)

print(luau.load(bytecode_container)())
6 changes: 6 additions & 0 deletions luau/include/lute/luau.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@ int luau_parse(lua_State* L);

int luau_parseexpr(lua_State* L);

int compile_luau(lua_State* L);

int load_luau(lua_State* L);

static const luaL_Reg lib[] = {
{"parse", luau_parse},
{"parseexpr", luau_parseexpr},
{"compile", compile_luau},
{"load", load_luau},
{nullptr, nullptr},
};

Expand Down
85 changes: 83 additions & 2 deletions luau/src/luau.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@
#include "Luau/Parser.h"
#include "Luau/ParseOptions.h"
#include "Luau/ToString.h"
#include "Luau/Compiler.h"

#include "lua.h"
#include "lualib.h"
#include <cstddef>
#include <cstring>
#include <iterator>

const char* COMPILE_RESULT_TYPE = "CompileResult";

namespace luau
{
Expand Down Expand Up @@ -1319,13 +1325,88 @@ int luau_parseexpr(lua_State* L)
return 1;
}

inline int check_int_field(lua_State* L, int obj_idx, const char* field_name, int default_value)
{
if (lua_getfield(L, obj_idx, field_name) == LUA_TNIL)
return default_value;

int is_num;
int value = lua_tointegerx(L, -1, &is_num);

if (!is_num)
luaL_errorL(L, "Expected number for field \"%s\"", field_name);

return value;
}

int compile_luau(lua_State* L)
{
size_t source_size;
const char* source = luaL_checklstring(L, 1, &source_size);

Luau::CompileOptions opts{};

if (lua_type(L, 2) == LUA_TTABLE)
{
opts.optimizationLevel = check_int_field(L, 2, "optimization_level", 1);
opts.debugLevel = check_int_field(L, 2, "debug_level", 1);
opts.coverageLevel = check_int_field(L, 2, "coverage_level", 1);
}

std::string bytecode = Luau::compile(std::string(source, source_size), opts);

std::string* userdata = static_cast<std::string*>(lua_newuserdata(L, sizeof(std::string)));

new (userdata) std::string(std::move(bytecode));

luaL_getmetatable(L, COMPILE_RESULT_TYPE);
lua_setmetatable(L, -2);

return 1;
}

int load_luau(lua_State* L)
{
const std::string* bytecode_string = static_cast<std::string*>(luaL_checkudata(L, 1, COMPILE_RESULT_TYPE));
const char* chunk_name = luaL_optlstring(L, 2, "luau.load", nullptr);

luau_load(L, chunk_name, bytecode_string->c_str(), bytecode_string->length(), lua_gettop(L) > 2 ? 3 : 0);

return 1;
}

} // namespace luau

static int index_result(lua_State* L) {
const std::string* bytecode_string = static_cast<std::string*>(luaL_checkudata(L, 1, COMPILE_RESULT_TYPE));

if (std::strcmp(luaL_checkstring(L, 2), "bytecode") == 0) {
lua_pushlstring(L, bytecode_string->c_str(), bytecode_string->size());

return 1;
}

return 0;
}

// perform type mt registration, etc
static int init_luau_lib(lua_State* L)
{
luaL_newmetatable(L, COMPILE_RESULT_TYPE);

lua_pushcfunction(L, index_result, "CompilerResult.__index");
lua_setfield(L, -2, "__index");

lua_pop(L, 1);

return 1;
}

int luaopen_luau(lua_State* L)
{
luaL_register(L, "luau", luau::lib);

return 1;
return init_luau_lib(L);
}

int luteopen_luau(lua_State* L)
Expand All @@ -1343,5 +1424,5 @@ int luteopen_luau(lua_State* L)

lua_setreadonly(L, -1, 1);

return 1;
return init_luau_lib(L);
}
0