lua-users home
lua-l archive

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


On Mon, 7 Jun 2010 01:09:06 +0100, Matthew Wild <mwild1@gmail.com> wrote:

> Just a couple of questions... it looks like I have to specify the
> exported functions for any module I require, is this correct?

You don't have to.  If you supply a list of exports, it will be used.
If you don't, then Darwin will generate the list automatically.  It
assumes that you want to export everything in _G that did not come
from one of the imported (pre-requisite) modules.  (The examples below
do exactly this.)

> Also how does it prevent C modules from modifying the main
> environment? (Does it even work with C modules?)

It works with C modules, although I only tested it on a handful
(including lanes, which forced me to very carefully ensure that Darwin
loads things exactly the way Lua does).  The C module that is loaded
will only ever see the environment that it loads into, which is an
instance of _G created just for it.

I don't know the Lua C interface very well, having used it only a
little.  But if a C function pokes around in its (Lua) environment, it
will only get as far as the copy of _G in which it was loaded.  For
instance, there is no metatable pointing to another environment; there
are no functions in _G whose environments point to some other
environment.  Are there other ways that a C function in a module can
escape my jail?

Note:  I had to rewrite all of loadlib.c in Lua, with only small
modifications so that I could have complete control over the
environment into which modules load.  I could have patched loadlib
instead, but I wanted to have a pure-Lua solution.  Maybe I'll write a
patch to 5.2 someday.  Or, maybe 5.2 will let me do what I need to do
using the existing loadlib.


--Jim

PS -- When I start Lua, I have Darwin loaded automatically, and I also
load a set of structure declarations so that I can simply use the
require() function to load them.  The structure definitions take up
little space because they are just declarations -- the modules they
declare are not loaded.  Some of those are:

structure.declare { name="debugger";
		    open={"_G", "debug", "string", "os", "io", "table", "coroutine"};
		    files="debugger.lua";
		 }

structure.declare { name="lanes";
		    open={"_G", "package", "table", "string"};
		    environment=[[package.initialize(); require("lanes"); return lanes]];
		 }

structure.declare { name="recordtype";
		    -- debug package is only needed because recordtype uses "strict"
		    open={"_G", "package"; "table", "string", "debug"};
		    environment=[[ require("recordtype"); return recordtype ]];
		 }

structure.declare { name="lprocess";
		    open={"package"};
		    environment=[[package.initialize(); require("lprocess"); return
lprocess]];
		 }

structure.declare { name="list";
		    location=".";
		    open={"_G"};
		    objects={"null"};
		    files="list.lua";
		 }

structure.declare { name="lfs";
		    open={"package"};
		    environment=[[ require "lfs"; return lfs ]];
		 }