Libraries and the Heap

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Libraries and the Heap

Leinen, Rick

Greetings,

 

When I first started my Lua project, I ran into a problem with it crashing as the standard Lua libraries were loading.  It turned out that my heap size was too small.  That’s when I discovered that Lua libraries are loaded into the heap, in my embedded case, copying the routines from flash into DRAM (or so I’ve been told).  Not an efficient use of memory.  I understand that eLua leaves the libraries in non-volatile memory.

 

My question is this; I assume libraries that I create will also be loaded into the heap.  Is this correct?

 

For example, following is a simple library I created allowing a Lua script to manipulate a C structure used to send a network message:

 

/*******************************************************************************

  messageHeader Library

*******************************************************************************/

static const struct luaL_Reg messageHeaderLib [] =

{

  {"new", newMessageHeader},

  {"set", setMessageHeader},

  {"get", getMessageHeader},

  {NULL, NULL}

};

 

static int newMessageHeader(lua_State *L)

{

  LevitonCAN_ApplicationCommonTypes *messageHeader;

  messageHeader = (LevitonCAN_ApplicationCommonTypes *)lua_newuserdata(L, sizeof(LevitonCAN_ApplicationCommonTypes));

 

  messageHeader->Address.D8.DestinationSubnet = 0xFF;

  messageHeader->Address.D8.DestinationNode   = 0xFF;

  messageHeader->returnAckNumber              = 0;

  messageHeader->priority                     = 0;

  messageHeader->serviceType                  = 0;

  messageHeader->priorityOverride             = 0;

  messageHeader->LC3_DestinationMulticast     = 0;

  return 1; /* new userdatum is already on the stack */

}

 

static int setMessageHeader(lua_State *L)

{

  LevitonCAN_ApplicationCommonTypes *messageHeader = (LevitonCAN_ApplicationCommonTypes *)lua_touserdata(L, 1);

  int subnet = luaL_checkint(L, 2);

  int nodeID = luaL_checkint(L, 3);

  luaL_argcheck(L, messageHeader != NULL, 1, "'messageHeader' expected");

  luaL_argcheck(L, 0 <= subnet && subnet < 255, 2, "subnet out of range");

  luaL_argcheck(L, 1 <= nodeID && nodeID < 255, 3, "nodeID out of range");

  messageHeader->Address.D8.DestinationSubnet = subnet;

  messageHeader->Address.D8.DestinationNode   = nodeID;

  return 0;

}

 

static int getMessageHeader(lua_State *L)

{

  LevitonCAN_ApplicationCommonTypes *messageHeader = (LevitonCAN_ApplicationCommonTypes *)lua_touserdata(L, 1);

  luaL_argcheck( L, messageHeader != NULL, 1, "'messageHeader' expected" );

  lua_pushnumber( L, messageHeader->Address.D8.DestinationSubnet );

  lua_pushnumber( L, messageHeader->Address.D8.DestinationNode );

  lua_remove(L,1);

  return 2;

}

 

int luaopen_messageHeader (lua_State *L)

{

  luaL_newlib(L, messageHeaderLib);

  return 1;

}

 

 

The library is load as follows:

 

  // Register messageHeader API Library

  lua_getglobal(L,"package");

  lua_getfield(L,-1,"preload");

  lua_pushcfunction(L,luaopen_messageHeader);

  lua_setfield(L,-2,"messageHeaderLib");

  luaL_requiref(L, "mh", luaopen_messageHeader, 1);

 

Thanks,

 

Rick

Reply | Threaded
Open this post in threaded view
|

Re: Libraries and the Heap

Roberto Ierusalimschy
> When I first started my Lua project, I ran into a problem with it crashing as the standard Lua libraries were loading.  It turned out that my heap size was too small.  That's when I discovered that Lua libraries are loaded into the heap, in my embedded case, copying the routines from flash into DRAM (or so I've been told).  Not an efficient use of memory.  I understand that eLua leaves the libraries in non-volatile memory.
>
> My question is this; I assume libraries that I create will also be loaded into the heap.  Is this correct?

Lua does not copy any C code to anywhere. Lua 5.1 (and previous versions)
creates a small structure in the heap (~3 words) to represent each C
function that is loaded. Lua 5.2 creates nothing in the heap when you
register a function. All versions create a table in the heap to represent
the entire library (~(8 + 6n) words) plus strings with the names
of the functions. (I guess this table and strings are what eLua avoids.)

-- Roberto

Reply | Threaded
Open this post in threaded view
|

RE: Libraries and the Heap

Leinen, Rick
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On Behalf Of Roberto Ierusalimschy
> Sent: Thursday, July 24, 2014 6:52 AM
> To: Lua mailing list
> Subject: Re: Libraries and the Heap
>
> > When I first started my Lua project, I ran into a problem with it crashing as the standard Lua libraries were loading.  It turned out that my  
> heap size was too small.  That's when I discovered that Lua libraries are loaded into the heap, in my embedded case, copying the routines from > flash into DRAM (or so I've been told).  Not an efficient use of memory.  I understand that eLua leaves the libraries in non-volatile memory.
> >
> > My question is this; I assume libraries that I create will also be loaded into the heap.  Is this correct?
>
> Lua does not copy any C code to anywhere. Lua 5.1 (and previous versions) creates a small structure in the heap (~3 words) to represent each > C function that is loaded. Lua 5.2 creates nothing in the heap when you register a function. All versions create a table in the heap to represent > the entire library (~(8 + 6n) words) plus strings with the names of the functions. (I guess this table and strings are what eLua avoids.)
>
> -- Roberto

Thanks Roberto.  Evidently I got some incorrect information, or I misunderstood.  What you describe follows with what I found in the code.  This is good news!

Rick