lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Tue, 2011-05-17 at 06:07 +0000, Josh Haberman wrote:
> I saw this posted on HackerNews: http://bellard.org/jslinux/
> 
> Besides being generally cool and impressive, I noticed that
> the speed of its x86 emulation comes largely from TypedArrays,
> which is a recent JavaScript library that lets you treat a byte
> array as an array of eg. 32-bit integers, floats, etc.  You can
> create different views into the array so that eg. you can write
> three floats and then three bytes.  The array elements don't
> have to be homogenous.
> 
> To my eye this looks like a very small subset of LuaJIT's FFI.
> It doesn't let you call C functions or do a lot of the advanced
> things that the FFI supports.  But one thing it *does* have
> going for it is memory safety -- it performs bounds-checking
> which prevents memory corruption.
> 
> I was wondering if it might make sense to offer an equivalent
> library for LuaJIT.  This library could offer a lot of the efficiency
> benefits of FFI (like for numerical computations) without giving
> up memory safety.  But "FFI" probably isn't the right name for it
> since it wouldn't let you call C functions.

It is not hard to wrap bounds testing around an ffi structure, although
the compiler does not optimise away all the overhead, it is about 16x
slower than without bounds checking, although it is only 4x slower if
you use function methods rather than metamethods... Then you can hide
the direct use of ffi from your users and just provide wrappers. You
dont really need the typed array views, as you can declare C structures
as types directly.

ffi = require "ffi"

int_t = ffi.typeof("int[?]")

local read = function(s, i)
  if type(i) == 'number' and i >= 0 and i < s.size then return s.buf[i]
end
  return nil
end

local write = function(s, i, v)
  if type(i) == 'number' and i >= 0 and i < s.size then s.buf[i] = v end
end

function int(size)
  local s = {buf = int_t(size), size = size, read = read, write = write}
  setmetatable(s, { __index = read, __newindex = write})
  return s
end

local m = 1000000
local a = int(m)

local b = a.buf

for j = 1, 500 do
for i = 3, m do
  a[i] = a[i - 1] + a[i - 2]
   --b[i] = b[i - 1] + b[i - 2]
  --a:write(i, a:read(i - 1) + a:read(i - 2))
end
end