Skip to content
This repository has been archived by the owner on Apr 6, 2024. It is now read-only.

Commit

Permalink
Actually fix for 0.579
Browse files Browse the repository at this point in the history
  • Loading branch information
RadiatedExodus committed Jun 9, 2023
1 parent eab3942 commit c7becfd
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 13 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# LuauInLuau
Inspired by @Rerumu's [LuauInLuau](https://gist.github.com/Rerumu/ecaf1de2f2b31d0fa91b9bac8e1e15d8), I've created this repository to translate Luau to Luau.

## BROKEN SINCE 0.579
Something seems to have changed (needing gl apis and ``__wasm_call_ctors`` jumped from 10/11 to 350, along with every function, the changes are REALLY large), the resulting wasm binary now requires multiple environment functions that I cannot write at the moment, there is a 0.579 pre-release but keep in mind that it does NOT work. Previous releases are unaffected. Feel free to make a pr to fix the issues, but as of June 8 2023, I cannot fix this due to my lack of understanding.

## Features
- Running Luau code (with or without safe env)
- Compiling Luau code into bytecode
- Compiling Luau code into bytecode (with support for setting optimization and debug levels)

## Fix list
- [ ] Fix issue where if a error occurs during runtime, it crashes the thread calling the function and does not provide any useful information

