local VMHelper = {}
VMHelper.VM = require(game:GetService("ReplicatedStorage"):WaitForChild("LuaVM"))
VMHelper.L = nil
local ift = VMHelper.VM.wasm.indirect_function_table.data
local cfns = VMHelper.VM.wasm.cfns
local rt = VMHelper.VM.wasm.rt
local memory_at_0 = VMHelper.VM.wasm.memory
local macros = VMHelper.VM.macros
local function cval(value)
if type(value) == "string" then
local strLen = #value
local ptr = cfns.malloc(strLen + 1)
rt.store.string(memory_at_0, ptr, value)
rt.store.i32_n8(memory_at_0, ptr + strLen, 0)
return ptr
elseif type(value) == "boolean" then
local ptr = cfns.malloc(1)
rt.store.i32_n8(memory_at_0, ptr, value and 1 or 0)
return ptr
end
end
local function insertCFunction(f: () -> ())
local ptr = #ift + 1
ift[ptr] = f
return ptr
end
local function handlePcall(result : number) : boolean
if (result == macros.LUA_OK) then
return true
elseif (result == macros.LUA_ERRRUN) then
local e = macros.lua_tostring(VMHelper.L, -1)
print(rt.load.string(memory_at_0, e, cfns.strlen(e)))
return false
elseif (result == macros.LUA_ERRERR) then
local e = macros.lua_tostring(VMHelper.L, -1)
print("error func errored ", rt.load.string(memory_at_0, e, cfns.strlen(e)))
return false
end
end
function VMHelper.MakeState()
VMHelper.L = cfns.luaL_newstate()
cfns.luaL_openlibs(VMHelper.L)
end
function VMHelper.PushGlobal(name: string, value: any)
if type(value) == "table" then
macros.lua_newtable(VMHelper.L)
for k, v in pairs(value) do
if type(k) == "string" then
cfns.lua_pushstring(VMHelper.L, cval(k))
elseif type(k) == "number" then
cfns.lua_pushnumber(VMHelper.L, k)
else
error("Unsupported table key type: "..typeof(k))
end
if type(v) == "function" then
cfns.lua_pushcclosurek(VMHelper.L, insertCFunction(v), cval(tostring(k)), 0, 0)
elseif type(v) == "string" then
cfns.lua_pushstring(VMHelper.L, cval(v))
elseif type(v) == "number" then
cfns.lua_pushnumber(VMHelper.L, v)
elseif type(v) == "boolean" then
cfns.lua_pushboolean(VMHelper.L, v and 1 or 0)
else
error("Unsupported table value type: "..typeof(v))
end
-- set table field
cfns.lua_settable(VMHelper.L, -3)
end
macros.lua_setglobal(VMHelper.L, cval(name))
else
if type(value) == "function" then
cfns.lua_pushcclosurek(VMHelper.L, insertCFunction(value), cval(name), 0, 0)
elseif type(value) == "string" then
cfns.lua_pushstring(VMHelper.L, cval(value))
elseif type(value) == "number" then
cfns.lua_pushnumber(VMHelper.L, value)
elseif type(value) == "boolean" then
cfns.lua_pushboolean(VMHelper.L, value and 1 or 0)
else
error("Unsupported global type: "..typeof(value))
end
macros.lua_setglobal(VMHelper.L, cval(name))
end
end
function VMHelper.Print(text : string)
macros.lua_getglobal(VMHelper.L,cval("print"))
cfns.lua_pushstring(VMHelper.L, cval(text))
local scriptResult = cfns.lua_pcall(VMHelper.L,1,0,0)
handlePcall(scriptResult)
end
local typeDict = {
string = function(L, v)
cfns.lua_pushstring(L, cval(v))
end,
number = function(L, v)
cfns.lua_pushnumber(L, v)
end,
boolean = function(L, v)
cfns.lua_pushboolean(L, v and 1 or 0)
end
}
function VMHelper.PushReturn(val : any)
local fn = typeDict[typeof(val)]
if fn then
fn(VMHelper.L, val)
else
error("Unknown lua type " .. typeof(val))
end
end
function VMHelper.RunScript(scriptData : string, chunkName : string)
local bc,bcs = VMHelper.VM.luau_compile(scriptData)
local bcPtr = cval(bc)
cfns.luau_load(VMHelper.L,cval(chunkName),bcPtr,#bc,0)
local scriptResult = cfns.lua_pcall(VMHelper.L,0,0,0)
handlePcall(scriptResult)
end
return VMHelper