rerumu / rerubi Goto Github PK
View Code? Open in Web Editor NEWLegacy Lua bytecode interpreter; discontinued in favor of https://github.com/Rerumu/FiOne
Legacy Lua bytecode interpreter; discontinued in favor of https://github.com/Rerumu/FiOne
'Quick-access' functions can go out of scope.
Example:
loadstring(string.dump(function() end))()
> attempt to call upvalue 'Select' (a nil value)
Instructions like OP_ADD and OP_SUB (henceforth referred to as special assignments) do unnecessary work.
if (B > 255) then
B = Const[B - 256];
else
B = Stk[B];
end;
if (C > 255) then
C = Const[C - 256];
else
C = Stk[C];
end;
I really, really dislike how LBI and its derivatives do this. This can be done at an instruction decoder level, where the cost for computing C and B would be incurred once at decode time, and never incurred again afterward.
Special assignments can be made extremely quick and make up a non-insignificant portion of the average script. Because they're all so similar and there many types of special assignments, it's relatively trivial to get large performance gains for the interpreter as a whole through something like this:
(how I do it):
[opcodes.SELF] = function(operands) -- 11
local p_data = operands.p_data
stack[operands.a + 1] = stack[operands.b]
stack[operands.a] = stack[operands.b][p_data.c_const and state.constants[p_data.c] or stack[p_data.c]]
end,
[opcodes.ADD] = function(operands) -- 12
local p_data = operands.p_data
stack[operands.a] = (p_data.b_const and state.constants[p_data.b] or stack[p_data.b]) + (p_data.c_const and state.constants[p_data.c] or stack[p_data.c])
end,
[opcodes.SUB] = function(operands) -- 13
local p_data = operands.p_data
stack[operands.a] = (p_data.b_const and state.constants[p_data.b] or stack[p_data.b]) - (p_data.c_const and state.constants[p_data.c] or stack[p_data.c])
end,
[opcodes.MUL] = function(operands) -- 14
local p_data = operands.p_data
stack[operands.a] = (p_data.b_const and state.constants[p_data.b] or stack[p_data.b]) * (p_data.c_const and state.constants[p_data.c] or stack[p_data.c])
end,
[opcodes.DIV] = function(operands) -- 15
local p_data = operands.p_data
stack[operands.a] = (p_data.b_const and state.constants[p_data.b] or stack[p_data.b]) / (p_data.c_const and state.constants[p_data.c] or stack[p_data.c])
end,
[opcodes.MOD] = function(operands) -- 16
local p_data = operands.p_data
stack[operands.a] = (p_data.b_const and state.constants[p_data.b] or stack[p_data.b]) % (p_data.c_const and state.constants[p_data.c] or stack[p_data.c])
end,
[opcodes.POW] = function(operands) -- 17
local p_data = operands.p_data
stack[operands.a] = (p_data.b_const and state.constants[p_data.b] or stack[p_data.b]) ^ (p_data.c_const and state.constants[p_data.c] or stack[p_data.c])
end,
You could go even faster than what I do (by, for example, doing what you do with if statements instead of function calls) but I think that you get the point.
Edit: I think it's also important to note that this is more than just a performance hack. For me, doing this was partly about having a more practical disassembler API (the VM being written atop my disassembler) but more largely about having much simpler code. I think that it's a useful change, if not for performance reasons, then for at least removing a lot of "noise" and redundancy from the codebase.
edit: oof ow my english
i just realized its not caused by rerubi, and rerubi isnt made for roblox i think
Since your implementation does not correct the top of the stack, previously pushed data can overlap argument Indices.
Example:
local x = {1, 2}
print(...)
> 2
Sadly, I'm terrible at math (yet love programmer, very interesting combo), so I don't even know where to start on this (trying to learn, but we will see how that goes). However, I do know enough to understand using the back-ported 5.2 bit32 library ROBLOX now provides would boost performance quite significantly.
As I attempt to get a grasp on bit operations, I will attempt to fix this myself, however in-case someone who already knows wants to do it faster, I'll leave this here.
For init/limit/step value conversion is not handled, enforcement of only numbers is not present as well.
Example:
for i = 1, "2" do end
> attempt to compare number with string
for i = 1, {} do end
> attempt to compare number with table
I have no idea why it's doing this, but I have found this line in my script is doing it:
local newClient = client:Clone()
newClient.Parent = player.PlayerScripts
newClient.Disabled = false
pc++ thanks
if you encoded any lua bytecode with hex and then decoding it, running it again it will say it is not valid bytecode. this goes for any form of encryption or encoding. even after decoding it to its original state, the vm will not accept it
for additional information: https://pastebin.com/raw/PvuU9N5e
that has minified the interpreter and has the encoding and decoding. encoded gets decoded then run on the interpreter (is luac bytecode and non encoded runs 100% fine) but throws an error:
Lua bytecode expected
Tried running a script compiled from Linux and it doesn't work, most likely due to the endianness of bytes being swapped.
Concat does not attempt to convert any objects, along with this table.concat
does not call the proper metamethod.
Example:
local x = {}
setmetatable(x, {__concat = function(x, y) return '__concat' end})
print(''..x)
> invalid value (table) at index 2 in table for 'concat'
i get this https://i.vgy.me/QCEOgV.png
Input:
local function test(a,b,...) print(...) end test(1,2,3,4)
Output:
1 2 3 4
Expected Output:
3 4
Interpreted some stuff wrong; going to fix SETLIST's C register (when 0) soon.
Similar to #6, the stack is not handled correctly, causing weird bugs after things are supposed to be adjusted.
print((function () return nil end)(4))
setfenv and getfenv are separated from the host environment.
LUA_COMPAT_VARARG
supportThis isn't really an issue, but since it is part of the default Lua5.1 package it would make of a more complete experience
Does not meet the full IEEE 754 standard.
print(-0)
LUAI_MAXCCALLS
The recursive limit is greatly shortened due to the wrapping of the entire VM in pcall.
function co()
print(1)
coroutine.yield()
print(2)
end
local thread = coroutine.create(co)
coroutine.resume(thread)
coroutine.resume(thread)
OP_TFOORLOOP
issueI really don't feel like digging around for what the problem is, but I was able to reproduce a working example.
This no longer works for some reason.
local function iter(lcnt)
return function(x, y)
return y - 1
end, nil, nil
end
for x, y in iter(5) do end
I noticed some missing jumps, without going through the entire VM I can say I noticed it first in OP_TESTSET
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.