CCCPaste

LuauVM helper

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