lua-users home
lua-l archive

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


----- Original Message -----
From: David Manura
Date: 2/24/2011 8:20 PM
On Thu, Feb 24, 2011 at 6:24 PM, Joshua Jensen<josh.jjensen@gmail.com>  wrote:
I'd love to find a patch that just does injection of the code in this manner:

     function Func()
         running = true;  -- finalize running = false end
         if somebadthing then
             running = false    --!!!!!!
             return false
         end
         mutex:lock();  -- finalize mutex:unlock() end
         if running then
             mutex:unlock()  --!!!!!!
             running = false   --!!!!!!
             return false
         end
         mutex:unlock()     --!!!!!!
         running = false      --!!!!!!
         return Idle_loop()  -- Tail call
     end
That should be straightforward enough, either as a patch to lparser.c
or as an external source preprocessor, neither of which require VM
changes.  The downside is that it doesn't cleanup properly on exits
due to raised errors.  (More difficult to address are out-of-memory
errors if allowed to occur anywhere [1].)

I would have thought the cleanup should occur after the idle_loop(),
as it does in C++, which would seem to prevent the tail call
optimization, but there may be justification for cleanup prior to the
tail call as your example shows.

[1] http://lua-users.org/lists/lua-l/2008-10/msg00396.html
Thinking on it further, I could have it both ways. Perhaps, for a tail call, it really should run as above. If you want the mutex to unlock after the call to Idle_loop(), then you wouldn't use a tail call:

    function Func()
        running = true;  -- finalize running = false end
        if somebadthing then
            running = false    --!!!!!!
            return false
        end
        mutex:lock();  -- finalize mutex:unlock() end
        if running then
            mutex:unlock()    --!!!!!!
            running = false   --!!!!!!
            return false
        end
        local ret = Idle_loop()  -- Tail call
        mutex:unlock()        --!!!!!!
        running = false       --!!!!!!
	return ret
    end

In any case, the original patch is flawed right here.  I suppose I'll have to dive in and find a fix for it if somebody has not already done so.  I believe I like the block-level finalization.  It seems very close to Go's 'defer' keyword.

Josh