You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2015/11/19 01:12:24 UTC

[11/14] incubator-mynewt-larva git commit: Lua from eluaproject.net.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/148a95ec/libs/elua/elua_base/src/loadlib.c
----------------------------------------------------------------------
diff --git a/libs/elua/elua_base/src/loadlib.c b/libs/elua/elua_base/src/loadlib.c
new file mode 100644
index 0000000..3513245
--- /dev/null
+++ b/libs/elua/elua_base/src/loadlib.c
@@ -0,0 +1,684 @@
+/*
+** $Id: loadlib.c,v 1.52.1.4 2009/09/09 13:17:16 roberto Exp $
+** Dynamic library loader for Lua
+** See Copyright Notice in lua.h
+**
+** This module contains an implementation of loadlib for Unix systems
+** that have dlfcn, an implementation for Darwin (Mac OS X), an
+** implementation for Windows, and a stub for other systems.
+*/
+
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#define loadlib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+#include "lrotable.h"
+
+/* prefix for open functions in C libraries */
+#define LUA_POF		"luaopen_"
+
+/* separator for open functions in C libraries */
+#define LUA_OFSEP	"_"
+
+
+#define LIBPREFIX	"LOADLIB: "
+
+#define POF		LUA_POF
+#define LIB_FAIL	"open"
+
+
+/* error codes for ll_loadfunc */
+#define ERRLIB		1
+#define ERRFUNC		2
+
+#define setprogdir(L)		((void)0)
+
+
+static void ll_unloadlib (void *lib);
+static void *ll_load (lua_State *L, const char *path);
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
+
+
+
+#if defined(LUA_DL_DLOPEN)
+/*
+** {========================================================================
+** This is an implementation of loadlib based on the dlfcn interface.
+** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
+** NetBSD, AIX 4.2, HPUX 11, and  probably most other Unix flavors, at least
+** as an emulation layer on top of native functions.
+** =========================================================================
+*/
+
+#include <dlfcn.h>
+
+static void ll_unloadlib (void *lib) {
+  dlclose(lib);
+}
+
+
+static void *ll_load (lua_State *L, const char *path) {
+  void *lib = dlopen(path, RTLD_NOW);
+  if (lib == NULL) lua_pushstring(L, dlerror());
+  return lib;
+}
+
+
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+  lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
+  if (f == NULL) lua_pushstring(L, dlerror());
+  return f;
+}
+
+/* }====================================================== */
+
+
+
+#elif defined(LUA_DL_DLL)
+/*
+** {======================================================================
+** This is an implementation of loadlib for Windows using native functions.
+** =======================================================================
+*/
+
+#include <windows.h>
+
+
+#undef setprogdir
+
+static void setprogdir (lua_State *L) {
+  char buff[MAX_PATH + 1];
+  char *lb;
+  DWORD nsize = sizeof(buff)/sizeof(char);
+  DWORD n = GetModuleFileNameA(NULL, buff, nsize);
+  if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
+    luaL_error(L, "unable to get ModuleFileName");
+  else {
+    *lb = '\0';
+    luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
+    lua_remove(L, -2);  /* remove original string */
+  }
+}
+
+
+static void pusherror (lua_State *L) {
+  int error = GetLastError();
+  char buffer[128];
+  if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
+      NULL, error, 0, buffer, sizeof(buffer), NULL))
+    lua_pushstring(L, buffer);
+  else
+    lua_pushfstring(L, "system error %d\n", error);
+}
+
+static void ll_unloadlib (void *lib) {
+  FreeLibrary((HINSTANCE)lib);
+}
+
+
+static void *ll_load (lua_State *L, const char *path) {
+  HINSTANCE lib = LoadLibraryA(path);
+  if (lib == NULL) pusherror(L);
+  return lib;
+}
+
+
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+  lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
+  if (f == NULL) pusherror(L);
+  return f;
+}
+
+/* }====================================================== */
+
+
+
+#elif defined(LUA_DL_DYLD)
+/*
+** {======================================================================
+** Native Mac OS X / Darwin Implementation
+** =======================================================================
+*/
+
+#include <mach-o/dyld.h>
+
+
+/* Mac appends a `_' before C function names */
+#undef POF
+#define POF	"_" LUA_POF
+
+
+static void pusherror (lua_State *L) {
+  const char *err_str;
+  const char *err_file;
+  NSLinkEditErrors err;
+  int err_num;
+  NSLinkEditError(&err, &err_num, &err_file, &err_str);
+  lua_pushstring(L, err_str);
+}
+
+
+static const char *errorfromcode (NSObjectFileImageReturnCode ret) {
+  switch (ret) {
+    case NSObjectFileImageInappropriateFile:
+      return "file is not a bundle";
+    case NSObjectFileImageArch:
+      return "library is for wrong CPU type";
+    case NSObjectFileImageFormat:
+      return "bad format";
+    case NSObjectFileImageAccess:
+      return "cannot access file";
+    case NSObjectFileImageFailure:
+    default:
+      return "unable to load library";
+  }
+}
+
+
+static void ll_unloadlib (void *lib) {
+  NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
+}
+
+
+static void *ll_load (lua_State *L, const char *path) {
+  NSObjectFileImage img;
+  NSObjectFileImageReturnCode ret;
+  /* this would be a rare case, but prevents crashing if it happens */
+  if(!_dyld_present()) {
+    lua_pushliteral(L, "dyld not present");
+    return NULL;
+  }
+  ret = NSCreateObjectFileImageFromFile(path, &img);
+  if (ret == NSObjectFileImageSuccess) {
+    NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE |
+                       NSLINKMODULE_OPTION_RETURN_ON_ERROR);
+    NSDestroyObjectFileImage(img);
+    if (mod == NULL) pusherror(L);
+    return mod;
+  }
+  lua_pushstring(L, errorfromcode(ret));
+  return NULL;
+}
+
+
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+  NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
+  if (nss == NULL) {
+    lua_pushfstring(L, "symbol " LUA_QS " not found", sym);
+    return NULL;
+  }
+  return (lua_CFunction)NSAddressOfSymbol(nss);
+}
+
+/* }====================================================== */
+
+
+
+#else
+/*
+** {======================================================
+** Fallback for other systems
+** =======================================================
+*/
+
+#undef LIB_FAIL
+#define LIB_FAIL	"absent"
+
+
+#define DLMSG	"dynamic libraries not enabled; check your Lua installation"
+
+
+static void ll_unloadlib (void *lib) {
+  (void)lib;  /* to avoid warnings */
+}
+
+
+static void *ll_load (lua_State *L, const char *path) {
+  (void)path;  /* to avoid warnings */
+  lua_pushliteral(L, DLMSG);
+  return NULL;
+}
+
+
+static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
+  (void)lib; (void)sym;  /* to avoid warnings */
+  lua_pushliteral(L, DLMSG);
+  return NULL;
+}
+
+/* }====================================================== */
+#endif
+
+
+
+static void **ll_register (lua_State *L, const char *path) {
+  void **plib;
+  lua_pushfstring(L, "%s%s", LIBPREFIX, path);
+  lua_gettable(L, LUA_REGISTRYINDEX);  /* check library in registry? */
+  if (!lua_isnil(L, -1))  /* is there an entry? */
+    plib = (void **)lua_touserdata(L, -1);
+  else {  /* no entry yet; create one */
+    lua_pop(L, 1);
+    plib = (void **)lua_newuserdata(L, sizeof(const void *));
+    *plib = NULL;
+    luaL_getmetatable(L, "_LOADLIB");
+    lua_setmetatable(L, -2);
+    lua_pushfstring(L, "%s%s", LIBPREFIX, path);
+    lua_pushvalue(L, -2);
+    lua_settable(L, LUA_REGISTRYINDEX);
+  }
+  return plib;
+}
+
+
+/*
+** __gc tag method: calls library's `ll_unloadlib' function with the lib
+** handle
+*/
+static int gctm (lua_State *L) {
+  void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
+  if (*lib) ll_unloadlib(*lib);
+  *lib = NULL;  /* mark library as closed */
+  return 0;
+}
+
+
+static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
+  void **reg = ll_register(L, path);
+  if (*reg == NULL) *reg = ll_load(L, path);
+  if (*reg == NULL)
+    return ERRLIB;  /* unable to load library */
+  else {
+    lua_CFunction f = ll_sym(L, *reg, sym);
+    if (f == NULL)
+      return ERRFUNC;  /* unable to find function */
+    lua_pushcfunction(L, f);
+    return 0;  /* return function */
+  }
+}
+
+
+static int ll_loadlib (lua_State *L) {
+  const char *path = luaL_checkstring(L, 1);
+  const char *init = luaL_checkstring(L, 2);
+  int stat = ll_loadfunc(L, path, init);
+  if (stat == 0)  /* no errors? */
+    return 1;  /* return the loaded function */
+  else {  /* error; error message is on stack top */
+    lua_pushnil(L);
+    lua_insert(L, -2);
+    lua_pushstring(L, (stat == ERRLIB) ?  LIB_FAIL : "init");
+    return 3;  /* return nil, error message, and where */
+  }
+}
+
+
+
+/*
+** {======================================================
+** 'require' function
+** =======================================================
+*/
+
+
+static int readable (const char *filename) {
+  FILE *f = fopen(filename, "r");  /* try to open file */
+  if (f == NULL) return 0;  /* open failed */
+  fclose(f);
+  return 1;
+}
+
+
+static const char *pushnexttemplate (lua_State *L, const char *path) {
+  const char *l;
+  while (*path == *LUA_PATHSEP) path++;  /* skip separators */
+  if (*path == '\0') return NULL;  /* no more templates */
+  l = strchr(path, *LUA_PATHSEP);  /* find next separator */
+  if (l == NULL) l = path + strlen(path);
+  lua_pushlstring(L, path, l - path);  /* template */
+  return l;
+}
+
+
+static const char *findfile (lua_State *L, const char *name,
+                                           const char *pname) {
+  const char *path;
+  name = luaL_gsub(L, name, ".", LUA_DIRSEP);
+  lua_getfield(L, LUA_ENVIRONINDEX, pname);
+  path = lua_tostring(L, -1);
+  if (path == NULL)
+    luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
+  lua_pushliteral(L, "");  /* error accumulator */
+  while ((path = pushnexttemplate(L, path)) != NULL) {
+    const char *filename;
+    filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
+    lua_remove(L, -2);  /* remove path template */
+    if (readable(filename))  /* does file exist and is readable? */
+      return filename;  /* return that file name */
+    lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
+    lua_remove(L, -2);  /* remove file name */
+    lua_concat(L, 2);  /* add entry to possible error message */
+  }
+  return NULL;  /* not found */
+}
+
+
+static void loaderror (lua_State *L, const char *filename) {
+  luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
+                lua_tostring(L, 1), filename, lua_tostring(L, -1));
+}
+
+
+static int loader_Lua (lua_State *L) {
+  const char *filename;
+  const char *name = luaL_checkstring(L, 1);
+  filename = findfile(L, name, "path");
+  if (filename == NULL) return 1;  /* library not found in this path */
+  if (luaL_loadfile(L, filename) != 0)
+    loaderror(L, filename);
+  return 1;  /* library loaded successfully */
+}
+
+
+static const char *mkfuncname (lua_State *L, const char *modname) {
+  const char *funcname;
+  const char *mark = strchr(modname, *LUA_IGMARK);
+  if (mark) modname = mark + 1;
+  funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
+  funcname = lua_pushfstring(L, POF"%s", funcname);
+  lua_remove(L, -2);  /* remove 'gsub' result */
+  return funcname;
+}
+
+
+static int loader_C (lua_State *L) {
+  const char *funcname;
+  const char *name = luaL_checkstring(L, 1);
+  const char *filename = findfile(L, name, "cpath");
+  if (filename == NULL) return 1;  /* library not found in this path */
+  funcname = mkfuncname(L, name);
+  if (ll_loadfunc(L, filename, funcname) != 0)
+    loaderror(L, filename);
+  return 1;  /* library loaded successfully */
+}
+
+
+static int loader_Croot (lua_State *L) {
+  const char *funcname;
+  const char *filename;
+  const char *name = luaL_checkstring(L, 1);
+  const char *p = strchr(name, '.');
+  int stat;
+  if (p == NULL) return 0;  /* is root */
+  lua_pushlstring(L, name, p - name);
+  filename = findfile(L, lua_tostring(L, -1), "cpath");
+  if (filename == NULL) return 1;  /* root not found */
+  funcname = mkfuncname(L, name);
+  if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
+    if (stat != ERRFUNC) loaderror(L, filename);  /* real error */
+    lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
+                       name, filename);
+    return 1;  /* function not found */
+  }
+  return 1;
+}
+
+
+static int loader_preload (lua_State *L) {
+  const char *name = luaL_checkstring(L, 1);
+  lua_getfield(L, LUA_ENVIRONINDEX, "preload");
+  if (!lua_istable(L, -1))
+    luaL_error(L, LUA_QL("package.preload") " must be a table");
+  lua_getfield(L, -1, name);
+  if (lua_isnil(L, -1))  /* not found? */
+    lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
+  return 1;
+}
+
+
+static const int sentinel_ = 0;
+#define sentinel	((void *)&sentinel_)
+
+
+static int ll_require (lua_State *L) {
+  const char *name = luaL_checkstring(L, 1);
+  int i;
+  lua_settop(L, 1);  /* _LOADED table will be at index 2 */
+  lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+  lua_getfield(L, 2, name);
+  if (lua_toboolean(L, -1)) {  /* is it there? */
+    if (lua_touserdata(L, -1) == sentinel)  /* check loops */
+      luaL_error(L, "loop or previous error loading module " LUA_QS, name);
+    return 1;  /* package is already loaded */
+  }
+  /* Is this a readonly table? */
+  void *res = luaR_findglobal(name, strlen(name));
+  if (res) {
+    lua_pushrotable(L, res);
+    return 1;
+  }
+  /* else must load it; iterate over available loaders */
+  lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
+  if (!lua_istable(L, -1))
+    luaL_error(L, LUA_QL("package.loaders") " must be a table");
+  lua_pushliteral(L, "");  /* error message accumulator */
+  for (i=1; ; i++) {
+    lua_rawgeti(L, -2, i);  /* get a loader */
+    if (lua_isnil(L, -1))
+      luaL_error(L, "module " LUA_QS " not found:%s",
+                    name, lua_tostring(L, -2));
+    lua_pushstring(L, name);
+    lua_call(L, 1, 1);  /* call it */
+    if (lua_isfunction(L, -1))  /* did it find module? */
+      break;  /* module loaded successfully */
+    else if (lua_isstring(L, -1))  /* loader returned error message? */
+      lua_concat(L, 2);  /* accumulate it */
+    else
+      lua_pop(L, 1);
+  }
+  lua_pushlightuserdata(L, sentinel);
+  lua_setfield(L, 2, name);  /* _LOADED[name] = sentinel */
+  lua_pushstring(L, name);  /* pass name as argument to module */
+  lua_call(L, 1, 1);  /* run loaded module */
+  if (!lua_isnil(L, -1))  /* non-nil return? */
+    lua_setfield(L, 2, name);  /* _LOADED[name] = returned value */
+  lua_getfield(L, 2, name);
+  if (lua_touserdata(L, -1) == sentinel) {   /* module did not set a value? */
+    lua_pushboolean(L, 1);  /* use true as result */
+    lua_pushvalue(L, -1);  /* extra copy to be returned */
+    lua_setfield(L, 2, name);  /* _LOADED[name] = true */
+  }
+  return 1;
+}
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** 'module' function
+** =======================================================
+*/
+  
+
+static void setfenv (lua_State *L) {
+  lua_Debug ar;
+  if (lua_getstack(L, 1, &ar) == 0 ||
+      lua_getinfo(L, "f", &ar) == 0 ||  /* get calling function */
+      lua_iscfunction(L, -1))
+    luaL_error(L, LUA_QL("module") " not called from a Lua function");
+  lua_pushvalue(L, -2);
+  lua_setfenv(L, -2);
+  lua_pop(L, 1);
+}
+
+
+static void dooptions (lua_State *L, int n) {
+  int i;
+  for (i = 2; i <= n; i++) {
+    lua_pushvalue(L, i);  /* get option (a function) */
+    lua_pushvalue(L, -2);  /* module */
+    lua_call(L, 1, 0);
+  }
+}
+
+
+static void modinit (lua_State *L, const char *modname) {
+  const char *dot;
+  lua_pushvalue(L, -1);
+  lua_setfield(L, -2, "_M");  /* module._M = module */
+  lua_pushstring(L, modname);
+  lua_setfield(L, -2, "_NAME");
+  dot = strrchr(modname, '.');  /* look for last dot in module name */
+  if (dot == NULL) dot = modname;
+  else dot++;
+  /* set _PACKAGE as package name (full module name minus last part) */
+  lua_pushlstring(L, modname, dot - modname);
+  lua_setfield(L, -2, "_PACKAGE");
+}
+
+
+static int ll_module (lua_State *L) {
+  const char *modname = luaL_checkstring(L, 1);
+  if (luaR_findglobal(modname, strlen(modname)))
+    return 0;
+  int loaded = lua_gettop(L) + 1;  /* index of _LOADED table */
+  lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+  lua_getfield(L, loaded, modname);  /* get _LOADED[modname] */
+  if (!lua_istable(L, -1)) {  /* not found? */
+    lua_pop(L, 1);  /* remove previous result */
+    /* try global variable (and create one if it does not exist) */
+    if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
+      return luaL_error(L, "name conflict for module " LUA_QS, modname);
+    lua_pushvalue(L, -1);
+    lua_setfield(L, loaded, modname);  /* _LOADED[modname] = new table */
+  }
+  /* check whether table already has a _NAME field */
+  lua_getfield(L, -1, "_NAME");
+  if (!lua_isnil(L, -1))  /* is table an initialized module? */
+    lua_pop(L, 1);
+  else {  /* no; initialize it */
+    lua_pop(L, 1);
+    modinit(L, modname);
+  }
+  lua_pushvalue(L, -1);
+  setfenv(L);
+  dooptions(L, loaded - 1);
+  return 0;
+}
+
+
+static int ll_seeall (lua_State *L) {
+  luaL_checktype(L, 1, LUA_TTABLE);
+  if (!lua_getmetatable(L, 1)) {
+    lua_createtable(L, 0, 1); /* create new metatable */
+    lua_pushvalue(L, -1);
+    lua_setmetatable(L, 1);
+  }
+  lua_pushvalue(L, LUA_GLOBALSINDEX);
+  lua_setfield(L, -2, "__index");  /* mt.__index = _G */
+  return 0;
+}
+
+
+/* }====================================================== */
+
+
+
+/* auxiliary mark (for internal use) */
+#define AUXMARK		"\1"
+
+static void setpath (lua_State *L, const char *fieldname, const char *envname,
+                                   const char *def) {
+  const char *path = getenv(envname);
+  if (path == NULL)  /* no environment variable? */
+    lua_pushstring(L, def);  /* use default */
+  else {
+    /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
+    path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
+                              LUA_PATHSEP AUXMARK LUA_PATHSEP);
+    luaL_gsub(L, path, AUXMARK, def);
+    lua_remove(L, -2);
+  }
+  setprogdir(L);
+  lua_setfield(L, -2, fieldname);
+}
+
+
+static const luaL_Reg pk_funcs[] = {
+  {"loadlib", ll_loadlib},
+  {"seeall", ll_seeall},
+  {NULL, NULL}
+};
+
+
+static const luaL_Reg ll_funcs[] = {
+  {"module", ll_module},
+  {"require", ll_require},
+  {NULL, NULL}
+};
+
+
+static const lua_CFunction loaders[] =
+  {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
+
+#if LUA_OPTIMIZE_MEMORY > 0
+const luaR_entry lmt[] = {
+  {LRO_STRKEY("__gc"), LRO_FUNCVAL(gctm)},
+  {LRO_NILKEY, LRO_NILVAL}
+};
+#endif
+
+LUALIB_API int luaopen_package (lua_State *L) {
+  int i;
+  /* create new type _LOADLIB */
+#if LUA_OPTIMIZE_MEMORY == 0
+  luaL_newmetatable(L, "_LOADLIB");
+  lua_pushlightfunction(L, gctm);
+  lua_setfield(L, -2, "__gc");
+#else
+  luaL_rometatable(L, "_LOADLIB", (void*)lmt);
+#endif
+  /* create `package' table */
+  luaL_register_light(L, LUA_LOADLIBNAME, pk_funcs);
+#if defined(LUA_COMPAT_LOADLIB) 
+  lua_getfield(L, -1, "loadlib");
+  lua_setfield(L, LUA_GLOBALSINDEX, "loadlib");
+#endif
+  lua_pushvalue(L, -1);
+  lua_replace(L, LUA_ENVIRONINDEX);
+  /* create `loaders' table */
+  lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0);
+  /* fill it with pre-defined loaders */
+  for (i=0; loaders[i] != NULL; i++) {
+    lua_pushcfunction(L, loaders[i]);
+    lua_rawseti(L, -2, i+1);
+  }
+  lua_setfield(L, -2, "loaders");  /* put it in field `loaders' */
+  setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT);  /* set field `path' */
+  setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */
+  /* store config information */
+  lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n"
+                     LUA_EXECDIR "\n" LUA_IGMARK);
+  lua_setfield(L, -2, "config");
+  /* set field `loaded' */
+  luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2);
+  lua_setfield(L, -2, "loaded");
+  /* set field `preload' */
+  lua_newtable(L);
+  lua_setfield(L, -2, "preload");
+  lua_pushvalue(L, LUA_GLOBALSINDEX);
+  luaL_register(L, NULL, ll_funcs);  /* open lib into global table */
+  lua_pop(L, 1);
+  return 1;  /* return 'package' table */
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/148a95ec/libs/elua/elua_base/src/lobject.c
----------------------------------------------------------------------
diff --git a/libs/elua/elua_base/src/lobject.c b/libs/elua/elua_base/src/lobject.c
new file mode 100644
index 0000000..6c987f6
--- /dev/null
+++ b/libs/elua/elua_base/src/lobject.c
@@ -0,0 +1,216 @@
+/*
+** $Id: lobject.c,v 2.22.1.1 2007/12/27 13:02:25 roberto Exp $
+** Some generic functions over Lua objects
+** See Copyright Notice in lua.h
+*/
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define lobject_c
+#define LUA_CORE
+
+#include "lua.h"
+
+#include "ldo.h"
+#include "lmem.h"
+#include "lobject.h"
+#include "lstate.h"
+#include "lstring.h"
+#include "lvm.h"
+
+
+
+const TValue luaO_nilobject_ = {LUA_TVALUE_NIL};
+
+
+/*
+** converts an integer to a "floating point byte", represented as
+** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
+** eeeee != 0 and (xxx) otherwise.
+*/
+int luaO_int2fb (unsigned int x) {
+  int e = 0;  /* expoent */
+  while (x >= 16) {
+    x = (x+1) >> 1;
+    e++;
+  }
+  if (x < 8) return x;
+  else return ((e+1) << 3) | (cast_int(x) - 8);
+}
+
+
+/* converts back */
+int luaO_fb2int (int x) {
+  int e = (x >> 3) & 31;
+  if (e == 0) return x;
+  else return ((x & 7)+8) << (e - 1);
+}
+
+
+int luaO_log2 (unsigned int x) {
+  static const lu_byte log_2[256] = {
+    0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+    8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
+  };
+  int l = -1;
+  while (x >= 256) { l += 8; x >>= 8; }
+  return l + log_2[x];
+
+}
+
+
+int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
+  if (ttype(t1) != ttype(t2)) return 0;
+  else switch (ttype(t1)) {
+    case LUA_TNIL:
+      return 1;
+    case LUA_TNUMBER:
+      return luai_numeq(nvalue(t1), nvalue(t2));
+    case LUA_TBOOLEAN:
+      return bvalue(t1) == bvalue(t2);  /* boolean true must be 1 !! */
+    case LUA_TLIGHTUSERDATA:
+    case LUA_TROTABLE:
+    case LUA_TLIGHTFUNCTION:
+      return pvalue(t1) == pvalue(t2);
+    default:
+      lua_assert(iscollectable(t1));
+      return gcvalue(t1) == gcvalue(t2);
+  }
+}
+
+
+int luaO_str2d (const char *s, lua_Number *result) {
+  char *endptr;
+  *result = lua_str2number(s, &endptr);
+  if (endptr == s) return 0;  /* conversion failed */
+  if (*endptr == 'x' || *endptr == 'X')  /* maybe an hexadecimal constant? */
+    *result = cast_num(strtoul(s, &endptr, 16));
+  if (*endptr == '\0') return 1;  /* most common case */
+  while (isspace(cast(unsigned char, *endptr))) endptr++;
+  if (*endptr != '\0') return 0;  /* invalid trailing characters? */
+  return 1;
+}
+
+
+
+static void pushstr (lua_State *L, const char *str) {
+  setsvalue2s(L, L->top, luaS_new(L, str));
+  incr_top(L);
+}
+
+
+/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
+const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
+  int n = 1;
+  pushstr(L, "");
+  for (;;) {
+    const char *e = strchr(fmt, '%');
+    if (e == NULL) break;
+    setsvalue2s(L, L->top, luaS_newlstr(L, fmt, e-fmt));
+    incr_top(L);
+    switch (*(e+1)) {
+      case 's': {
+        const char *s = va_arg(argp, char *);
+        if (s == NULL) s = "(null)";
+        pushstr(L, s);
+        break;
+      }
+      case 'c': {
+        char buff[2];
+        buff[0] = cast(char, va_arg(argp, int));
+        buff[1] = '\0';
+        pushstr(L, buff);
+        break;
+      }
+      case 'd': {
+        setnvalue(L->top, cast_num(va_arg(argp, int)));
+        incr_top(L);
+        break;
+      }
+      case 'f': {
+        setnvalue(L->top, cast_num(va_arg(argp, l_uacNumber)));
+        incr_top(L);
+        break;
+      }
+      case 'p': {
+        char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
+        sprintf(buff, "%p", va_arg(argp, void *));
+        pushstr(L, buff);
+        break;
+      }
+      case '%': {
+        pushstr(L, "%");
+        break;
+      }
+      default: {
+        char buff[3];
+        buff[0] = '%';
+        buff[1] = *(e+1);
+        buff[2] = '\0';
+        pushstr(L, buff);
+        break;
+      }
+    }
+    n += 2;
+    fmt = e+2;
+  }
+  pushstr(L, fmt);
+  luaV_concat(L, n+1, cast_int(L->top - L->base) - 1);
+  L->top -= n;
+  return svalue(L->top - 1);
+}
+
+
+const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
+  const char *msg;
+  va_list argp;
+  va_start(argp, fmt);
+  msg = luaO_pushvfstring(L, fmt, argp);
+  va_end(argp);
+  return msg;
+}
+
+
+void luaO_chunkid (char *out, const char *source, size_t bufflen) {
+  if (*source == '=') {
+    strncpy(out, source+1, bufflen);  /* remove first char */
+    out[bufflen-1] = '\0';  /* ensures null termination */
+  }
+  else {  /* out = "source", or "...source" */
+    if (*source == '@') {
+      size_t l;
+      source++;  /* skip the `@' */
+      bufflen -= sizeof(" '...' ");
+      l = strlen(source);
+      strcpy(out, "");
+      if (l > bufflen) {
+        source += (l-bufflen);  /* get last part of file name */
+        strcat(out, "...");
+      }
+      strcat(out, source);
+    }
+    else {  /* out = [string "string"] */
+      size_t len = strcspn(source, "\n\r");  /* stop at first newline */
+      bufflen -= sizeof(" [string \"...\"] ");
+      if (len > bufflen) len = bufflen;
+      strcpy(out, "[string \"");
+      if (source[len] != '\0') {  /* must truncate? */
+        strncat(out, source, len);
+        strcat(out, "...");
+      }
+      else
+        strcat(out, source);
+      strcat(out, "\"]");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/148a95ec/libs/elua/elua_base/src/lobject.h
----------------------------------------------------------------------
diff --git a/libs/elua/elua_base/src/lobject.h b/libs/elua/elua_base/src/lobject.h
new file mode 100644
index 0000000..55532f4
--- /dev/null
+++ b/libs/elua/elua_base/src/lobject.h
@@ -0,0 +1,557 @@
+/*
+** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $
+** Type definitions for Lua objects
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lobject_h
+#define lobject_h
+
+
+#include <stdarg.h>
+
+
+#include "llimits.h"
+#include "lua.h"
+
+
+/* tags for values visible from Lua */
+#define LAST_TAG	LUA_TTHREAD
+
+#define NUM_TAGS	(LAST_TAG+1)
+
+/* mask for 'read-only' objects. must match READONLYBIT in lgc.h' */
+#define READONLYMASK  128
+
+
+/*
+** Extra tags for non-values
+*/
+#define LUA_TPROTO	(LAST_TAG+1)
+#define LUA_TUPVAL	(LAST_TAG+2)
+#define LUA_TDEADKEY	(LAST_TAG+3)
+
+
+/*
+** Union of all collectable objects
+*/
+typedef union GCObject GCObject;
+
+
+/*
+** Common Header for all collectable objects (in macro form, to be
+** included in other objects)
+*/
+#define CommonHeader	GCObject *next; lu_byte tt; lu_byte marked
+
+
+/*
+** Common header in struct form
+*/
+typedef struct GCheader {
+  CommonHeader;
+} GCheader;
+
+
+
+
+/*
+** Union of all Lua values
+*/
+#if defined( LUA_PACK_VALUE ) && defined( ELUA_ENDIAN_BIG )
+typedef union {
+  struct {
+    int _pad0;
+    GCObject *gc;
+  };
+  struct {
+    int _pad1;
+    void *p;
+  };
+  lua_Number n;
+  struct {
+    int _pad2;
+    int b;
+  };
+} Value;
+#else // #if defined( LUA_PACK_VALUE ) && defined( ELUA_ENDIAN_BIG )
+typedef union {
+  GCObject *gc;
+  void *p;
+  lua_Number n;
+  int b;
+} Value;
+#endif // #if defined( LUA_PACK_VALUE ) && defined( ELUA_ENDIAN_BIG )
+
+/*
+** Tagged Values
+*/
+
+#ifndef LUA_PACK_VALUE
+#define TValuefields	Value value; int tt
+#define LUA_TVALUE_NIL {NULL}, LUA_TNIL
+
+typedef struct lua_TValue {
+  TValuefields;
+} TValue;
+#else // #ifndef LUA_PACK_VALUE
+#ifdef ELUA_ENDIAN_LITTLE
+#define TValuefields union { \
+  struct { \
+    int _pad0; \
+    int tt_sig; \
+  } _ts; \
+  struct { \
+    int _pad; \
+    short tt; \
+    short sig; \
+  } _t; \
+  Value value; \
+}
+#define LUA_TVALUE_NIL {0, add_sig(LUA_TNIL)}
+#else // #ifdef ELUA_ENDIAN_LITTLE
+#define TValuefields union { \
+  struct { \
+    int tt_sig; \
+    int _pad0; \
+  } _ts; \
+  struct { \
+    short sig; \
+    short tt; \
+    int _pad; \
+  } _t; \
+  Value value; \
+}
+#define LUA_TVALUE_NIL {add_sig(LUA_TNIL), 0}
+#endif // #ifdef ELUA_ENDIAN_LITTLE
+#define LUA_NOTNUMBER_SIG (-1)
+#define add_sig(tt) ( 0xffff0000 | (tt) )
+
+typedef TValuefields TValue;
+#endif // #ifndef LUA_PACK_VALUE
+
+/* Macros to test type */
+#ifndef LUA_PACK_VALUE
+#define ttisnil(o)	(ttype(o) == LUA_TNIL)
+#define ttisnumber(o)	(ttype(o) == LUA_TNUMBER)
+#define ttisstring(o)	(ttype(o) == LUA_TSTRING)
+#define ttistable(o)	(ttype(o) == LUA_TTABLE)
+#define ttisfunction(o)	(ttype(o) == LUA_TFUNCTION)
+#define ttisboolean(o)	(ttype(o) == LUA_TBOOLEAN)
+#define ttisuserdata(o)	(ttype(o) == LUA_TUSERDATA)
+#define ttisthread(o)	(ttype(o) == LUA_TTHREAD)
+#define ttislightuserdata(o)	(ttype(o) == LUA_TLIGHTUSERDATA)
+#define ttisrotable(o) (ttype(o) == LUA_TROTABLE)
+#define ttislightfunction(o)  (ttype(o) == LUA_TLIGHTFUNCTION)
+#else // #ifndef LUA_PACK_VALUE
+#define ttisnil(o) (ttype_sig(o) == add_sig(LUA_TNIL))
+#define ttisnumber(o)  ((o)->_t.sig != LUA_NOTNUMBER_SIG)
+#define ttisstring(o)  (ttype_sig(o) == add_sig(LUA_TSTRING))
+#define ttistable(o) (ttype_sig(o) == add_sig(LUA_TTABLE))
+#define ttisfunction(o)  (ttype_sig(o) == add_sig(LUA_TFUNCTION))
+#define ttisboolean(o) (ttype_sig(o) == add_sig(LUA_TBOOLEAN))
+#define ttisuserdata(o)  (ttype_sig(o) == add_sig(LUA_TUSERDATA))
+#define ttisthread(o)  (ttype_sig(o) == add_sig(LUA_TTHREAD))
+#define ttislightuserdata(o) (ttype_sig(o) == add_sig(LUA_TLIGHTUSERDATA))
+#define ttisrotable(o) (ttype_sig(o) == add_sig(LUA_TROTABLE))
+#define ttislightfunction(o)  (ttype_sig(o) == add_sig(LUA_TLIGHTFUNCTION))
+#endif // #ifndef LUA_PACK_VALUE
+
+/* Macros to access values */
+#ifndef LUA_PACK_VALUE
+#define ttype(o)	((o)->tt)
+#else // #ifndef LUA_PACK_VALUE
+#define ttype(o)	((o)->_t.sig == LUA_NOTNUMBER_SIG ? (o)->_t.tt : LUA_TNUMBER)
+#define ttype_sig(o)	((o)->_ts.tt_sig)
+#endif // #ifndef LUA_PACK_VALUE
+#define gcvalue(o)	check_exp(iscollectable(o), (o)->value.gc)
+#define pvalue(o)	check_exp(ttislightuserdata(o), (o)->value.p)
+#define rvalue(o)	check_exp(ttisrotable(o), (o)->value.p)
+#define fvalue(o) check_exp(ttislightfunction(o), (o)->value.p)
+#define nvalue(o)	check_exp(ttisnumber(o), (o)->value.n)
+#define rawtsvalue(o)	check_exp(ttisstring(o), &(o)->value.gc->ts)
+#define tsvalue(o)	(&rawtsvalue(o)->tsv)
+#define rawuvalue(o)	check_exp(ttisuserdata(o), &(o)->value.gc->u)
+#define uvalue(o)	(&rawuvalue(o)->uv)
+#define clvalue(o)	check_exp(ttisfunction(o), &(o)->value.gc->cl)
+#define hvalue(o)	check_exp(ttistable(o), &(o)->value.gc->h)
+#define bvalue(o)	check_exp(ttisboolean(o), (o)->value.b)
+#define thvalue(o)	check_exp(ttisthread(o), &(o)->value.gc->th)
+
+#define l_isfalse(o)	(ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
+
+/*
+** for internal debug only
+*/
+#ifndef LUA_PACK_VALUE
+#define checkconsistency(obj) \
+  lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
+
+#define checkliveness(g,obj) \
+  lua_assert(!iscollectable(obj) || \
+  ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
+#else // #ifndef LUA_PACK_VALUE
+#define checkconsistency(obj) \
+  lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch._t.tt))
+
+#define checkliveness(g,obj) \
+  lua_assert(!iscollectable(obj) || \
+  ((ttype(obj) == (obj)->value.gc->gch._t.tt) && !isdead(g, (obj)->value.gc)))
+#endif // #ifndef LUA_PACK_VALUE
+
+/* Macros to set values */
+#ifndef LUA_PACK_VALUE
+#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
+
+#define setnvalue(obj,x) \
+  { lua_Number i_x = (x); TValue *i_o=(obj); i_o->value.n=i_x; i_o->tt=LUA_TNUMBER; }
+
+#define setpvalue(obj,x) \
+  { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTUSERDATA; }
+  
+#define setrvalue(obj,x) \
+  { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TROTABLE; }
+  
+#define setfvalue(obj,x) \
+  { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTFUNCTION; }
+
+#define setbvalue(obj,x) \
+  { int i_x = (x); TValue *i_o=(obj); i_o->value.b=i_x; i_o->tt=LUA_TBOOLEAN; }
+
+#define setsvalue(L,obj,x) \
+  { GCObject *i_x = cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->tt=LUA_TSTRING; \
+    checkliveness(G(L),i_o); }
+
+#define setuvalue(L,obj,x) \
+  { GCObject *i_x = cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->tt=LUA_TUSERDATA; \
+    checkliveness(G(L),i_o); }
+
+#define setthvalue(L,obj,x) \
+  { GCObject *i_x = cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->tt=LUA_TTHREAD; \
+    checkliveness(G(L),i_o); }
+
+#define setclvalue(L,obj,x) \
+  { GCObject *i_x = cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->tt=LUA_TFUNCTION; \
+    checkliveness(G(L),i_o); }
+
+#define sethvalue(L,obj,x) \
+  { GCObject *i_x = cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->tt=LUA_TTABLE; \
+    checkliveness(G(L),i_o); }
+
+#define setptvalue(L,obj,x) \
+  { GCObject *i_x = cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->tt=LUA_TPROTO; \
+    checkliveness(G(L),i_o); }
+
+
+
+
+#define setobj(L,obj1,obj2) \
+  { const TValue *o2=(obj2); TValue *o1=(obj1); \
+    o1->value = o2->value; o1->tt=o2->tt; \
+    checkliveness(G(L),o1); }
+#else // #ifndef LUA_PACK_VALUE
+#define setnilvalue(obj) ( ttype_sig(obj) = add_sig(LUA_TNIL) )
+
+#define setnvalue(obj,x) \
+  { TValue *i_o=(obj); i_o->value.n=(x); }
+
+#define setpvalue(obj,x) \
+  { TValue *i_o=(obj); i_o->value.p=(x); i_o->_ts.tt_sig=add_sig(LUA_TLIGHTUSERDATA);}
+
+#define setrvalue(obj,x) \
+  { TValue *i_o=(obj); i_o->value.p=(x); i_o->_ts.tt_sig=add_sig(LUA_TROTABLE);}
+
+#define setfvalue(obj,x) \
+  { TValue *i_o=(obj); i_o->value.p=(x); i_o->_ts.tt_sig=add_sig(LUA_TLIGHTFUNCTION);}
+
+#define setbvalue(obj,x) \
+  { TValue *i_o=(obj); i_o->value.b=(x); i_o->_ts.tt_sig=add_sig(LUA_TBOOLEAN);}
+
+#define setsvalue(L,obj,x) \
+  { GCObject *i_x=cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->_ts.tt_sig=add_sig(LUA_TSTRING); \
+    checkliveness(G(L),i_o); }
+
+#define setuvalue(L,obj,x) \
+  { GCObject *i_x=cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->_ts.tt_sig=add_sig(LUA_TUSERDATA); \
+    checkliveness(G(L),i_o); }
+
+#define setthvalue(L,obj,x) \
+  { GCObject *i_x=cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->_ts.tt_sig=add_sig(LUA_TTHREAD); \
+    checkliveness(G(L),i_o); }
+
+#define setclvalue(L,obj,x) \
+  { GCObject *i_x=cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->_ts.tt_sig=add_sig(LUA_TFUNCTION); \
+    checkliveness(G(L),i_o); }
+
+#define sethvalue(L,obj,x) \
+  { GCObject *i_x=cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->_ts.tt_sig=add_sig(LUA_TTABLE); \
+    checkliveness(G(L),i_o); }
+
+#define setptvalue(L,obj,x) \
+  { GCObject *i_x=cast(GCObject *, (x)); \
+    TValue *i_o=(obj); \
+    i_o->value.gc=i_x; i_o->_ts.tt_sig=add_sig(LUA_TPROTO); \
+    checkliveness(G(L),i_o); }
+
+
+
+
+#define setobj(L,obj1,obj2) \
+  { const TValue *o2=(obj2); TValue *o1=(obj1); \
+    o1->value = o2->value; \
+    checkliveness(G(L),o1); }
+#endif // #ifndef LUA_PACK_VALUE
+
+/*
+** different types of sets, according to destination
+*/
+
+/* from stack to (same) stack */
+#define setobjs2s	setobj
+/* to stack (not from same stack) */
+#define setobj2s	setobj
+#define setsvalue2s	setsvalue
+#define sethvalue2s	sethvalue
+#define setptvalue2s	setptvalue
+/* from table to same table */
+#define setobjt2t	setobj
+/* to table */
+#define setobj2t	setobj
+/* to new object */
+#define setobj2n	setobj
+#define setsvalue2n	setsvalue
+
+#ifndef LUA_PACK_VALUE
+#define setttype(obj, tt) (ttype(obj) = (tt))
+#else // #ifndef LUA_PACK_VALUE
+/* considering it used only in lgc to set LUA_TDEADKEY */
+/* we could define it this way */
+#define setttype(obj, _tt) ( ttype_sig(obj) = add_sig(_tt) )
+#endif // #ifndef LUA_PACK_VALUE
+
+#define iscollectable(o)	(ttype(o) >= LUA_TSTRING)
+
+
+
+typedef TValue *StkId;  /* index to stack elements */
+
+
+/*
+** String headers for string table
+*/
+typedef union TString {
+  L_Umaxalign dummy;  /* ensures maximum alignment for strings */
+  struct {
+    CommonHeader;
+    unsigned int hash;
+    size_t len;
+  } tsv;
+} TString;
+
+
+#define getstr(ts)	(((ts)->tsv.marked & READONLYMASK) ? cast(const char *, *(const char**)((ts) + 1)) : cast(const char *, (ts) + 1))
+#define svalue(o)       getstr(rawtsvalue(o))
+
+
+
+typedef union Udata {
+  L_Umaxalign dummy;  /* ensures maximum alignment for `local' udata */
+  struct {
+    CommonHeader;
+    struct Table *metatable;
+    struct Table *env;
+    size_t len;
+  } uv;
+} Udata;
+
+
+
+
+/*
+** Function Prototypes
+*/
+typedef struct Proto {
+  CommonHeader;
+  TValue *k;  /* constants used by the function */
+  Instruction *code;
+  struct Proto **p;  /* functions defined inside the function */
+  int *lineinfo;  /* map from opcodes to source lines */
+  struct LocVar *locvars;  /* information about local variables */
+  TString **upvalues;  /* upvalue names */
+  TString  *source;
+  int sizeupvalues;
+  int sizek;  /* size of `k' */
+  int sizecode;
+  int sizelineinfo;
+  int sizep;  /* size of `p' */
+  int sizelocvars;
+  int linedefined;
+  int lastlinedefined;
+  GCObject *gclist;
+  lu_byte nups;  /* number of upvalues */
+  lu_byte numparams;
+  lu_byte is_vararg;
+  lu_byte maxstacksize;
+} Proto;
+
+
+/* masks for new-style vararg */
+#define VARARG_HASARG		1
+#define VARARG_ISVARARG		2
+#define VARARG_NEEDSARG		4
+
+
+typedef struct LocVar {
+  TString *varname;
+  int startpc;  /* first point where variable is active */
+  int endpc;    /* first point where variable is dead */
+} LocVar;
+
+
+
+/*
+** Upvalues
+*/
+
+typedef struct UpVal {
+  CommonHeader;
+  TValue *v;  /* points to stack or to its own value */
+  union {
+    TValue value;  /* the value (when closed) */
+    struct {  /* double linked list (when open) */
+      struct UpVal *prev;
+      struct UpVal *next;
+    } l;
+  } u;
+} UpVal;
+
+
+/*
+** Closures
+*/
+
+#define ClosureHeader \
+	CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
+	struct Table *env
+
+typedef struct CClosure {
+  ClosureHeader;
+  lua_CFunction f;
+  TValue upvalue[1];
+} CClosure;
+
+
+typedef struct LClosure {
+  ClosureHeader;
+  struct Proto *p;
+  UpVal *upvals[1];
+} LClosure;
+
+
+typedef union Closure {
+  CClosure c;
+  LClosure l;
+} Closure;
+
+
+#define iscfunction(o)	((ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)||(ttype(o)==LUA_TLIGHTFUNCTION))
+#define isLfunction(o)	(ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
+
+
+/*
+** Tables
+*/
+
+#ifndef LUA_PACK_VALUE
+typedef union TKey {
+  struct {
+    TValuefields;
+    struct Node *next;  /* for chaining */
+  } nk;
+  TValue tvk;
+} TKey;
+
+#define LUA_TKEY_NIL {LUA_TVALUE_NIL, NULL}
+#else // #ifndef LUA_PACK_VALUE
+typedef struct TKey {
+  TValue tvk;
+  struct {
+     struct Node *next; /* for chaining */
+  } nk;
+} TKey;
+
+#define LUA_TKEY_NIL {LUA_TVALUE_NIL}, {NULL}
+#endif // #ifndef LUA_PACK_VALUE
+
+typedef struct Node {
+  TValue i_val;
+  TKey i_key;
+} Node;
+
+
+typedef struct Table {
+  CommonHeader;
+  lu_byte flags;  /* 1<<p means tagmethod(p) is not present */ 
+  lu_byte lsizenode;  /* log2 of size of `node' array */
+  struct Table *metatable;
+  TValue *array;  /* array part */
+  Node *node;
+  Node *lastfree;  /* any free position is before this position */
+  GCObject *gclist;
+  int sizearray;  /* size of `array' array */
+} Table;
+
+
+/*
+** `module' operation for hashing (size is always a power of 2)
+*/
+#define lmod(s,size) \
+	(check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
+
+
+#define twoto(x)	(1<<(x))
+#define sizenode(t)	(twoto((t)->lsizenode))
+
+
+#define luaO_nilobject		(&luaO_nilobject_)
+
+LUAI_DATA const TValue luaO_nilobject_;
+
+#define ceillog2(x)	(luaO_log2((x)-1) + 1)
+
+LUAI_FUNC int luaO_log2 (unsigned int x);
+LUAI_FUNC int luaO_int2fb (unsigned int x);
+LUAI_FUNC int luaO_fb2int (int x);
+LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
+LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
+LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
+                                                       va_list argp);
+LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
+LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
+
+
+#endif
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/148a95ec/libs/elua/elua_base/src/lopcodes.c
----------------------------------------------------------------------
diff --git a/libs/elua/elua_base/src/lopcodes.c b/libs/elua/elua_base/src/lopcodes.c
new file mode 100644
index 0000000..4cc7452
--- /dev/null
+++ b/libs/elua/elua_base/src/lopcodes.c
@@ -0,0 +1,102 @@
+/*
+** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
+** See Copyright Notice in lua.h
+*/
+
+
+#define lopcodes_c
+#define LUA_CORE
+
+
+#include "lopcodes.h"
+
+
+/* ORDER OP */
+
+const char *const luaP_opnames[NUM_OPCODES+1] = {
+  "MOVE",
+  "LOADK",
+  "LOADBOOL",
+  "LOADNIL",
+  "GETUPVAL",
+  "GETGLOBAL",
+  "GETTABLE",
+  "SETGLOBAL",
+  "SETUPVAL",
+  "SETTABLE",
+  "NEWTABLE",
+  "SELF",
+  "ADD",
+  "SUB",
+  "MUL",
+  "DIV",
+  "MOD",
+  "POW",
+  "UNM",
+  "NOT",
+  "LEN",
+  "CONCAT",
+  "JMP",
+  "EQ",
+  "LT",
+  "LE",
+  "TEST",
+  "TESTSET",
+  "CALL",
+  "TAILCALL",
+  "RETURN",
+  "FORLOOP",
+  "FORPREP",
+  "TFORLOOP",
+  "SETLIST",
+  "CLOSE",
+  "CLOSURE",
+  "VARARG",
+  NULL
+};
+
+
+#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
+
+const lu_byte luaP_opmodes[NUM_OPCODES] = {
+/*       T  A    B       C     mode		   opcode	*/
+  opmode(0, 1, OpArgR, OpArgN, iABC) 		/* OP_MOVE */
+ ,opmode(0, 1, OpArgK, OpArgN, iABx)		/* OP_LOADK */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_LOADBOOL */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_LOADNIL */
+ ,opmode(0, 1, OpArgU, OpArgN, iABC)		/* OP_GETUPVAL */
+ ,opmode(0, 1, OpArgK, OpArgN, iABx)		/* OP_GETGLOBAL */
+ ,opmode(0, 1, OpArgR, OpArgK, iABC)		/* OP_GETTABLE */
+ ,opmode(0, 0, OpArgK, OpArgN, iABx)		/* OP_SETGLOBAL */
+ ,opmode(0, 0, OpArgU, OpArgN, iABC)		/* OP_SETUPVAL */
+ ,opmode(0, 0, OpArgK, OpArgK, iABC)		/* OP_SETTABLE */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_NEWTABLE */
+ ,opmode(0, 1, OpArgR, OpArgK, iABC)		/* OP_SELF */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_ADD */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_SUB */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_MUL */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_DIV */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_MOD */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC)		/* OP_POW */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_UNM */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_NOT */
+ ,opmode(0, 1, OpArgR, OpArgN, iABC)		/* OP_LEN */
+ ,opmode(0, 1, OpArgR, OpArgR, iABC)		/* OP_CONCAT */
+ ,opmode(0, 0, OpArgR, OpArgN, iAsBx)		/* OP_JMP */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC)		/* OP_EQ */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC)		/* OP_LT */
+ ,opmode(1, 0, OpArgK, OpArgK, iABC)		/* OP_LE */
+ ,opmode(1, 1, OpArgR, OpArgU, iABC)		/* OP_TEST */
+ ,opmode(1, 1, OpArgR, OpArgU, iABC)		/* OP_TESTSET */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_CALL */
+ ,opmode(0, 1, OpArgU, OpArgU, iABC)		/* OP_TAILCALL */
+ ,opmode(0, 0, OpArgU, OpArgN, iABC)		/* OP_RETURN */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx)		/* OP_FORLOOP */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx)		/* OP_FORPREP */
+ ,opmode(1, 0, OpArgN, OpArgU, iABC)		/* OP_TFORLOOP */
+ ,opmode(0, 0, OpArgU, OpArgU, iABC)		/* OP_SETLIST */
+ ,opmode(0, 0, OpArgN, OpArgN, iABC)		/* OP_CLOSE */
+ ,opmode(0, 1, OpArgU, OpArgN, iABx)		/* OP_CLOSURE */
+ ,opmode(0, 1, OpArgU, OpArgN, iABC)		/* OP_VARARG */
+};
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/148a95ec/libs/elua/elua_base/src/lopcodes.h
----------------------------------------------------------------------
diff --git a/libs/elua/elua_base/src/lopcodes.h b/libs/elua/elua_base/src/lopcodes.h
new file mode 100644
index 0000000..41224d6
--- /dev/null
+++ b/libs/elua/elua_base/src/lopcodes.h
@@ -0,0 +1,268 @@
+/*
+** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $
+** Opcodes for Lua virtual machine
+** See Copyright Notice in lua.h
+*/
+
+#ifndef lopcodes_h
+#define lopcodes_h
+
+#include "llimits.h"
+
+
+/*===========================================================================
+  We assume that instructions are unsigned numbers.
+  All instructions have an opcode in the first 6 bits.
+  Instructions can have the following fields:
+	`A' : 8 bits
+	`B' : 9 bits
+	`C' : 9 bits
+	`Bx' : 18 bits (`B' and `C' together)
+	`sBx' : signed Bx
+
+  A signed argument is represented in excess K; that is, the number
+  value is the unsigned value minus K. K is exactly the maximum value
+  for that argument (so that -max is represented by 0, and +max is
+  represented by 2*max), which is half the maximum for the corresponding
+  unsigned argument.
+===========================================================================*/
+
+
+enum OpMode {iABC, iABx, iAsBx};  /* basic instruction format */
+
+
+/*
+** size and position of opcode arguments.
+*/
+#define SIZE_C		9
+#define SIZE_B		9
+#define SIZE_Bx		(SIZE_C + SIZE_B)
+#define SIZE_A		8
+
+#define SIZE_OP		6
+
+#define POS_OP		0
+#define POS_A		(POS_OP + SIZE_OP)
+#define POS_C		(POS_A + SIZE_A)
+#define POS_B		(POS_C + SIZE_C)
+#define POS_Bx		POS_C
+
+
+/*
+** limits for opcode arguments.
+** we use (signed) int to manipulate most arguments,
+** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
+*/
+#if SIZE_Bx < LUAI_BITSINT-1
+#define MAXARG_Bx        ((1<<SIZE_Bx)-1)
+#define MAXARG_sBx        (MAXARG_Bx>>1)         /* `sBx' is signed */
+#else
+#define MAXARG_Bx        MAX_INT
+#define MAXARG_sBx        MAX_INT
+#endif
+
+
+#define MAXARG_A        ((1<<SIZE_A)-1)
+#define MAXARG_B        ((1<<SIZE_B)-1)
+#define MAXARG_C        ((1<<SIZE_C)-1)
+
+
+/* creates a mask with `n' 1 bits at position `p' */
+#define MASK1(n,p)	((~((~(Instruction)0)<<n))<<p)
+
+/* creates a mask with `n' 0 bits at position `p' */
+#define MASK0(n,p)	(~MASK1(n,p))
+
+/*
+** the following macros help to manipulate instructions
+*/
+
+#define GET_OPCODE(i)	(cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
+#define SET_OPCODE(i,o)	((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
+		((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
+
+#define GETARG_A(i)	(cast(int, ((i)>>POS_A) & MASK1(SIZE_A,0)))
+#define SETARG_A(i,u)	((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
+		((cast(Instruction, u)<<POS_A)&MASK1(SIZE_A,POS_A))))
+
+#define GETARG_B(i)	(cast(int, ((i)>>POS_B) & MASK1(SIZE_B,0)))
+#define SETARG_B(i,b)	((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
+		((cast(Instruction, b)<<POS_B)&MASK1(SIZE_B,POS_B))))
+
+#define GETARG_C(i)	(cast(int, ((i)>>POS_C) & MASK1(SIZE_C,0)))
+#define SETARG_C(i,b)	((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
+		((cast(Instruction, b)<<POS_C)&MASK1(SIZE_C,POS_C))))
+
+#define GETARG_Bx(i)	(cast(int, ((i)>>POS_Bx) & MASK1(SIZE_Bx,0)))
+#define SETARG_Bx(i,b)	((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
+		((cast(Instruction, b)<<POS_Bx)&MASK1(SIZE_Bx,POS_Bx))))
+
+#define GETARG_sBx(i)	(GETARG_Bx(i)-MAXARG_sBx)
+#define SETARG_sBx(i,b)	SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
+
+
+#define CREATE_ABC(o,a,b,c)	((cast(Instruction, o)<<POS_OP) \
+			| (cast(Instruction, a)<<POS_A) \
+			| (cast(Instruction, b)<<POS_B) \
+			| (cast(Instruction, c)<<POS_C))
+
+#define CREATE_ABx(o,a,bc)	((cast(Instruction, o)<<POS_OP) \
+			| (cast(Instruction, a)<<POS_A) \
+			| (cast(Instruction, bc)<<POS_Bx))
+
+
+/*
+** Macros to operate RK indices
+*/
+
+/* this bit 1 means constant (0 means register) */
+#define BITRK		(1 << (SIZE_B - 1))
+
+/* test whether value is a constant */
+#define ISK(x)		((x) & BITRK)
+
+/* gets the index of the constant */
+#define INDEXK(r)	((int)(r) & ~BITRK)
+
+#define MAXINDEXRK	(BITRK - 1)
+
+/* code a constant index as a RK value */
+#define RKASK(x)	((x) | BITRK)
+
+
+/*
+** invalid register that fits in 8 bits
+*/
+#define NO_REG		MAXARG_A
+
+
+/*
+** R(x) - register
+** Kst(x) - constant (in constant table)
+** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
+*/
+
+
+/*
+** grep "ORDER OP" if you change these enums
+*/
+
+typedef enum {
+/*----------------------------------------------------------------------
+name		args	description
+------------------------------------------------------------------------*/
+OP_MOVE,/*	A B	R(A) := R(B)					*/
+OP_LOADK,/*	A Bx	R(A) := Kst(Bx)					*/
+OP_LOADBOOL,/*	A B C	R(A) := (Bool)B; if (C) pc++			*/
+OP_LOADNIL,/*	A B	R(A) := ... := R(B) := nil			*/
+OP_GETUPVAL,/*	A B	R(A) := UpValue[B]				*/
+
+OP_GETGLOBAL,/*	A Bx	R(A) := Gbl[Kst(Bx)]				*/
+OP_GETTABLE,/*	A B C	R(A) := R(B)[RK(C)]				*/
+
+OP_SETGLOBAL,/*	A Bx	Gbl[Kst(Bx)] := R(A)				*/
+OP_SETUPVAL,/*	A B	UpValue[B] := R(A)				*/
+OP_SETTABLE,/*	A B C	R(A)[RK(B)] := RK(C)				*/
+
+OP_NEWTABLE,/*	A B C	R(A) := {} (size = B,C)				*/
+
+OP_SELF,/*	A B C	R(A+1) := R(B); R(A) := R(B)[RK(C)]		*/
+
+OP_ADD,/*	A B C	R(A) := RK(B) + RK(C)				*/
+OP_SUB,/*	A B C	R(A) := RK(B) - RK(C)				*/
+OP_MUL,/*	A B C	R(A) := RK(B) * RK(C)				*/
+OP_DIV,/*	A B C	R(A) := RK(B) / RK(C)				*/
+OP_MOD,/*	A B C	R(A) := RK(B) % RK(C)				*/
+OP_POW,/*	A B C	R(A) := RK(B) ^ RK(C)				*/
+OP_UNM,/*	A B	R(A) := -R(B)					*/
+OP_NOT,/*	A B	R(A) := not R(B)				*/
+OP_LEN,/*	A B	R(A) := length of R(B)				*/
+
+OP_CONCAT,/*	A B C	R(A) := R(B).. ... ..R(C)			*/
+
+OP_JMP,/*	sBx	pc+=sBx					*/
+
+OP_EQ,/*	A B C	if ((RK(B) == RK(C)) ~= A) then pc++		*/
+OP_LT,/*	A B C	if ((RK(B) <  RK(C)) ~= A) then pc++  		*/
+OP_LE,/*	A B C	if ((RK(B) <= RK(C)) ~= A) then pc++  		*/
+
+OP_TEST,/*	A C	if not (R(A) <=> C) then pc++			*/ 
+OP_TESTSET,/*	A B C	if (R(B) <=> C) then R(A) := R(B) else pc++	*/ 
+
+OP_CALL,/*	A B C	R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
+OP_TAILCALL,/*	A B C	return R(A)(R(A+1), ... ,R(A+B-1))		*/
+OP_RETURN,/*	A B	return R(A), ... ,R(A+B-2)	(see note)	*/
+
+OP_FORLOOP,/*	A sBx	R(A)+=R(A+2);
+			if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
+OP_FORPREP,/*	A sBx	R(A)-=R(A+2); pc+=sBx				*/
+
+OP_TFORLOOP,/*	A C	R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); 
+                        if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++	*/ 
+OP_SETLIST,/*	A B C	R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B	*/
+
+OP_CLOSE,/*	A 	close all variables in the stack up to (>=) R(A)*/
+OP_CLOSURE,/*	A Bx	R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))	*/
+
+OP_VARARG/*	A B	R(A), R(A+1), ..., R(A+B-1) = vararg		*/
+} OpCode;
+
+
+#define NUM_OPCODES	(cast(int, OP_VARARG) + 1)
+
+
+
+/*===========================================================================
+  Notes:
+  (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
+      and can be 0: OP_CALL then sets `top' to last_result+1, so
+      next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
+
+  (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
+      set top (like in OP_CALL with C == 0).
+
+  (*) In OP_RETURN, if (B == 0) then return up to `top'
+
+  (*) In OP_SETLIST, if (B == 0) then B = `top';
+      if (C == 0) then next `instruction' is real C
+
+  (*) For comparisons, A specifies what condition the test should accept
+      (true or false).
+
+  (*) All `skips' (pc++) assume that next instruction is a jump
+===========================================================================*/
+
+
+/*
+** masks for instruction properties. The format is:
+** bits 0-1: op mode
+** bits 2-3: C arg mode
+** bits 4-5: B arg mode
+** bit 6: instruction set register A
+** bit 7: operator is a test
+*/  
+
+enum OpArgMask {
+  OpArgN,  /* argument is not used */
+  OpArgU,  /* argument is used */
+  OpArgR,  /* argument is a register or a jump offset */
+  OpArgK   /* argument is a constant or register/constant */
+};
+
+LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
+
+#define getOpMode(m)	(cast(enum OpMode, luaP_opmodes[m] & 3))
+#define getBMode(m)	(cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
+#define getCMode(m)	(cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
+#define testAMode(m)	(luaP_opmodes[m] & (1 << 6))
+#define testTMode(m)	(luaP_opmodes[m] & (1 << 7))
+
+
+LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1];  /* opcode names */
+
+
+/* number of list items to accumulate before a SETLIST instruction */
+#define LFIELDS_PER_FLUSH	50
+
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/148a95ec/libs/elua/elua_base/src/loslib.c
----------------------------------------------------------------------
diff --git a/libs/elua/elua_base/src/loslib.c b/libs/elua/elua_base/src/loslib.c
new file mode 100644
index 0000000..1139cb6
--- /dev/null
+++ b/libs/elua/elua_base/src/loslib.c
@@ -0,0 +1,247 @@
+/*
+** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $
+** Standard Operating System library
+** See Copyright Notice in lua.h
+*/
+
+
+#include <errno.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#define loslib_c
+#define LUA_LIB
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+#include "lrotable.h"
+
+
+static int os_pushresult (lua_State *L, int i, const char *filename) {
+  int en = errno;  /* calls to Lua API may change this value */
+  if (i) {
+    lua_pushboolean(L, 1);
+    return 1;
+  }
+  else {
+    lua_pushnil(L);
+    lua_pushfstring(L, "%s: %s", filename, strerror(en));
+    lua_pushinteger(L, en);
+    return 3;
+  }
+}
+
+
+static int os_execute (lua_State *L) {
+  lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
+  return 1;
+}
+
+
+static int os_remove (lua_State *L) {
+  const char *filename = luaL_checkstring(L, 1);
+  return os_pushresult(L, remove(filename) == 0, filename);
+}
+
+
+static int os_rename (lua_State *L) {
+  const char *fromname = luaL_checkstring(L, 1);
+  const char *toname = luaL_checkstring(L, 2);
+  return os_pushresult(L, rename(fromname, toname) == 0, fromname);
+}
+
+
+static int os_tmpname (lua_State *L) {
+  char buff[LUA_TMPNAMBUFSIZE];
+  int err;
+  lua_tmpnam(buff, err);
+  if (err)
+    return luaL_error(L, "unable to generate a unique filename");
+  lua_pushstring(L, buff);
+  return 1;
+}
+
+
+static int os_getenv (lua_State *L) {
+  lua_pushstring(L, getenv(luaL_checkstring(L, 1)));  /* if NULL push nil */
+  return 1;
+}
+
+
+static int os_clock (lua_State *L) {
+  lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
+  return 1;
+}
+
+
+/*
+** {======================================================
+** Time/Date operations
+** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
+**   wday=%w+1, yday=%j, isdst=? }
+** =======================================================
+*/
+
+static void setfield (lua_State *L, const char *key, int value) {
+  lua_pushinteger(L, value);
+  lua_setfield(L, -2, key);
+}
+
+static void setboolfield (lua_State *L, const char *key, int value) {
+  if (value < 0)  /* undefined? */
+    return;  /* does not set field */
+  lua_pushboolean(L, value);
+  lua_setfield(L, -2, key);
+}
+
+static int getboolfield (lua_State *L, const char *key) {
+  int res;
+  lua_getfield(L, -1, key);
+  res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
+  lua_pop(L, 1);
+  return res;
+}
+
+
+static int getfield (lua_State *L, const char *key, int d) {
+  int res;
+  lua_getfield(L, -1, key);
+  if (lua_isnumber(L, -1))
+    res = (int)lua_tointeger(L, -1);
+  else {
+    if (d < 0)
+      return luaL_error(L, "field " LUA_QS " missing in date table", key);
+    res = d;
+  }
+  lua_pop(L, 1);
+  return res;
+}
+
+
+static int os_date (lua_State *L) {
+  const char *s = luaL_optstring(L, 1, "%c");
+  time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
+  struct tm *stm;
+  if (*s == '!') {  /* UTC? */
+    stm = gmtime(&t);
+    s++;  /* skip `!' */
+  }
+  else
+    stm = localtime(&t);
+  if (stm == NULL)  /* invalid date? */
+    lua_pushnil(L);
+  else if (strcmp(s, "*t") == 0) {
+    lua_createtable(L, 0, 9);  /* 9 = number of fields */
+    setfield(L, "sec", stm->tm_sec);
+    setfield(L, "min", stm->tm_min);
+    setfield(L, "hour", stm->tm_hour);
+    setfield(L, "day", stm->tm_mday);
+    setfield(L, "month", stm->tm_mon+1);
+    setfield(L, "year", stm->tm_year+1900);
+    setfield(L, "wday", stm->tm_wday+1);
+    setfield(L, "yday", stm->tm_yday+1);
+    setboolfield(L, "isdst", stm->tm_isdst);
+  }
+  else {
+    char cc[3];
+    luaL_Buffer b;
+    cc[0] = '%'; cc[2] = '\0';
+    luaL_buffinit(L, &b);
+    for (; *s; s++) {
+      if (*s != '%' || *(s + 1) == '\0')  /* no conversion specifier? */
+        luaL_addchar(&b, *s);
+      else {
+        size_t reslen;
+        char buff[200];  /* should be big enough for any conversion result */
+        cc[1] = *(++s);
+        reslen = strftime(buff, sizeof(buff), cc, stm);
+        luaL_addlstring(&b, buff, reslen);
+      }
+    }
+    luaL_pushresult(&b);
+  }
+  return 1;
+}
+
+
+static int os_time (lua_State *L) {
+  time_t t;
+  if (lua_isnoneornil(L, 1))  /* called without args? */
+    t = time(NULL);  /* get current time */
+  else {
+    struct tm ts;
+    luaL_checktype(L, 1, LUA_TTABLE);
+    lua_settop(L, 1);  /* make sure table is at the top */
+    ts.tm_sec = getfield(L, "sec", 0);
+    ts.tm_min = getfield(L, "min", 0);
+    ts.tm_hour = getfield(L, "hour", 12);
+    ts.tm_mday = getfield(L, "day", -1);
+    ts.tm_mon = getfield(L, "month", -1) - 1;
+    ts.tm_year = getfield(L, "year", -1) - 1900;
+    ts.tm_isdst = getboolfield(L, "isdst");
+    t = mktime(&ts);
+  }
+  if (t == (time_t)(-1))
+    lua_pushnil(L);
+  else
+    lua_pushnumber(L, (lua_Number)t);
+  return 1;
+}
+
+#if !defined LUA_NUMBER_INTEGRAL
+static int os_difftime (lua_State *L) {
+  lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
+                             (time_t)(luaL_optnumber(L, 2, 0))));
+  return 1;
+}
+#endif
+
+/* }====================================================== */
+
+
+static int os_setlocale (lua_State *L) {
+  static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
+                      LC_NUMERIC, LC_TIME};
+  static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
+     "numeric", "time", NULL};
+  const char *l = luaL_optstring(L, 1, NULL);
+  int op = luaL_checkoption(L, 2, "all", catnames);
+  lua_pushstring(L, setlocale(cat[op], l));
+  return 1;
+}
+
+
+static int os_exit (lua_State *L) {
+  exit(luaL_optint(L, 1, EXIT_SUCCESS));
+}
+
+#define MIN_OPT_LEVEL 1
+#include "lrodefs.h"
+const LUA_REG_TYPE syslib[] = {
+  {LSTRKEY("clock"),     LFUNCVAL(os_clock)},
+  {LSTRKEY("date"),      LFUNCVAL(os_date)},
+#if !defined LUA_NUMBER_INTEGRAL
+  {LSTRKEY("difftime"),  LFUNCVAL(os_difftime)},
+#endif
+  {LSTRKEY("execute"),   LFUNCVAL(os_execute)},
+  {LSTRKEY("exit"),      LFUNCVAL(os_exit)},
+  {LSTRKEY("getenv"),    LFUNCVAL(os_getenv)},
+  {LSTRKEY("remove"),    LFUNCVAL(os_remove)},
+  {LSTRKEY("rename"),    LFUNCVAL(os_rename)},
+  {LSTRKEY("setlocale"), LFUNCVAL(os_setlocale)},
+  {LSTRKEY("time"),      LFUNCVAL(os_time)},
+  {LSTRKEY("tmpname"),   LFUNCVAL(os_tmpname)},
+  {LNILKEY, LNILVAL}
+};
+
+/* }====================================================== */
+
+
+
+LUALIB_API int luaopen_os (lua_State *L) {
+  LREGISTER(L, LUA_OSLIBNAME, syslib);
+}