Finalizers and Lua.org demo page

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
34 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Finalizers and Lua.org demo page

Egor Skriptunoff-2
Hi!

I have the following Lua program:

setmetatable({}, {__gc = function() print("Hello") end})

When I run it on my computer, It prints "Hello".
It also prints "Hello" when I run it on most "run Lua code online" websites:
rextester.com, jdoodle.com, tutorialspoint.com, ideone.com

But it prints nothing when I try to run in on www.lua.org/cgi-bin/demo
Why?

-- Egor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Зайцев Михаил
This program works fine:

setmetatable({}, {__gc = function() print("Hello") end})
collectgarbage()

Maybe there is one persistent Lua process at the server side, or final garbage collection takes place after the script output is sent to you.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Luiz Henrique de Figueiredo
In reply to this post by Egor Skriptunoff-2
> setmetatable({}, {__gc = function() print("Hello") end})
>
> But it prints nothing when I try to run in on www.lua.org/cgi-bin/demo
> Why?

Good catch!

It does print "Hello" but it does not show! Look at the HTML and you'll see

        Your program ran successfully.<!-- Hello
        </TEXTAREA><P><IMG SRC="images/alert.png" ALIGN="absbottom">
        Your program was aborted.<!-- -->

That happens because "Hello" is printed only when the Lua interpreter
exits, after the Lua program ran, and then the CGI script has already
collected the output from the Lua program.

Sorry about that. It's probably too complicated to fix this, but
I welcome fixes, of course. The source of the demo is at
        http://webserver2.tecgraf.puc-rio.br/~lhf/ftp/lua/index.html#demo
for those who want to try.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Luiz Henrique de Figueiredo
> It's probably too complicated to fix this

Actually, just calling collectgarbage() at the end of the script might do it.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

William Ahern
In reply to this post by Egor Skriptunoff-2
On Wed, Jul 19, 2017 at 09:00:49PM +0300, Egor Skriptunoff wrote:

> Hi!
>
> I have the following Lua program:
>
> setmetatable({}, {__gc = function() print("Hello") end})
>
> When I run it on my computer, It prints "Hello".
> It also prints "Hello" when I run it on most "run Lua code online" websites:
> rextester.com, jdoodle.com, tutorialspoint.com, ideone.com
>
> But it prints nothing when I try to run in on www.lua.org/cgi-bin/demo
> Why?

The lua(1) utility will destroy the Lua state after it finishes executing
the specified program(s). But if a program calls os.exit, control never
returns to the utility, and the process might terminate without destroying
the Lua state, in which case nothing further would be garbage collected.

In Lua 5.2 and 5.3, os.exit() takes a second, optional argument to force
destruction of the Lua state. The default behavior is to exit without
destruction. See https://www.lua.org/manual/5.3/manual.html#pdf-os.exit

Similarly, if the demo environment is a long-running process that reuses a
persistent Lua state, it might just be the case that program results are
captured and returned without first forcing collection of all the generated
garbage.

It all depends on how the demo environment is implemented.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Luiz Henrique de Figueiredo
In reply to this post by Luiz Henrique de Figueiredo
It's fixed now.
Thanks Egor for catching this and Mikhail for finding a solution.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Luiz Henrique de Figueiredo
> It's fixed now.

Except that now the program below has the problem again:
        a=setmetatable({}, {__gc = function() print("Hello") end})

Fixing this might require surgery in the CGI script.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Egor Skriptunoff-2
On Wed, Jul 19, 2017 at 9:29 PM, Luiz Henrique de Figueiredo wrote:
> It's fixed now.

Except that now the program below has the problem again:
        a=setmetatable({}, {__gc = function() print("Hello") end})

Fixing this might require surgery in the CGI script.


Yes, program which uses global variables
https://codegolf.stackexchange.com/a/133107/7313
still does not work properly on Lua demo page
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Egor Skriptunoff-2
In reply to this post by Luiz Henrique de Figueiredo
On Wed, Jul 19, 2017 at 9:12 PM, Luiz Henrique de Figueiredo wrote:
The source of the demo is at
        http://webserver2.tecgraf.puc-rio.br/~lhf/ftp/lua/index.html#demo


After examining the source of the demo I've found another bug.
The following absolutely correct and innocuous program gets aborted:

tostring = nil
return nil
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Luiz Henrique de Figueiredo
> After examining the source of the demo I've found another bug.
> The following absolutely correct and innocuous program gets aborted:
>
> tostring = nil
> return nil

It's no different than what happens in the command line:

        % lua
        Lua 5.3.4  Copyright (C) 1994-2017 Lua.org, PUC-Rio
        > tostring = nil
        > return nil
        error calling 'print' (attempt to call a nil value)

