some improvements to type checking via XmiliaH

pull/216/head
Dibyendu Majumdar 3 years ago
parent 248c730c43
commit 5c30d255c7

@ -1568,8 +1568,9 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
static const char *aux_upvalue (StkId fi, int n, TValue **val,
CClosure **owner, UpVal **uv, ravitype_t *type) {
CClosure **owner, UpVal **uv, ravitype_t *type, TString **usertype) {
*type = RAVI_TANY;
*usertype = NULL;
switch (ttype(fi)) {
case LUA_TCCL: { /* C closure */
CClosure *f = clCvalue(fi);
@ -1587,6 +1588,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val,
if (uv) *uv = f->upvals[n - 1];
name = p->upvalues[n-1].name;
*type = p->upvalues[n - 1].ravi_type;
*usertype = p->upvalues[n - 1].usertype;
return (name == NULL) ? "(*no name)" : getstr(name);
}
default: return NULL; /* not a closure */
@ -1597,9 +1599,10 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val,
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
const char *name;
ravitype_t type;
TString *usertype;
TValue *val = NULL; /* to avoid warnings */
lua_lock(L);
name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL, &type);
name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL, &type, &usertype);
if (name) {
setobj2s(L, L->top, val);
api_incr_top(L);
@ -1616,30 +1619,22 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
UpVal *uv = NULL;
StkId fi;
ravitype_t type; /* RAVI upvalue type will be obtained if possible */
TString *usertype;
lua_lock(L);
fi = index2addr(L, funcindex);
api_checknelems(L, 1);
name = aux_upvalue(fi, n, &val, &owner, &uv, &type);
name = aux_upvalue(fi, n, &val, &owner, &uv, &type, &usertype);
if (name) {
/* RAVI extension
** We need to ensure that this function does
** not subvert the types of local variables
*/
if ( type == RAVI_TNUMFLT
|| type == RAVI_TNUMINT
|| type == RAVI_TARRAYFLT
|| type == RAVI_TARRAYINT) {
StkId input = L->top - 1;
int compatible =
(type == RAVI_TNUMFLT && ttisfloat(input))
|| (type == RAVI_TNUMINT && ttisinteger(input))
|| (type == RAVI_TARRAYFLT && ttisfarray(input))
|| (type == RAVI_TARRAYINT && ttisiarray(input))
|| (type == RAVI_TTABLE && ttisLtable(input))
;
if (!compatible)
name = NULL;
}
StkId input = L->top - 1;
int compatible = raviV_checktype(L, input, type, usertype);
if (!compatible)
name = NULL;
}
if (name) {
L->top--;

@ -147,16 +147,17 @@ static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
static const char *findlocal (lua_State *L, CallInfo *ci, int n,
StkId *pos, ravitype_t *type) {
StkId *pos, ravitype_t *type, TString** usertype) {
const char *name = NULL;
StkId base;
*type = RAVI_TANY;
*usertype = NULL;
if (isLua(ci)) {
if (n < 0) /* access to vararg values? */
return findvararg(ci, -n, pos);
else {
base = ci->u.l.base;
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci), type);
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci), type, usertype);
}
}
else
@ -176,17 +177,18 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n,
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
const char *name;
ravitype_t type;
TString *usertype;
lua_lock(L);
swapextra(L);
if (ar == NULL) { /* information about non-active function? */
if (!isLfunction(L->top - 1)) /* not a Lua function? */
name = NULL;
else /* consider live variables at function start (parameters) */
name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0, &type);
name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0, &type, &usertype);
}
else { /* active function; get information through 'ar' */
StkId pos = NULL; /* to avoid warnings */
name = findlocal(L, ar->i_ci, n, &pos, &type);
name = findlocal(L, ar->i_ci, n, &pos, &type, &usertype);
if (name) {
setobj2s(L, L->top, pos);
api_incr_top(L);
@ -202,24 +204,18 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
StkId pos = NULL; /* to avoid warnings */
const char *name;
ravitype_t type;
TString* usertype;
int compatible = 1;
lua_lock(L);
swapextra(L);
name = findlocal(L, ar->i_ci, n, &pos, &type);
name = findlocal(L, ar->i_ci, n, &pos, &type, &usertype);
if (name) {
/* RAVI extension
** We need to ensure that this function does
** not subvert the types of local variables
*/
if (type == RAVI_TNUMFLT || type == RAVI_TNUMINT || type == RAVI_TARRAYFLT || type == RAVI_TARRAYINT) {
StkId input = L->top - 1;
compatible = (type == RAVI_TNUMFLT && ttisfloat(input))
|| (type == RAVI_TNUMINT && ttisinteger(input))
|| (type == RAVI_TARRAYFLT && ttisfarray(input))
|| (type == RAVI_TARRAYINT && ttisiarray(input))
|| (type == RAVI_TTABLE && ttisLtable(input))
;
}
StkId input = L->top - 1;
int compatible = raviV_checktype(L, input, type, usertype);
if (compatible) {
setobjs2s(L, pos, L->top - 1);
L->top--; /* pop value */
@ -457,7 +453,8 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
const char **name) {
int pc;
ravitype_t type;
*name = luaF_getlocalname(p, reg + 1, lastpc, &type);
TString *usertype;
*name = luaF_getlocalname(p, reg + 1, lastpc, &type, &usertype);
if (*name) /* is a local? */
return "local";
/* else try symbolic execution */
@ -488,7 +485,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
int k = GETARG_C(i); /* key index */
int t = GETARG_B(i); /* table index */
const char *vn = (op != OP_GETTABUP && op != OP_RAVI_GETTABUP_SK) /* name of indexed variable */
? luaF_getlocalname(p, t + 1, pc, &type) /* t+1 is the local variable number */
? luaF_getlocalname(p, t + 1, pc, &type, &usertype) /* t+1 is the local variable number */
: upvalname(p, t);
kname(p, pc, k, name);
return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";

@ -243,7 +243,7 @@ void luaF_freeproto (lua_State *L, Proto *f) {
** Returns NULL if not found.
** RAVI extension - also return the known type if any
*/
const char *luaF_getlocalname (const Proto *f, int local_number, int pc, ravitype_t *type) {
const char *luaF_getlocalname (const Proto *f, int local_number, int pc, ravitype_t *type, TString **usertype) {
int i;
for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
if (pc < f->locvars[i].endpc) { /* is variable active? */
@ -252,11 +252,13 @@ const char *luaF_getlocalname (const Proto *f, int local_number, int pc, ravityp
if (f->locvars[i].varname == NULL)
break;
*type = f->locvars[i].ravi_type;
*usertype = f->locvars[i].usertype;
return getstr(f->locvars[i].varname);
}
}
}
*type = RAVI_TANY;
*usertype = NULL;
return NULL; /* not found */
}

@ -57,7 +57,7 @@ LUAI_FUNC void luaF_close (lua_State *L, StkId level);
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
/* The additional type argument is a Ravi extension */
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
int pc, ravitype_t* type);
int pc, ravitype_t* type, TString **usertype);
#endif

@ -645,10 +645,11 @@ static int listlocals (lua_State *L) {
int i = 0;
const char *name;
ravitype_t tt;
TString *usertype;
luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1),
1, "Lua function expected");
p = getproto(obj_at(L, 1));
while ((name = luaF_getlocalname(p, ++i, pc, &tt)) != NULL)
while ((name = luaF_getlocalname(p, ++i, pc, &tt, &usertype)) != NULL)
lua_pushstring(L, name);
return i-1;
}

@ -1204,6 +1204,33 @@ void luaV_finishOp (lua_State *L) {
if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \
Protect(luaV_finishset(L,t,k,v,slot)); }
int raviV_checktype(lua_State *L, TValue *input, ravitype_t type, TString *usertype) {
if (type == RAVI_TANY)
return 1;
if (type == RAVI_TNIL && ttisnil(input))
return 1;
if (type == RAVI_TBOOLEAN && ttisboolean(input))
return 1;
if (type == RAVI_TNUMINT && ttisinteger(input))
return 1;
if (type == RAVI_TNUMFLT && ttisfloat(input))
return 1;
if (type == RAVI_TARRAYINT && ttisiarray(input))
return 1;
if (type == RAVI_TARRAYFLT && ttisfarray(input))
return 1;
if (type == RAVI_TTABLE && ttisLtable(input))
return 1;
if (type == RAVI_TSTRING && ttisstring(input))
return 1;
if (type == RAVI_TFUNCTION && ttisclosure(input))
return 1;
if (type == RAVI_TUSERDATA) {
if (raviV_check_usertype(L, usertype, input))
return 1;
}
return 0;
}
int raviV_check_usertype(lua_State *L, TString *name, const TValue *o)
{

@ -172,6 +172,7 @@ LUAI_FUNC void raviV_settable_sskey(lua_State *L, const TValue *t, TValue *key,
LUAI_FUNC void raviV_gettable_i(lua_State *L, const TValue *t, TValue *key, StkId val);
LUAI_FUNC void raviV_settable_i(lua_State *L, const TValue *t, TValue *key, StkId val);
LUAI_FUNC void raviV_op_totype(lua_State *L, TValue *ra, TValue *rb);
LUAI_FUNC int raviV_checktype(lua_State *L, TValue *input, ravitype_t type, TString *usertype);
LUAI_FUNC int raviV_check_usertype(lua_State *L, TString *name, const TValue *o);
#ifdef RAVI_DEFER_STATEMENT
LUAI_FUNC void raviV_op_defer(lua_State *L, TValue *ra);

Loading…
Cancel
Save