Re: ffi type of pointer to

  • From: Mike Pall <mike-1206@xxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Wed, 20 Jun 2012 15:55:00 +0200

Justin Cormack wrote:
> Here is a quick update of an array slice library (based on the Go one more
> or less) to use this new functionality. You couldn't really sanely write
> something like this before generically. Needs some more work, but serves as
> an example.
> 
> https://github.com/justincormack/slice

That doesn't anchor the return of buffer(), which will crash when
the GC kicks in. And it doesn't use the factory pattern, which
means unnecessary work on every instantiation. Also, it could be
made much simpler with a VLS.


I've attached a parameterized stack datatype as a best-practices
template. Needs latest git HEAD, because I'm looking up the 'new'
method via the ctype. This allows invocation of 'static methods'
aka 'class methods' via the ctype.

Also, I've decided to no longer resolve strings passed to a
parameterized type. Which means that ffi.typeof("$ *", "typename")
won't work anymore. You really have to pass a ctype and not its
name. It didn't work for "struct foo" before, so that actually
makes it more consistent. Passing a string as a parameter now only
makes sense for field names or function names (in ffi.cdef).

[Side-effect is that you can create arbitrary field names with
e.g. spaces or C keywords in it. Not sure that's gonna be useful.]

--Mike
local ffi = require("ffi")

local function stack_iter(stack)
  local top = stack.top
  if top > 0 then
    stack.top = top-1
    return stack.slot[top-1]
  end
end

local stack_mt = {
  __index = {
    new = function(tp, max)
      local stack = tp(max)
      stack.max = max
      return stack
    end,
    push = function(stack, val)
      local top = stack.top
      if top >= stack.max then error("stack overflow") end
      stack.top = top + 1
      stack.slot[top] = val
    end,
    pop = function(stack)
      local top = stack.top
      if top <= 0 then error("stack underflow") end
      stack.top = top-1
      return stack.slot[top-1]
    end,
    iter = function(stack)
      return stack_iter, stack
    end,
  }
}

local function makestack(ct)
  local tp = ffi.typeof("struct { int top, max; $ slot[?]; }", ct)
  return ffi.metatype(tp, stack_mt)
end

local stack_t = makestack(ffi.typeof("double"))

local stack = stack_t:new(100)
for i=1,100 do stack:push(i) end
for x in stack:iter() do io.write(x, " ") end
io.write("\n")

Other related posts: