diff mbox series

Lua: improve stack cleanliness for lua_handlers_init()

Message ID 20171002141342.14193-1-christian.storm@siemens.com
State Accepted
Headers show
Series Lua: improve stack cleanliness for lua_handlers_init() | expand

Commit Message

Storm, Christian Oct. 2, 2017, 2:13 p.m. UTC
luaL_requiref() leaves an unused copy of the 'swupdate' module
on the stack, remove it.

Signed-off-by: Christian Storm <christian.storm@siemens.com>
---
 corelib/lua_interface.c | 1 +
 1 file changed, 1 insertion(+)

Comments

Stefano Babic Oct. 3, 2017, 8:40 a.m. UTC | #1
Hi Christian,

On 02/10/2017 16:13, Christian Storm wrote:
> luaL_requiref() leaves an unused copy of the 'swupdate' module
> on the stack, remove it.
> 
> Signed-off-by: Christian Storm <christian.storm@siemens.com>
> ---
>  corelib/lua_interface.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/corelib/lua_interface.c b/corelib/lua_interface.c
> index 0553c1d..e190ebf 100644
> --- a/corelib/lua_interface.c
> +++ b/corelib/lua_interface.c
> @@ -477,6 +477,7 @@ int lua_handlers_init(void)
>  		/* load standard libraries */
>  		luaL_openlibs(gL);
>  		luaL_requiref( gL, "swupdate", luaopen_swupdate, 1 );
> +		lua_pop(gL, 1); /* remove unused copy left on stack */

I confess I have investigated this on Roberto's "Programming in LUA"
book. Most examples I saw don't have any cleanup after calling
luaL_requiref(). If I understand well, on the stack is pushed the result
of the call instead of a copy of module / function. But in reference
manual, I see "Leaves a copy of the module on the stack. ". I agree to
call lua_pop(), I am just puzzled what is pushed on the stack by
luaL_requiref().

Best regards,
Stefano
Storm, Christian Oct. 4, 2017, 6:28 a.m. UTC | #2
Hi Stefano,

> On 02/10/2017 16:13, Christian Storm wrote:
> > luaL_requiref() leaves an unused copy of the 'swupdate' module
> > on the stack, remove it.
> > 
> > Signed-off-by: Christian Storm <christian.storm@siemens.com>
> > ---
> >  corelib/lua_interface.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/corelib/lua_interface.c b/corelib/lua_interface.c
> > index 0553c1d..e190ebf 100644
> > --- a/corelib/lua_interface.c
> > +++ b/corelib/lua_interface.c
> > @@ -477,6 +477,7 @@ int lua_handlers_init(void)
> >  		/* load standard libraries */
> >  		luaL_openlibs(gL);
> >  		luaL_requiref( gL, "swupdate", luaopen_swupdate, 1 );
> > +		lua_pop(gL, 1); /* remove unused copy left on stack */
> 
> I confess I have investigated this on Roberto's "Programming in LUA"
> book. Most examples I saw don't have any cleanup after calling
> luaL_requiref(). 

Yes, true, but they should :)
However, the only downside with not cleaning up the stack is that the
table is on the stack for the lifetime of the Lua VM, which shouldn't be
a too big problem in our case.
But, luaL_requiref() leaves a "copy" (see below) on the stack every time
it's called. Hence, calling luaL_requiref() multiple times leaves
multiple "copies" of it on the stack.


> If I understand well, on the stack is pushed the result
> of the call instead of a copy of module / function. But in reference
> manual, I see "Leaves a copy of the module on the stack. ". I agree to
> call lua_pop(), I am just puzzled what is pushed on the stack by
> luaL_requiref().

In some sense it's the result, namely in terms of the module's table as
being the "return value" of loading the module. This is the exact table
that gets registered in the package.loaded table.
If you do a print on the address of the table left on the stack and
compare that to the address of the table in package.loaded, you'll see
it's the same. So, it's not a copy in the meaning of duplication but a
pointer to a table. The same pointer is inserted into the
package.loaded table under the module's name. If you do multiple
luaL_requiref() for the same module, the pointer value is also the
same.


Kind regards,
   Christian
Stefano Babic Oct. 4, 2017, 7:59 a.m. UTC | #3
On 04/10/2017 08:28, Christian Storm wrote:
> Hi Stefano,
> 
>> On 02/10/2017 16:13, Christian Storm wrote:
>>> luaL_requiref() leaves an unused copy of the 'swupdate' module
>>> on the stack, remove it.
>>>
>>> Signed-off-by: Christian Storm <christian.storm@siemens.com>
>>> ---
>>>  corelib/lua_interface.c | 1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/corelib/lua_interface.c b/corelib/lua_interface.c
>>> index 0553c1d..e190ebf 100644
>>> --- a/corelib/lua_interface.c
>>> +++ b/corelib/lua_interface.c
>>> @@ -477,6 +477,7 @@ int lua_handlers_init(void)
>>>  		/* load standard libraries */
>>>  		luaL_openlibs(gL);
>>>  		luaL_requiref( gL, "swupdate", luaopen_swupdate, 1 );
>>> +		lua_pop(gL, 1); /* remove unused copy left on stack */
>>
>> I confess I have investigated this on Roberto's "Programming in LUA"
>> book. Most examples I saw don't have any cleanup after calling
>> luaL_requiref(). 
> 
> Yes, true, but they should :)
> However, the only downside with not cleaning up the stack is that the
> table is on the stack for the lifetime of the Lua VM, which shouldn't be
> a too big problem in our case.
> But, luaL_requiref() leaves a "copy" (see below) on the stack every time
> it's called. Hence, calling luaL_requiref() multiple times leaves
> multiple "copies" of it on the stack.
> 
> 
>> If I understand well, on the stack is pushed the result
>> of the call instead of a copy of module / function. But in reference
>> manual, I see "Leaves a copy of the module on the stack. ". I agree to
>> call lua_pop(), I am just puzzled what is pushed on the stack by
>> luaL_requiref().
> 
> In some sense it's the result, namely in terms of the module's table as
> being the "return value" of loading the module. This is the exact table
> that gets registered in the package.loaded table.
> If you do a print on the address of the table left on the stack and
> compare that to the address of the table in package.loaded, you'll see
> it's the same. So, it's not a copy in the meaning of duplication but a
> pointer to a table. The same pointer is inserted into the
> package.loaded table under the module's name. If you do multiple
> luaL_requiref() for the same module, the pointer value is also the
> same.

ok, got it - thanks for clarification.

Regards,
Stefano
diff mbox series

Patch

diff --git a/corelib/lua_interface.c b/corelib/lua_interface.c
index 0553c1d..e190ebf 100644
--- a/corelib/lua_interface.c
+++ b/corelib/lua_interface.c
@@ -477,6 +477,7 @@  int lua_handlers_init(void)
 		/* load standard libraries */
 		luaL_openlibs(gL);
 		luaL_requiref( gL, "swupdate", luaopen_swupdate, 1 );
+		lua_pop(gL, 1); /* remove unused copy left on stack */
 		/* try to load lua handlers for the swupdate system */
 		if ((ret = luaL_dostring(gL, "require (\"swupdate_handlers\")")) != 0) {
 			INFO("No Lua handler(s) found.");