But the error message in the demo might be improved.

Thanks for the report.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Luiz Henrique de Figueiredo
> The following absolutely correct and innocuous program gets aborted:
> tostring = nil
> return nil

It works now without raising an error.
I've added these lines to demo.lua:

        local tostring=tostring
        local collectgarbage=collectgarbage


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Egor Skriptunoff-2
On Sun, Jul 23, 2017 at 1:25 AM, Luiz Henrique de Figueiredo <[hidden email]> wrote:
> The following absolutely correct and innocuous program gets aborted:
> tostring = nil
> return nil

It works now without raising an error.
I've added these lines to demo.lua:

        local tostring=tostring
        local collectgarbage=collectgarbage



Probably, you have forgotten about "select" :-)
Try this program:

select = nil

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Luiz Henrique de Figueiredo
> Probably, you have forgotten about "select" :-)
> Try this program:
>
> select = nil

Yes, that is fixed now as well. Thanks.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Egor Skriptunoff-2
In reply to this post by Luiz Henrique de Figueiredo
On Wed, Jul 19, 2017 at 9:29 PM, Luiz Henrique de Figueiredo wrote:
> It's fixed now.

Except that now the program below has the problem again:
        a=setmetatable({}, {__gc = function() print("Hello") end})

Fixing this might require surgery in the CGI script.


The idea is to defer closing "Output" TEXTAREA by temporarily redirecting its text to file descriptor #3
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Зайцев Михаил
Egor wrote:

> The idea is to defer closing "Output" TEXTAREA by temporarily
> redirecting its text to file descriptor #3

Other idea is to modify demo.lua:

1. Load user script in separate environment:
   local env = {}
   setmetatable(env, {__index = _ENV})
   T, E = load(T, "=input", "t", env)
instead of
   T,E=loadstring(T,"=input")

2. Delete and collect user environment after running script (or failing to run):
   env = nil
   collectgarbage()
before line
   write[[</TEXTAREA><P>]]


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Egor Skriptunoff-2
On Sun, Jul 23, 2017 at 8:48 PM, Mikhail Zajcev wrote:
Other idea is to modify demo.lua:

1. Load user script in separate environment:
   local env = {}
   setmetatable(env, {__index = _ENV})


This will not prevent user from inserting custom functions and tables in "math", "string" and "table" libraries.
Example:

math.primes = setmetatable({2,3,5,7,11}, {__index = function(t,k) ... end, __gc = function() print("BYE") end})

In this case, clearing the "env" and collecting the garbage is not enough to trigger __gc metamethod of math.primes.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Зайцев Михаил
Egor wrote:

> On Sun, Jul 23, 2017 at 8:48 PM, Mikhail Zajcev wrote:

> Other idea is to modify demo.lua:

>  1. Load user script in separate environment:
>     local env = {}
>     setmetatable(env, {__index = _ENV})





> This will not prevent user from inserting custom functions and
> tables in "math", "string" and "table" libraries.

> Example:


> math.primes = setmetatable({2,3,5,7,11}, {__index = function(t,k)
> ... end, __gc = function() print("BYE") end})


> In this case, clearing the "env" and collecting the garbage is not
> enough to trigger __gc metamethod of math.primes.

This can be fixed by making copies of standard library tables, available to user script, in "env", so it will see its own math, string, etc. tables instead of global ones, and they will be collected after deletion of "env".


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

szbnwer@gmail.com
In reply to this post by Egor Skriptunoff-2
emscripten would be the safest solution as that's limited to frontend,
and can be downloaded as well if anyone would like to do so. but i'm
not familiar with the demo, and didn't really follow this thread, so i
don't know the considerations pros and cons, but there are limitations
both ways. additionally even different lua versions could live
parallel.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Egor Skriptunoff-2
In reply to this post by Зайцев Михаил
On Sun, Jul 23, 2017 at 9:39 PM, Mikhail Zajcev wrote:

This can be fixed by making copies of standard library tables, available to user script, in "env"


Yes, deep copy of whole _G into env is a solution.
Don't forget to create new metatable for strings and set its __index field to env.string to prevent user from accessing original "string" library as debug.getmetatable"".__index
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Finalizers and Lua.org demo page

Egor Skriptunoff-2

On Sun, Jul 23, 2017 at 9:39 PM, Mikhail Zajcev wrote:

This can be fixed by making copies of standard library tables, available to user script, in "env"


Yes, deep copy of whole _G into env is a solution.
Don't forget to create new metatable for strings and set its __index field to env.string to prevent user from accessing original "string" library as debug.getmetatable"".__index

And don't forget to deep copy metatable of file handles too, this metatable is accessible by getmetatable(io.output())
12
Loading...