Add some more changes and extensions from Lua 5.2.

Contributed by François Perrad.
This commit is contained in:
Mike Pall 2017-03-30 12:43:21 +02:00
parent dc320ca70f
commit de97b9d52b
5 changed files with 64 additions and 40 deletions

View File

@ -312,6 +312,20 @@ indexes for varargs.</li>
<li><tt>debug.getupvalue()</tt> and <tt>debug.setupvalue()</tt> handle <li><tt>debug.getupvalue()</tt> and <tt>debug.setupvalue()</tt> handle
C&nbsp;functions.</li> C&nbsp;functions.</li>
<li><tt>debug.upvalueid()</tt> and <tt>debug.upvaluejoin()</tt>.</li> <li><tt>debug.upvalueid()</tt> and <tt>debug.upvaluejoin()</tt>.</li>
<li>Lua/C API extensions:
<tt>lua_upvalueid()</tt>
<tt>lua_upvaluejoin()</tt>
<tt>lua_loadx()</tt>
<tt>luaL_fileresult()</tt>
<tt>luaL_execresult()</tt>
<tt>luaL_loadfilex()</tt>
<tt>luaL_loadbufferx()</tt>
<tt>luaL_traceback()</tt>
<tt>luaL_setfuncs()</tt>
<tt>luaL_pushmodule()</tt>
<tt>luaL_newlibtable()</tt>
<tt>luaL_newlib()</tt>
</li>
<li>Command line option <tt>-E</tt>.</li> <li>Command line option <tt>-E</tt>.</li>
<li>Command line checks <tt>__tostring</tt> for errors.</li> <li>Command line checks <tt>__tostring</tt> for errors.</li>
</ul> </ul>
@ -338,6 +352,7 @@ exit status.</li>
<li><tt>debug.getuservalue()</tt> and <tt>debug.setuservalue()</tt>.</li> <li><tt>debug.getuservalue()</tt> and <tt>debug.setuservalue()</tt>.</li>
<li>Remove <tt>math.mod()</tt>, <tt>string.gfind()</tt>.</li> <li>Remove <tt>math.mod()</tt>, <tt>string.gfind()</tt>.</li>
<li><tt>package.searchers</tt>.</li> <li><tt>package.searchers</tt>.</li>
<li><tt>module()</tt> returns the module table.</li>
</ul> </ul>
<p> <p>
Note: this provides only partial compatibility with Lua 5.2 at the Note: this provides only partial compatibility with Lua 5.2 at the

View File

