lua-users home
lua-l archive

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

On Tue, Feb 10, 2009 at 6:07 PM, Roberto Ierusalimschy wrote:
> Maybe we could avoid these workarounds by forcing a full garbage collection
> upon errors.

Doing a collectgarbage after a pcall did help in some cases, and it
usually is acceptable/expected that slow steps (e.g. garbage
collection) are performed upon error recovery, but I'm not sure if
this approach was more than just a hack.  For one thing, would the
order of close calls be deterministic?  Here's a test:

  -- preamble
  local pcall_original = pcall
  function pcall(...)
    local function cps(...) collectgarbage(); return ... end
    return cps(pcall_original(...))
  local function newresource(f)
    local o = newproxy(true)
    getmetatable(o).__gc = f
    return o

  -- test
  function test()
    local a = newresource(function() print 'close a' end)
    local b = newresource(function() print 'close b' end)
    local c = newresource(function() print 'close c' end)
    local d = newresource(function() print 'close d' end)
    local e = newresource(function() print 'close e' end)
    local f = newresource(function() print 'close f' end)
    local g = newresource(function() print 'close g' end)
    error '1'
  print 'done'

This may be promising because the results don't indicate nondeterminalism:

  $ lua test.lua
  close g
  close f
  close e
  close d
  close c
  close b
  close a

Explicit closes will still be needed following scope exits, including
before each return and break (which perhaps are good to avoid).

Assuming in 5.2 that throwing objects (rather than just strings)
becomes more common, it may also become more common to catch and
transform errors (John's point #3), such as between module boundaries,
which isn't supported as is in the above proposal but could be added:

    local g = newresource(function(e) print 'close g' return e2 end)
-- or error(e2)