[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Module system curiosity
- From: Jim Jennings <jennings.durham.nc+lua@...>
- Date: Wed, 9 Jun 2010 20:25:04 -0400
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 ]];
}