## Getting LuauInLuau
You can get it from releases or compile using the following instruction: (they were tested in Linux, WSL2 to be specific, using bash)
Expand All @@ -31,9 +31,11 @@ My solution? Make a C++ program to wrap around those functions! Yes, that is why
- [Wasynth](https://github.com/Rerumu/Wasynth) - WebAssembly -> Luau translation tool
- [The original LuauInLuau](https://gist.github.com/Rerumu/ecaf1de2f2b31d0fa91b9bac8e1e15d8) - What started this project, and used some code from it.
- [Fiu](https://github.com/TheGreatSageEqualToHeaven/Fiu) - Used their Luau bytecode version verification code
- [NougatBitz/Luau](https://github.com/NougatBitz/Luau) - Used code from here (with permission) to patch things further

## Acknowledgements
- [@Roblox](https://github.com/Roblox) and Luau contributors
- Emscripten contributors and creators
- [@Rerumu](https://github.com/Rerumu)
- [@TheGreatSageEqualToHeaven](https://github.com/TheGreatSageEqualToHeaven)
- [@TheGreatSageEqualToHeaven](https://github.com/TheGreatSageEqualToHeaven)
- [@NougatBitz](https://github.com/NougatBitz)
62 changes: 54 additions & 8 deletions snippets/ExtraCodeSnippet.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ local NamedFunctionList = {
["lua_close"] = FUNC_LIST[1150];
["luaL_sandbox"] = FUNC_LIST[1082];
["lua_tolstring"] = FUNC_LIST[784];
["luaL_pushresult"] = FUNC_LIST[888];

--// Standard Library
["dlmalloc"] = FUNC_LIST[3450];
["dlfree"] = FUNC_LIST[3451];
["strlen"] = FUNC_LIST[3196];

--// WebAssembly
["__wasm_call_ctors"] = FUNC_LIST[350];
Expand All @@ -19,7 +21,7 @@ local NamedFunctionList = {
["LuauRunUsingCustomState"] = FUNC_LIST[352];

--// Macros
["lua_tostring"] = function(L, i) return FUNC_LIST[784](L, i, 0) end;
["lua_tostring"] = function(L, i) return FUNC_LIST[784](L, i, 0) end; --// lua_tolstring
}

--// Pre-init environment function setup
Expand All @@ -28,6 +30,12 @@ local FILE_MAP = { {}, {} }
local load_string = rt.load.string
local table_insert = table.insert

local function CreateStub(ret)
return function()
return ret
end
end

local function fd_flush(file)
local final = table.concat(file)
local last = 1
Expand All @@ -39,10 +47,24 @@ local function fd_flush(file)
file[1] = string.sub(final, last + 1)
end

--// Stubbed functions
FUNC_LIST[311] = CreateStub(0) --// _emscripten_get_progname
FUNC_LIST[344] = CreateStub(0) --// fd_seek
FUNC_LIST[347] = CreateStub(0) --// fd_pread
FUNC_LIST[348] = CreateStub(0) --// fd_pwrite
FUNC_LIST[349] = CreateStub(0) --// __syscall_truncate64
FUNC_LIST[346] = CreateStub(0) --// __syscall_fallocate
FUNC_LIST[298] = CreateStub(0) --// fd_sync
FUNC_LIST[302] = CreateStub(0) --// fs_fdstat_get
FUNC_LIST[260] = CreateStub(0) --// environ_sizes_get
FUNC_LIST[261] = CreateStub(0) --// environ_get
FUNC_LIST[266] = CreateStub(0) --// fd_close
FUNC_LIST[267] = CreateStub(0) --// fd_read

--// __cxa_throw
FUNC_LIST[0] = function(except, _info, _dtor)
local what = FUNC_LIST[519](except)
local len = FUNC_LIST[1197](what)
local what = NamedFunctionList.luaL_pushresult(except)
local len = NamedFunctionList.strlen(what)
error("An exception was thrown\n" .. load_string(memory_at_0, what, len))
end

Expand Down Expand Up @@ -78,6 +100,11 @@ FUNC_LIST[312] = function(reason)
assert(false, "Aborted("..reason..")")
end

--// proc_exit
FUNC_LIST[259] = function()
return FUNC_LIST[312]("process exited")
end

--// Initialize
run_init_code()
memory_at_0 = MEMORY_LIST[0]
Expand All @@ -88,7 +115,7 @@ local function lua_try_catch(index, ...)
return TABLE_LIST[0].data[index](...)
end

local DoNotPatchTargets = { 0, 268, 281, 285, 312 }
local DoNotPatchTargets = { 0, 259, 260, 261, 266, 267, 268, 281, 285, 298, 302, 311, 312, 344, 346, 347, 348, 349 }
local PatchTargets = {}
for i = 0, 349 do
if table.find(DoNotPatchTargets, i) then continue end
Expand All @@ -110,16 +137,34 @@ local function ResultCodeToBoolean(code)
return code == 0
end

local function LuauCompile(src: string)
local function LuauCompile(src: string, optimizationlevel: number?, debuglevel: number?)
--// Create source string (char*) and bytecode size thing (size_t)
local SrcLength = #src
local SrcBuffer = NamedFunctionList.dlmalloc(SrcLength + 1)
rt.store.string(memory_at_0, SrcBuffer, src)
rt.store.i32_n8(memory_at_0, SrcBuffer + SrcLength, 0)
local BytecodeSizePtr = NamedFunctionList.dlmalloc(8) --// size_t = 8 bytes, thanks @Rerumu

--// Create a CompileOptions (luau/Compiler/include/Luau/Compiler.h#L17)
--// Struct object
--// We're only using the optimizationLevel and debugLevel properties on the struct,
--// both are int, a int is 4 bytes, so we allocate 8 bytes to store those 2 properties:
--[[
// 0 - no optimization
// 1 - baseline optimization level that doesn't prevent debuggability
// 2 - includes optimizations that harm debuggability such as inlining
int optimizationLevel = 1;

// 0 - no debugging support
// 1 - line info & function names only; sufficient for backtraces
// 2 - full debug info with local & upvalue names; necessary for debugger
int debugLevel = 1;
--]]
local CompileOptionsPtr = NamedFunctionList.dlmalloc(8)
rt.store.i64(memory_at_0, CompileOptionsPtr, rt.i64.from_u32(optimizationlevel or 1, debuglevel or 1))

--// Compile bytecode and get the size
local BytecodePtr = NamedFunctionList.luau_compile(SrcBuffer, SrcLength, 0, BytecodeSizePtr)
local BytecodePtr = NamedFunctionList.luau_compile(SrcBuffer, SrcLength, CompileOptionsPtr, BytecodeSizePtr)
local BytecodeSize = load_i32(memory_at_0, BytecodeSizePtr)
local Bytecode = load_string(memory_at_0, BytecodePtr, BytecodeSize)
local ValidLuauBytecode = ValidLuauBytecode(Bytecode)
Expand All @@ -128,15 +173,16 @@ local function LuauCompile(src: string)
NamedFunctionList.dlfree(SrcBuffer)
NamedFunctionList.dlfree(BytecodeSizePtr)
NamedFunctionList.dlfree(BytecodePtr)
NamedFunctionList.dlfree(CompileOptionsPtr)

--// Return
--// If the compiler failed, then Bytecode will be the error that occured while compiling (BytecodeSize will be the length of the error)
return ValidLuauBytecode, Bytecode, BytecodeSize
end

local function LuauRun(src: string, safeenv: boolean?)
local function LuauRun(src: string, safeenv: boolean?, optimizationlevel: number?, debuglevel: number?)
--// Compile bytecode
local CompileSuccess, Result, ResultSize = LuauCompile(src)
local CompileSuccess, Result, ResultSize = LuauCompile(src, optimizationlevel, debuglevel)
assert(CompileSuccess, Result)

--// Load bytecode string into memory
Expand Down

0 comments on commit c7becfd

Please sign in to comment.