@ -85,6 +85,9 @@ LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
const char *name, const char *mode); const char *name, const char *mode);
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg, LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
int level); int level);
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
int sizehint);
/* /*
@ -114,6 +117,11 @@ LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) #define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
/* From Lua 5.2. */
#define luaL_newlibtable(L, l) \
lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
#define luaL_newlib(L, l) (luaL_newlibtable(L, l), luaL_setfuncs(L, l, 0))
/* /*
** {====================================================== ** {======================================================
** Generic Buffer manipulation ** Generic Buffer manipulation

View File

@ -107,38 +107,36 @@ LUALIB_API const char *luaL_findtable(lua_State *L, int idx,
static int libsize(const luaL_Reg *l) static int libsize(const luaL_Reg *l)
{ {
int size = 0; int size = 0;
for (; l->name; l++) size++; for (; l && l->name; l++) size++;
return size; return size;
} }
LUALIB_API void luaL_pushmodule(lua_State *L, const char *modname, int sizehint)
{
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
lua_getfield(L, -1, modname);
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, sizehint) != NULL)
lj_err_callerv(L, LJ_ERR_BADMODN, modname);
lua_pushvalue(L, -1);
lua_setfield(L, -3, modname); /* _LOADED[modname] = new table. */
}
lua_remove(L, -2); /* Remove _LOADED table. */
}
LUALIB_API void luaL_openlib(lua_State *L, const char *libname, LUALIB_API void luaL_openlib(lua_State *L, const char *libname,
const luaL_Reg *l, int nup) const luaL_Reg *l, int nup)
{ {
lj_lib_checkfpu(L); lj_lib_checkfpu(L);
if (libname) { if (libname) {
int size = libsize(l); luaL_pushmodule(L, libname, libsize(l));
/* check whether lib already exists */ lua_insert(L, -(nup + 1)); /* Move module table below upvalues. */
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16);
lua_getfield(L, -1, libname); /* get _LOADED[libname] */
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, libname, size) != NULL)
lj_err_callerv(L, LJ_ERR_BADMODN, libname);
lua_pushvalue(L, -1);
lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
}
lua_remove(L, -2); /* remove _LOADED table */
lua_insert(L, -(nup+1)); /* move library table to below upvalues */
} }
for (; l->name; l++) { if (l)
int i; luaL_setfuncs(L, l, nup);
for (i = 0; i < nup; i++) /* copy upvalues to the top */ else
lua_pushvalue(L, -nup); lua_pop(L, nup); /* Remove upvalues. */
lua_pushcclosure(L, l->func, nup);
lua_setfield(L, -(nup+2), l->name);
}
lua_pop(L, nup); /* remove upvalues */
} }
LUALIB_API void luaL_register(lua_State *L, const char *libname, LUALIB_API void luaL_register(lua_State *L, const char *libname,
@ -147,6 +145,19 @@ LUALIB_API void luaL_register(lua_State *L, const char *libname,
luaL_openlib(L, libname, l, 0); luaL_openlib(L, libname, l, 0);
} }
LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup)
{
luaL_checkstack(L, nup, "too many upvalues");
for (; l->name; l++) {
int i;
for (i = 0; i < nup; i++) /* Copy upvalues to the top. */
lua_pushvalue(L, -nup);
lua_pushcclosure(L, l->func, nup);
lua_setfield(L, -(nup + 2), l->name);
}
lua_pop(L, nup); /* Remove upvalues. */
}
LUALIB_API const char *luaL_gsub(lua_State *L, const char *s, LUALIB_API const char *luaL_gsub(lua_State *L, const char *s,
const char *p, const char *r) const char *p, const char *r)
{ {

View File

@ -489,29 +489,19 @@ static void modinit(lua_State *L, const char *modname)
static int lj_cf_package_module(lua_State *L) static int lj_cf_package_module(lua_State *L)
{ {
const char *modname = luaL_checkstring(L, 1); const char *modname = luaL_checkstring(L, 1);
int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ int lastarg = (int)(L->top - L->base);
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); luaL_pushmodule(L, modname, 1);
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)
lj_err_callerv(L, LJ_ERR_BADMODN, 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"); lua_getfield(L, -1, "_NAME");
if (!lua_isnil(L, -1)) { /* is table an initialized module? */ if (!lua_isnil(L, -1)) { /* Module already initialized? */
lua_pop(L, 1); lua_pop(L, 1);
} else { /* no; initialize it */ } else {
lua_pop(L, 1); lua_pop(L, 1);
modinit(L, modname); modinit(L, modname);
} }
lua_pushvalue(L, -1); lua_pushvalue(L, -1);
setfenv(L); setfenv(L);
dooptions(L, loaded - 1); dooptions(L, lastarg);
return 0; return LJ_52;
} }
static int lj_cf_package_seeall(lua_State *L) static int lj_cf_package_seeall(lua_State *L)

View File

@ -79,7 +79,7 @@
#define LUA_IGMARK "-" #define LUA_IGMARK "-"
#define LUA_PATH_CONFIG \ #define LUA_PATH_CONFIG \
LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" \ LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" \
LUA_EXECDIR "\n" LUA_IGMARK LUA_EXECDIR "\n" LUA_IGMARK "\n"
/* Quoting in error messages. */ /* Quoting in error messages. */
#define LUA_QL(x) "'" x "'" #define LUA_QL(x) "'" x "'"