GithubHelp home page GithubHelp logo

rerumu / rerubi Goto Github PK

View Code? Open in Web Editor NEW
25.0 25.0 19.0 26 KB

Legacy Lua bytecode interpreter; discontinued in favor of https://github.com/Rerumu/FiOne

Lua 100.00%
lua lua-bytecode-interpreter

rerubi's People

Contributors

gonzalezjo avatar rerumu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

rerubi's Issues

Scoping error on reentry.

Cause

'Quick-access' functions can go out of scope.

Example:

loadstring(string.dump(function() end))()
> attempt to call upvalue 'Select' (a nil value)

Precompute instruction behavior for special assignments

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

OP_VARARG does not nil pad.

Cause

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

Utilize the recently implemented bit32 library (in ROBLOX)

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.

Incorrect handling of OP_FORPREP.

Cause

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

Attempt to index local 'B' (a nil value)

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

decoding luac bytecode with hex and decoding it

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

Support different endianness

Tried running a script compiled from Linux and it doesn't work, most likely due to the endianness of bytes being swapped.

Incorrect handling of OP_CONCAT.

Cause

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'

Vararg Bug

Input:
local function test(a,b,...) print(...) end test(1,2,3,4)

Output:
1 2 3 4

Expected Output:
3 4

@Rerumu

Enhance SETLIST

Interpreted some stuff wrong; going to fix SETLIST's C register (when 0) soon.

General issues with the VM.

Incorrect argument adjusting

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))

Environment handling

setfenv and getfenv are separated from the host environment.

Lack of LUA_COMPAT_VARARG support

This isn't really an issue, but since it is part of the default Lua5.1 package it would make of a more complete experience

Broken IEEE unpacking

Does not meet the full IEEE 754 standard.

print(-0)

Forced LUAI_MAXCCALLS

The recursive limit is greatly shortened due to the wrapping of the entire VM in pcall.

Pcall... Yielding?

function co()
  print(1)
  coroutine.yield()
  print(2)
end

local thread = coroutine.create(co)
coroutine.resume(thread)
coroutine.resume(thread)

OP_TFOORLOOP issue

I 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

Incorrect jumping

I noticed some missing jumps, without going through the entire VM I can say I noticed it first in OP_TESTSET

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.