Files
flatbuffers-bigfoot/lua/flatbuffers/compat_luajit.lua
罗泽轩 d3cd78a87c [Lua] Add LuaJIT support (#6584)
* [Lua] Add LuaJIT support

Here is the output of LuaTest.sh:

Run with LuaJIT:
built 100 512-byte flatbuffers in 0.16sec: 0.63/msec, 0.31MB/sec
built 1000 512-byte flatbuffers in 0.08sec: 12.06/msec, 5.89MB/sec
built 10000 512-byte flatbuffers in 0.80sec: 12.44/msec, 6.07MB/sec
built 10000 512-byte flatbuffers in 0.33sec: 30.58/msec, 14.93MB/sec
traversed 100 592-byte flatbuffers in 0.04sec: 2.51/msec, 1.42MB/sec
traversed 1000 592-byte flatbuffers in 0.03sec: 31.52/msec, 17.79MB/sec
traversed 10000 592-byte flatbuffers in 0.21sec: 48.77/msec, 27.53MB/sec
Run with Lua 5.3:
built 100 512-byte flatbuffers in 0.02sec: 5.44/msec, 2.66MB/sec
built 1000 512-byte flatbuffers in 0.17sec: 5.74/msec, 2.80MB/sec
built 10000 512-byte flatbuffers in 1.75sec: 5.72/msec, 2.79MB/sec
built 10000 512-byte flatbuffers in 1.38sec: 7.26/msec, 3.55MB/sec
traversed 100 592-byte flatbuffers in 0.00sec: 27.64/msec, 15.60MB/sec
traversed 1000 592-byte flatbuffers in 0.03sec: 30.46/msec, 17.20MB/sec
traversed 10000 592-byte flatbuffers in 0.34sec: 29.62/msec, 16.72MB/sec

* [Lua] Better usage description

* update according to the review
2021-04-30 10:38:16 -07:00

207 lines
4.6 KiB
Lua

local bit = require("bit")
local ffi = require("ffi")
local band = bit.band
local bnot = bit.bnot
local m = {}
local Uint8Bound = 256 -- bound is the max uintN + 1
local Uint16Bound = 65536
local Uint32Bound = 4294967296
m.GetAlignSize = function(k, size)
return band((bnot(k) + 1), (size - 1))
end
local function pack_I1(n)
return string.char(n)
end
local function pack_i1(n)
if n < 0 then
n = Uint8Bound + n
end
return pack_I1(n)
end
local function unpack_I1(n, pos)
return string.byte(n, pos)
end
local function unpack_i1(n, pos)
local res = unpack_I1(n, pos)
if res >= Uint8Bound / 2 then
return res - Uint8Bound
end
return res
end
local b2 = ffi.new("unsigned char[2]")
local function pack_I2(n)
for i = 0, 1 do
b2[i] = bit.band(n, 255)
n = bit.rshift(n, 8)
end
return ffi.string(b2, 2)
end
local function pack_i2(n)
if n < 0 then
n = Uint16Bound + n
end
return pack_I2(n)
end
local function unpack_I2(n, pos)
local a, b = string.byte(n, pos, pos + 1)
return b * Uint8Bound + a
end
local function unpack_i2(n, pos)
local res = unpack_I2(n, pos)
if res >= Uint16Bound / 2 then
return res - Uint16Bound
end
return res
end
local b4 = ffi.new("unsigned char[4]")
local function pack_I4(n)
for i = 0, 3 do
b4[i] = bit.band(n, 255)
n = bit.rshift(n, 8)
end
return ffi.string(b4, 4)
end
local function pack_i4(n)
if n < 0 then
n = Uint32Bound + n
end
return pack_I4(n)
end
local function unpack_I4(n, pos)
local a, b, c, d = string.byte(n, pos, pos + 3)
return Uint8Bound * (Uint8Bound * ((Uint8Bound * d) + c) + b) + a
end
local function unpack_i4(n, pos)
local res = unpack_I4(n, pos)
if res >= Uint32Bound / 2 then
return res - Uint32Bound
end
return res
end
local b8 = ffi.new("unsigned char[8]")
local function pack_I8(n)
n = ffi.cast("unsigned long long", n)
local hi = math.floor(tonumber(n / Uint32Bound))
local li = n % Uint32Bound
for i = 0, 3 do
b8[i] = bit.band(li, 255)
li = bit.rshift(li, 8)
end
for i = 4, 7 do
b8[i] = bit.band(hi, 255)
hi = bit.rshift(hi, 8)
end
return ffi.string(b8, 8)
end
local function pack_i8(n)
n = ffi.cast("signed long long", n)
return pack_I8(n)
end
local function unpack_I8(n, pos)
local a, b, c, d = string.byte(n, pos, pos + 3)
local li = Uint8Bound * (Uint8Bound * ((Uint8Bound * d) + c) + b) + a
local a, b, c, d = string.byte(n, pos + 4, pos + 7)
local hi = Uint8Bound * (Uint8Bound * ((Uint8Bound * d) + c) + b) + a
return ffi.cast("unsigned long long", hi) * Uint32Bound + li
end
local function unpack_i8(n, pos)
local res = unpack_I8(n, pos)
return ffi.cast("signed long long", res)
end
local bf = ffi.new("float[1]")
local function pack_f(n)
bf[0] = n
return ffi.string(bf, 4)
end
local function unpack_f(n, pos)
ffi.copy(bf, ffi.cast("char *", n) + pos - 1, 4)
return tonumber(bf[0])
end
local bd = ffi.new("double[1]")
local function pack_d(n)
bd[0] = n
return ffi.string(bd, 8)
end
local function unpack_d(n, pos)
ffi.copy(bd, ffi.cast("char *", n) + pos - 1, 8)
return tonumber(bd[0])
end
m.string_pack = function(fmt, i, ...)
if fmt == "<I1" then
return pack_I1(i)
elseif fmt == "<I2" then
return pack_I2(i)
elseif fmt == "<I4" then
return pack_I4(i)
elseif fmt == "<I8" then
return pack_I8(i)
elseif fmt == "<i1" then
return pack_i1(i)
elseif fmt == "<i2" then
return pack_i2(i)
elseif fmt == "<i4" then
return pack_i4(i)
elseif fmt == "<i8" then
return pack_i8(i)
elseif fmt == "<f" then
return pack_f(i)
elseif fmt == "<d" then
return pack_d(i)
else
error(string.format("FIXME: support fmt %s", fmt))
end
end
m.string_unpack = function(fmt, s, pos)
if not pos then
pos = 1
end
if fmt == "<I1" then
return unpack_I1(s, pos)
elseif fmt == "<I2" then
return unpack_I2(s, pos)
elseif fmt == "<I4" then
return unpack_I4(s, pos)
elseif fmt == "<I8" then
return unpack_I8(s, pos)
elseif fmt == "<i1" then
return unpack_i1(s, pos)
elseif fmt == "<i2" then
return unpack_i2(s, pos)
elseif fmt == "<i4" then
return unpack_i4(s, pos)
elseif fmt == "<i8" then
return unpack_i8(s, pos)
elseif fmt == "<f" then
return unpack_f(s, pos)
elseif fmt == "<d" then
return unpack_d(s, pos)
else
error(string.format("FIXME: support fmt %s", fmt))
end
end
return m