From 7789f4f32db19c326cf8d5f2e0e0e991cb1681b2 Mon Sep 17 00:00:00 2001 From: XmiliaH Date: Fri, 19 Feb 2021 16:39:29 +0100 Subject: [PATCH] Finish type maps --- src/lapi.c | 38 ++++----- src/lcode.c | 94 +++++++++++++-------- src/ldebug.c | 21 ++--- src/ldump.c | 20 ++++- src/lfunc.c | 6 +- src/lfunc.h | 2 +- src/lobject.c | 16 ++++ src/lobject.h | 46 +++++----- src/lparser.c | 144 ++++++++++++++------------------ src/lparser.h | 6 +- src/ltable.c | 18 ++-- src/ltable.h | 2 +- src/ltests.c | 2 +- src/lundump.c | 21 ++++- src/lvm.c | 8 +- tests/language/ravi_tests1.ravi | 2 +- 16 files changed, 237 insertions(+), 209 deletions(-) diff --git a/src/lapi.c b/src/lapi.c index 9eac09a..e3b5027 100644 --- a/src/lapi.c +++ b/src/lapi.c @@ -1568,8 +1568,8 @@ 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) { - *type = RAVI_TANY; + CClosure **owner, UpVal **uv, ravi_type_map *type) { + *type = RAVI_TM_ANY; switch (ttype(fi)) { case LUA_TCCL: { /* C closure */ CClosure *f = clCvalue(fi); @@ -1586,7 +1586,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val, *val = f->upvals[n-1]->v; if (uv) *uv = f->upvals[n - 1]; name = p->upvalues[n-1].name; - *type = p->upvalues[n - 1].ravi_type; + *type = p->upvalues[n - 1].ravi_type_map; return (name == NULL) ? "(*no name)" : getstr(name); } default: return NULL; /* not a closure */ @@ -1596,7 +1596,7 @@ 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; + ravi_type_map type; TValue *val = NULL; /* to avoid warnings */ lua_lock(L); name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL, &type); @@ -1608,14 +1608,13 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { return name; } - LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { const char *name; TValue *val = NULL; /* to avoid warnings */ CClosure *owner = NULL; UpVal *uv = NULL; StkId fi; - ravitype_t type; /* RAVI upvalue type will be obtained if possible */ + ravi_type_map type; /* RAVI upvalue type will be obtained if possible */ lua_lock(L); fi = index2addr(L, funcindex); api_checknelems(L, 1); @@ -1625,21 +1624,12 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { ** 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 = ravi_checktype(input, type); + + if (!compatible) + name = NULL; } if (name) { L->top--; @@ -1652,13 +1642,13 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { } -static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf, ravitype_t *type) { +static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf, ravi_type_map *type) { LClosure *f; StkId fi = index2addr(L, fidx); api_check(L, ttisLclosure(fi), "Lua function expected"); f = clLvalue(fi); api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); - if (type) *type = f->p->upvalues[n - 1].ravi_type; + if (type) *type = f->p->upvalues[n - 1].ravi_type_map; if (pf) *pf = f; return &f->upvals[n - 1]; /* get its upvalue pointer */ } @@ -1686,7 +1676,7 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, int fidx2, int n2) { LClosure *f1; - ravitype_t t1, t2; + ravi_type_map t1, t2; UpVal **up1 = getupvalref(L, fidx1, n1, &f1, &t1); UpVal **up2 = getupvalref(L, fidx2, n2, NULL, &t2); if (t1 == t2 && *up1 != *up2) { diff --git a/src/lcode.c b/src/lcode.c index 93438cd..f7d02a5 100644 --- a/src/lcode.c +++ b/src/lcode.c @@ -621,7 +621,7 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { else op = OP_GETTABUP; /* 't' is in an upvalue */ } - uint32_t result_type = 0; + ravi_type_map result_type = 0; if (e->ravi_type_map & (~(RAVI_TM_INTEGER_ARRAY | RAVI_TM_FLOAT_ARRAY))) { result_type = RAVI_TM_ANY; } else { @@ -683,28 +683,28 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { TString *usertype = NULL; int ravi_type = raviY_get_register_typeinfo(fs, reg, &usertype); switch (ravi_type) { - case RAVI_TNUMINT: + case RAVI_TM_INTEGER: luaK_codeABC(fs, OP_RAVI_MOVEI, reg, e->u.info, 0); break; - case RAVI_TNUMFLT: + case RAVI_TM_FLOAT: luaK_codeABC(fs, OP_RAVI_MOVEF, reg, e->u.info, 0); break; - case RAVI_TARRAYINT: + case RAVI_TM_INTEGER_ARRAY: luaK_codeABC(fs, OP_RAVI_MOVEIARRAY, reg, e->u.info, 0); break; - case RAVI_TARRAYFLT: + case RAVI_TM_FLOAT_ARRAY: luaK_codeABC(fs, OP_RAVI_MOVEFARRAY, reg, e->u.info, 0); break; - case RAVI_TTABLE: + case RAVI_TM_TABLE: luaK_codeABC(fs, OP_RAVI_MOVETAB, reg, e->u.info, 0); break; default: luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); - if (ravi_type == RAVI_TSTRING) + if (ravi_type == (RAVI_TM_STRING | RAVI_TM_NIL)) luaK_codeABC(fs, OP_RAVI_TOSTRING, reg, 0, 0); - else if (ravi_type == RAVI_TFUNCTION) + else if (ravi_type == (RAVI_TM_FUNCTION | RAVI_TM_NIL)) luaK_codeABC(fs, OP_RAVI_TOCLOSURE, reg, 0, 0); - else if (ravi_type == RAVI_TUSERDATA && usertype) + else if (ravi_type == (RAVI_TM_USERDATA | RAVI_TM_NIL) && usertype) luaK_codeABx(fs, OP_RAVI_TOTYPE, reg, luaK_stringK(fs, usertype)); break; } @@ -862,7 +862,6 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) { } static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) { - lua_assert(var->ravi_type_map == RAVI_TM_ANY || (var->ravi_type_map != 0 && (var->ravi_type_map & (var->ravi_type_map - 1)) == 0)); /* VNONRELOC means we have fixed register and do we know the type? */ if (ex->k == VNONRELOC && (var->ravi_type_map == RAVI_TM_FLOAT || @@ -876,8 +875,18 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) { /* handled by MOVEI, MOVEF, MOVEIARRAY, MOVEFARRAY at runtime */ return; } + ravi_type_map ex_ravi_type_map = ex->ravi_type_map; + if (ex->k == VINDEXED) { + if (ex_ravi_type_map == RAVI_TM_INTEGER_ARRAY) { + ex_ravi_type_map = RAVI_TM_INTEGER; + } else if (ex_ravi_type_map == RAVI_TM_FLOAT_ARRAY) { + ex_ravi_type_map = RAVI_TM_FLOAT; + } else { + ex_ravi_type_map = RAVI_TM_ANY; + } + } if (var->ravi_type_map == RAVI_TM_FLOAT) { - if (ex->ravi_type_map == RAVI_TM_FLOAT) + if (ex_ravi_type_map == RAVI_TM_FLOAT) return; luaX_syntaxerror( fs->ls, @@ -886,7 +895,7 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) { "Invalid assignment: number expected")); } else if (var->ravi_type_map == RAVI_TM_INTEGER) { - if (ex->ravi_type_map == RAVI_TM_INTEGER) + if (ex_ravi_type_map == RAVI_TM_INTEGER) return; luaX_syntaxerror( fs->ls, @@ -894,8 +903,8 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) { fs->ls->L, "Invalid assignment: integer expected")); } - else if (var->ravi_type_map & (~(RAVI_TM_INTEGER_ARRAY | RAVI_TM_FLOAT_ARRAY | RAVI_TM_TABLE)) == 0) { - if (ex->ravi_type_map == var->ravi_type_map) + else if ((var->ravi_type_map & (~(RAVI_TM_INTEGER_ARRAY | RAVI_TM_FLOAT_ARRAY | RAVI_TM_TABLE))) == 0) { + if (ex_ravi_type_map == var->ravi_type_map) return; luaX_syntaxerror( fs->ls, @@ -905,7 +914,7 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) { var->ravi_type_map == RAVI_TM_TABLE ? "table" : (var->ravi_type_map == RAVI_TM_FLOAT_ARRAY ? "number[]" : "integer[]"))); } else if (var->ravi_type_map == (RAVI_TM_STRING | RAVI_TM_NIL)) { - if ((ex->ravi_type_map & ~(RAVI_TM_STRING | RAVI_TM_NIL)) == 0) + if ((ex_ravi_type_map & ~(RAVI_TM_STRING | RAVI_TM_NIL)) == 0) return; luaX_syntaxerror( fs->ls, @@ -914,7 +923,7 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) { "Invalid assignment: string expected")); } else if (var->ravi_type_map == (RAVI_TM_FUNCTION | RAVI_TM_NIL)) { - if ((ex->ravi_type_map & ~(RAVI_TM_FUNCTION | RAVI_TM_NIL)) == 0) + if ((ex_ravi_type_map & ~(RAVI_TM_FUNCTION | RAVI_TM_NIL)) == 0) return; luaX_syntaxerror( fs->ls, @@ -923,8 +932,8 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) { "Invalid assignment: function expected")); } else if (var->ravi_type_map == (RAVI_TM_USERDATA | RAVI_TM_NIL)) { - if ((ex->ravi_type_map & ~(RAVI_TM_USERDATA | RAVI_TM_NIL)) == 0 && - (!(ex->ravi_type_map & RAVI_TM_USERDATA) || (var->usertype && var->usertype == ex->usertype))) + if ((ex_ravi_type_map & ~(RAVI_TM_USERDATA | RAVI_TM_NIL)) == 0 && + (!(ex_ravi_type_map & RAVI_TM_USERDATA) || (var->usertype && var->usertype == ex->usertype))) return; luaX_syntaxerror( fs->ls, @@ -936,12 +945,11 @@ static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) { static OpCode check_valid_setupval(FuncState *fs, expdesc *var, expdesc *ex, int reg) { - lua_assert(var->ravi_type_map == RAVI_TM_ANY || (var->ravi_type_map != 0 && (var->ravi_type_map & (var->ravi_type_map - 1)) == 0)); OpCode op = OP_SETUPVAL; if ((var->ravi_type_map == RAVI_TM_INTEGER || var->ravi_type_map == RAVI_TM_FLOAT || var->ravi_type_map == RAVI_TM_INTEGER_ARRAY || var->ravi_type_map == RAVI_TM_FLOAT_ARRAY || - var->ravi_type_map == RAVI_TM_TABLE || var->ravi_type_map == RAVI_TM_STRING | RAVI_TM_NIL || - var->ravi_type_map == RAVI_TM_FUNCTION | RAVI_TM_NIL || var->ravi_type_map == RAVI_TM_USERDATA | RAVI_TM_NIL) && + var->ravi_type_map == RAVI_TM_TABLE || var->ravi_type_map == (RAVI_TM_STRING | RAVI_TM_NIL) || + var->ravi_type_map == (RAVI_TM_FUNCTION | RAVI_TM_NIL) || var->ravi_type_map == (RAVI_TM_USERDATA | RAVI_TM_NIL)) && ex->ravi_type_map & ~var->ravi_type_map) { if (var->ravi_type_map == RAVI_TM_INTEGER) op = OP_RAVI_SETUPVALI; @@ -953,21 +961,27 @@ static OpCode check_valid_setupval(FuncState *fs, expdesc *var, expdesc *ex, op = OP_RAVI_SETUPVAL_FARRAY; else if (var->ravi_type_map == RAVI_TM_TABLE) op = OP_RAVI_SETUPVALT; - else if (var->ravi_type_map == RAVI_TM_STRING | RAVI_TM_NIL) + else if (var->ravi_type_map == (RAVI_TM_STRING | RAVI_TM_NIL)) luaK_codeABC(fs, OP_RAVI_TOSTRING, reg, 0, 0); - else if (var->ravi_type_map == RAVI_TM_FUNCTION | RAVI_TM_NIL) + else if (var->ravi_type_map == (RAVI_TM_FUNCTION | RAVI_TM_NIL)) luaK_codeABC(fs, OP_RAVI_TOCLOSURE, reg, 0, 0); - else if (var->ravi_type_map == RAVI_TM_USERDATA | RAVI_TM_NIL) { + else if (var->ravi_type_map == (RAVI_TM_USERDATA | RAVI_TM_NIL)) { TString *usertype = fs->f->upvalues[var->u.info].usertype; luaK_codeABx(fs, OP_RAVI_TOTYPE, reg, luaK_stringK(fs, usertype)); } - else + else { + char var_type_map_str[RAVI_TYPEMAP_MAX_LEN]; + char ex_type_map_str[RAVI_TYPEMAP_MAX_LEN]; + raviY_typemap_string(var->ravi_type_map, var_type_map_str); + raviY_typemap_string(ex->ravi_type_map, ex_type_map_str); + luaX_syntaxerror(fs->ls, luaO_pushfstring(fs->ls->L, "Invalid assignment of " "upvalue: upvalue type " "%s, expression type %s", - raviY_typename(var->ravi_type), - raviY_typename(ex->ravi_type))); + var_type_map_str, + ex_type_map_str)); + } } return op; } @@ -976,9 +990,9 @@ static OpCode check_valid_setupval(FuncState *fs, expdesc *var, expdesc *ex, void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { switch (var->k) { case VLOCAL: { + check_valid_store(fs, var, ex); freeexp(fs, ex); exp2reg(fs, ex, var->u.info); /* compute 'ex' into proper place */ - check_valid_store(fs, var, ex); return; } case VUPVAL: { @@ -1535,17 +1549,17 @@ static void code_type_assertion(FuncState *fs, UnOpr op, expdesc *e, TString *us opcode = OP_RAVI_TOTAB; tm = RAVI_TM_TABLE; } - else if (op == OPR_TO_STRING && e->ravi_type_map != RAVI_TM_STRING) { + else if (op == OPR_TO_STRING && (e->ravi_type_map & (~(RAVI_TM_STRING | RAVI_TM_NIL))) != 0) { opcode = OP_RAVI_TOSTRING; - tm = RAVI_TM_STRING; + tm = RAVI_TM_STRING | RAVI_TM_NIL; } - else if (op == OPR_TO_CLOSURE && e->ravi_type_map != RAVI_TM_FUNCTION) { + else if (op == OPR_TO_CLOSURE && (e->ravi_type_map & (~(RAVI_TM_FUNCTION | RAVI_TM_NIL))) != 0) { opcode = OP_RAVI_TOCLOSURE; - tm = RAVI_TM_FUNCTION; + tm = RAVI_TM_FUNCTION | RAVI_TM_NIL; } else if (op == OPR_TO_TYPE) { - opcode = OP_RAVI_TOTYPE; - tm = RAVI_TM_USERDATA; + opcode = OP_RAVI_TOTYPE; + tm = RAVI_TM_USERDATA | RAVI_TM_NIL; } else { /* nothing to do*/ @@ -1646,7 +1660,11 @@ void luaK_posfix (FuncState *fs, BinOpr op, lua_assert(e1->t == NO_JUMP); /* list closed by 'luK_infix' */ luaK_dischargevars(fs, e2); luaK_concat(fs, &e2->f, e1->f); - e2->ravi_type_map |= e1->ravi_type_map & RAVI_TM_FALSISH; + if (e1->ravi_type_map & RAVI_TM_TRUISH) { + e2->ravi_type_map |= e1->ravi_type_map & RAVI_TM_FALSISH; + } else { + e2->ravi_type_map = e1->ravi_type_map & RAVI_TM_FALSISH; + } *e1 = *e2; break; } @@ -1658,7 +1676,11 @@ void luaK_posfix (FuncState *fs, BinOpr op, if (e1->usertype != e2->usertype) e2->usertype = NULL; } - e2->ravi_type_map |= e1->ravi_type_map & RAVI_TM_TRUISH; + if (e1->ravi_type_map & RAVI_TM_FALSISH) { + e2->ravi_type_map |= e1->ravi_type_map & RAVI_TM_TRUISH; + } else { + e2->ravi_type_map = e1->ravi_type_map & RAVI_TM_TRUISH; + } *e1 = *e2; break; } diff --git a/src/ldebug.c b/src/ldebug.c index 13ba22b..6408a1f 100644 --- a/src/ldebug.c +++ b/src/ldebug.c @@ -147,10 +147,10 @@ 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, ravi_type_map *type) { const char *name = NULL; StkId base; - *type = RAVI_TANY; + *type = RAVI_TM_ANY; if (isLua(ci)) { if (n < 0) /* access to vararg values? */ return findvararg(ci, -n, pos); @@ -175,7 +175,7 @@ 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; + ravi_type_map type; lua_lock(L); swapextra(L); if (ar == NULL) { /* information about non-active function? */ @@ -201,7 +201,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { 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; + ravi_type_map type; int compatible = 1; lua_lock(L); swapextra(L); @@ -211,15 +211,8 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { ** 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 = ravi_checktype(input, type); if (compatible) { setobjs2s(L, pos, L->top - 1); L->top--; /* pop value */ @@ -456,7 +449,7 @@ static int findsetreg (Proto *p, int lastpc, int reg) { static const char *getobjname (Proto *p, int lastpc, int reg, const char **name) { int pc; - ravitype_t type; + ravi_type_map type; *name = luaF_getlocalname(p, reg + 1, lastpc, &type); if (*name) /* is a local? */ return "local"; diff --git a/src/ldump.c b/src/ldump.c index 32aa8ce..f6a57de 100644 --- a/src/ldump.c +++ b/src/ldump.c @@ -150,6 +150,22 @@ static void DumpUpvalues (const Proto *f, DumpState *D) { } } +static lu_byte ravi_type_map_to_old_type(ravi_type_map type_map) { + switch (type_map) { + case RAVI_TM_ANY: return 0; + case RAVI_TM_INTEGER: return 1; + case RAVI_TM_FLOAT: return 2; + case RAVI_TM_INTEGER_ARRAY: return 3; + case RAVI_TM_FLOAT_ARRAY: return 4; + case RAVI_TM_FUNCTION | RAVI_TM_NIL: return 5; + case RAVI_TM_TABLE: return 6; + case RAVI_TM_STRING | RAVI_TM_NIL: return 7; + case RAVI_TM_NIL: return 8; + case RAVI_TM_BOOLEAN | RAVI_TM_NIL: return 9; + case RAVI_TM_USERDATA | RAVI_TM_NIL: return 10; + default: return 0; + } +} static void DumpDebug (const Proto *f, DumpState *D) { int i, n; @@ -163,7 +179,7 @@ static void DumpDebug (const Proto *f, DumpState *D) { DumpString((D->strip) ? NULL : f->locvars[i].varname, D); DumpInt(f->locvars[i].startpc, D); DumpInt(f->locvars[i].endpc, D); - DumpByte(f->locvars[i].ravi_type, D); + DumpByte(ravi_type_map_to_old_type(f->locvars[i].ravi_type_map), D); DumpString(f->locvars[i].usertype, D); } /* n = (D->strip) ? 0 : f->sizeupvalues; */ @@ -171,7 +187,7 @@ static void DumpDebug (const Proto *f, DumpState *D) { DumpInt(n, D); for (i = 0; i < n; i++) { DumpString((D->strip) ? NULL : f->upvalues[i].name, D); - DumpByte(f->upvalues[i].ravi_type, D); + DumpByte(ravi_type_map_to_old_type(f->upvalues[i].ravi_type_map), D); DumpString(f->upvalues[i].usertype, D); } } diff --git a/src/lfunc.c b/src/lfunc.c index 09db3d9..e4bc138 100644 --- a/src/lfunc.c +++ b/src/lfunc.c @@ -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, ravi_type_map *type) { int i; for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { if (pc < f->locvars[i].endpc) { /* is variable active? */ @@ -251,12 +251,12 @@ const char *luaF_getlocalname (const Proto *f, int local_number, int pc, ravityp if (local_number == 0) { if (f->locvars[i].varname == NULL) break; - *type = f->locvars[i].ravi_type; + *type = f->locvars[i].ravi_type_map; return getstr(f->locvars[i].varname); } } } - *type = RAVI_TANY; + *type = RAVI_TM_ANY; return NULL; /* not found */ } diff --git a/src/lfunc.h b/src/lfunc.h index 21f1aa2..a945b0a 100644 --- a/src/lfunc.h +++ b/src/lfunc.h @@ -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, ravi_type_map* type); #endif diff --git a/src/lobject.c b/src/lobject.c index 24a20a1..b8bf65b 100644 --- a/src/lobject.c +++ b/src/lobject.c @@ -33,6 +33,22 @@ LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT}; +int ravi_checktype(StkId input, ravi_type_map type) { + if (type == RAVI_TM_ANY) return 1; + if (type & RAVI_TM_NIL && ttisnil(input)) return 1; + if (type & RAVI_TM_FALSE && ttisboolean(input) && l_isfalse(input)) return 1; + if (type & RAVI_TM_TRUE && ttisboolean(input) && !l_isfalse(input)) return 1; + if (type & RAVI_TM_INTEGER && ttisinteger(input)) return 1; + if (type & RAVI_TM_FLOAT && ttisfloat(input)) return 1; + if (type & RAVI_TM_INTEGER_ARRAY && ttisiarray(input)) return 1; + if (type & RAVI_TM_FLOAT_ARRAY && ttisfarray(input)) return 1; + if (type & RAVI_TM_TABLE && ttisLtable(input)) return 1; + if (type & RAVI_TM_STRING && ttisstring(input)) return 1; + if (type & RAVI_TM_FUNCTION && ttisclosure(input)) return 1; + // TODO if (type & RAVI_TM_USERDATA && ) + return 0; +} + /* ** converts an integer to a "floating point byte", represented as ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if diff --git a/src/lobject.h b/src/lobject.h index ad5f12b..028d3d0 100644 --- a/src/lobject.h +++ b/src/lobject.h @@ -54,19 +54,6 @@ typedef uint16_t LuaType; ** we care about from a performance point of view - if any ** other types appear then they are all treated as ANY **/ -typedef enum { - RAVI_TANY = 0, /* Lua dynamic type */ - RAVI_TNUMINT = 1, /* integer number */ - RAVI_TNUMFLT, /* floating point number */ - RAVI_TARRAYINT, /* array of ints */ - RAVI_TARRAYFLT, /* array of doubles */ - RAVI_TFUNCTION, /* Lua or C Function */ - RAVI_TTABLE, /* Lua table */ - RAVI_TSTRING, /* string */ - RAVI_TNIL, /* NIL */ - RAVI_TBOOLEAN, /* boolean */ - RAVI_TUSERDATA /* userdata or lightuserdata */ -} ravitype_t; typedef enum { RAVI_TI_NIL, @@ -83,18 +70,20 @@ typedef enum { RAVI_TI_OTHER } ravi_type_index; -#define RAVI_TM_NIL (1<ravi_type_map, type_map_str); switch (e->k) { @@ -187,10 +161,14 @@ static void v(FILE *fp, FuncState *fs, const expdesc *e) { type_map_str); break; case VNONRELOC: + { + char var_type_map_str[RAVI_TYPEMAP_MAX_LEN]; + raviY_typemap_string(raviY_get_register_typeinfo(fs, e->u.info, NULL), var_type_map_str); fprintf(fp, "{p=%p, k=VNONRELOC, register=%d %s, type=%s, pc=%d}", e, e->u.info, - raviY_typename(raviY_get_register_typeinfo(fs, e->u.info, NULL)), + var_type_map_str, type_map_str, e->pc); + } break; case VLOCAL: fprintf(fp, "{p=%p, k=VLOCAL, register=%d, type=%s}", e, e->u.info, @@ -221,11 +199,15 @@ static void v(FILE *fp, FuncState *fs, const expdesc *e) { e->pc); break; case VCALL: + { + char var_type_map_str[RAVI_TYPEMAP_MAX_LEN]; + raviY_typemap_string(raviY_get_register_typeinfo(fs, GETARG_A(getinstruction(fs, e)), NULL), var_type_map_str); fprintf( fp, "{p=%p, k=VCALL, pc=%d, instruction=(%s %s), type=%s}", e, e->u.info, raviP_instruction_to_str(buf, sizeof buf, getinstruction(fs, e)), - raviY_typename(raviY_get_register_typeinfo(fs, GETARG_A(getinstruction(fs, e)), NULL)), + var_type_map_str, type_map_str); + } break; case VVARARG: fprintf(fp, "{p=%p, k=VVARARG, pc=%d, instruction=(%s), type=%s}", e, @@ -280,9 +262,11 @@ void raviY_printf(FuncState *fs, const char *format, ...) { printf("%f", d); cp++; } else if (cp[0] == '%' && cp[1] == 't') { - ravitype_t i; - i = va_arg(ap, ravitype_t); - fputs(raviY_typename(i), stdout); + ravi_type_map i; + char type_map_str[RAVI_TYPEMAP_MAX_LEN]; + i = va_arg(ap, ravi_type_map); + raviY_typemap_string(i, type_map_str); + fputs(type_map_str, stdout); cp++; } else { fputc(*cp, stdout); @@ -410,7 +394,7 @@ static void checkname (LexState *ls, expdesc *e) { * variable's index in ls->f->locvars. * RAVI change - added the type of the variable. */ -static int registerlocalvar (LexState *ls, TString *varname, uint32_t ravi_type_map, TString *usertype) { +static int registerlocalvar (LexState *ls, TString *varname, ravi_type_map ravi_type_map, TString *usertype) { FuncState *fs = ls->fs; Proto *f = fs->f; int oldsize = f->sizelocvars; @@ -433,7 +417,7 @@ static int registerlocalvar (LexState *ls, TString *varname, uint32_t ravi_type_ /* create a new local variable in function scope, and set the * variable type (RAVI - added type tt) */ -static void new_localvar (LexState *ls, TString *name, uint32_t tm, TString *usertype) { +static void new_localvar (LexState *ls, TString *name, ravi_type_map tm, TString *usertype) { FuncState *fs = ls->fs; Dyndata *dyd = ls->dyd; /* register variable and get its index */ @@ -491,7 +475,7 @@ static int register_to_locvar_index(FuncState *fs, int reg) { * return the type associated with the variable. * This is a RAVI function */ -uint32_t raviY_get_register_typeinfo(FuncState *fs, int reg, TString **pusertype) { +ravi_type_map raviY_get_register_typeinfo(FuncState *fs, int reg, TString **pusertype) { int idx; LocVar *v; /* Due to the way Lua parser works it is not safe to look beyond nactvar */ @@ -603,7 +587,7 @@ static void singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { if (v >= 0) { /* found? */ /* RAVI set type of local var / expr if possible */ TString *usertype = NULL; - uint32_t tt = raviY_get_register_typeinfo(fs, v, &usertype); + ravi_type_map tt = raviY_get_register_typeinfo(fs, v, &usertype); init_exp(var, VLOCAL, v, tt, usertype); /* variable is local, RAVI set type */ if (!base) markupval(fs, v); /* local will be used as an upval */ @@ -641,7 +625,7 @@ static void singlevar (LexState *ls, expdesc *var) { /* RAVI code an instruction to coerce the type, reg is the register, and ravi_type is the type we want */ -static void ravi_code_typecoersion(LexState *ls, int reg, uint32_t ravi_type_map, TString *typename /* only if tt is USERDATA */) { +static void ravi_code_typecoersion(LexState *ls, int reg, ravi_type_map ravi_type_map, TString *typename /* only if tt is USERDATA */) { /* do we need to convert ? */ if (ravi_type_map == RAVI_TM_FLOAT || ravi_type_map == RAVI_TM_INTEGER) /* code an instruction to convert in place */ @@ -661,7 +645,7 @@ static void ravi_code_typecoersion(LexState *ls, int reg, uint32_t ravi_type_map else if (ravi_type_map == (RAVI_TM_STRING | RAVI_TM_NIL)) luaK_codeABC(ls->fs, OP_RAVI_TOSTRING, reg, 0, 0); - else if (ravi_type_map == RAVI_TM_FUNCTION | RAVI_TM_NIL) + else if (ravi_type_map == (RAVI_TM_FUNCTION | RAVI_TM_NIL)) luaK_codeABC(ls->fs, OP_RAVI_TOCLOSURE, reg, 0, 0); // TODO coerse to boolean @@ -671,19 +655,17 @@ static void ravi_code_typecoersion(LexState *ls, int reg, uint32_t ravi_type_map For array and table types however raise an error as uninitialized value would cause a null pointer and therefore memory fault */ -static void ravi_code_setzero(FuncState *fs, int reg, ravitype_t ravi_type, TString *usertype) { +static void ravi_code_setzero(FuncState *fs, int reg, ravi_type_map ravi_type, TString *usertype) { (void) usertype; if (ravi_type == RAVI_TM_FLOAT || ravi_type == RAVI_TM_INTEGER) /* code an instruction to convert in place */ luaK_codeABC(fs, ravi_type == RAVI_TM_FLOAT ? OP_RAVI_LOADFZ : OP_RAVI_LOADIZ, reg, 0, 0); - else if (~(ravi_type & RAVI_TM_NIL)) - luaX_syntaxerror(fs->ls, "uninitialized number[] in local variable"); // TODO - else if (ravi_type == RAVI_TM_FLOAT_ARRAY) - luaX_syntaxerror(fs->ls, "uninitialized number[] in local variable"); - else if (ravi_type == RAVI_TM_INTEGER_ARRAY) - luaX_syntaxerror(fs->ls, "uninitialized integer[] in local variable"); - else if (ravi_type == RAVI_TM_TABLE) - luaX_syntaxerror(fs->ls, "uninitialized table in local variable"); + else if ((ravi_type & RAVI_TM_NIL) == 0) { + char type_map_str[RAVI_TYPEMAP_MAX_LEN]; + raviY_typemap_string(ravi_type, type_map_str); + + luaX_syntaxerror(fs->ls, luaO_pushfstring(fs->ls->L, "uninitialized %s in local variable", type_map_str)); + } } @@ -713,7 +695,7 @@ static void ravi_coercetype(LexState *ls, expdesc *v, int n) * first convert from local register to variable index. */ int idx = register_to_locvar_index(ls->fs, i); - uint32_t ravi_type_map = ls->fs->f->locvars[idx].ravi_type_map; /* get variable's type */ + ravi_type_map ravi_type_map = ls->fs->f->locvars[idx].ravi_type_map; /* get variable's type */ TString *usertype = ls->fs->f->locvars[idx].usertype; /* do we need to convert ? */ ravi_code_typecoersion(ls, i, ravi_type_map, usertype); @@ -730,7 +712,7 @@ static void ravi_setzero(FuncState *fs, int from, int n) { * first convert from local register to variable index. */ int idx = register_to_locvar_index(fs, i); - uint32_t ravi_type_map = fs->f->locvars[idx].ravi_type_map; /* get variable's type */ + ravi_type_map ravi_type_map = fs->f->locvars[idx].ravi_type_map; /* get variable's type */ TString *usertype = fs->f->locvars[idx].usertype; /* do we need to convert ? */ ravi_code_setzero(fs, i, ravi_type_map, usertype); @@ -1279,11 +1261,11 @@ static TString *user_defined_type_name(LexState *ls, TString *typename) { * where type is 'integer', 'integer[]', * 'number', 'number[]' */ -static ravitype_t declare_localvar(LexState *ls, TString **pusertype) { +static ravi_type_map declare_localvar(LexState *ls, TString **pusertype) { /* RAVI change - add type */ TString *name = str_checkname(ls); /* assume a dynamic type */ - ravitype_t tm = RAVI_TM_ANY; + ravi_type_map tm = RAVI_TM_ANY; /* if the variable name is followed by a colon then we have a type * specifier */ @@ -1333,7 +1315,7 @@ static void parlist (LexState *ls) { Proto *f = fs->f; int nparams = 0; enum { N = MAXVARS + 10 }; - int vars[N] = { 0 }; + ravi_type_map vars[N] = { 0 }; TString *typenames[N] = { NULL }; f->is_vararg = 0; if (ls->t.token != ')') { /* is 'parlist' not empty? */ @@ -1359,12 +1341,12 @@ static void parlist (LexState *ls) { luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ for (int i = 0; i < f->numparams; i++) { TString *usertype = NULL; - ravitype_t tt = raviY_get_register_typeinfo(fs, i, &usertype); - lua_assert((i < nparams && vars[i] == (int)tt) || 1); + ravi_type_map tm = raviY_get_register_typeinfo(fs, i, &usertype); + lua_assert((i < nparams && vars[i] == tm) || 1); lua_assert((i < nparams && usertype == typenames[i]) || 1); DEBUG_VARS(raviY_printf(fs, "Parameter [%d] = %v\n", i + 1, getlocvar(fs, i))); /* do we need to convert ? */ - ravi_code_typecoersion(ls, i, tt, usertype); + ravi_code_typecoersion(ls, i, tm, usertype); } } @@ -1433,13 +1415,12 @@ static int explist (LexState *ls, expdesc *v) { * 'v' may be a function call returning multiple values, in which case * we need to check all returned values against the expected types. */ -static void ravi_typecheck(LexState *ls, expdesc *v, int *var_types, +static void ravi_typecheck(LexState *ls, expdesc *v, ravi_type_map *var_types, TString **usertypes, int nvars, int n) { /* NOTE that 'v' may not have register assigned yet */ - ravitype_t vartype = var_types[n]; - if (n < nvars && vartype != RAVI_TANY && v->ravi_type != vartype) { - if (v->ravi_type != vartype && - (vartype == RAVI_TARRAYFLT || vartype == RAVI_TARRAYINT) && + ravi_type_map vartype = var_types[n]; + if (n < nvars && (v->ravi_type_map & ~vartype)) { + if ((vartype == RAVI_TM_FLOAT_ARRAY || vartype == RAVI_TM_INTEGER_ARRAY) && v->k == VNONRELOC) { /* as the bytecode for generating a table is already emitted by this stage * we have to amend the generated byte code - not sure if there is a @@ -1458,7 +1439,7 @@ static void ravi_typecheck(LexState *ls, expdesc *v, int *var_types, int reg = GETARG_A(*pc); if (reg == v->u.info) { /* double check that register is as expected */ - op = (vartype == RAVI_TARRAYINT) ? OP_RAVI_NEW_IARRAY + op = (vartype == RAVI_TM_INTEGER_ARRAY) ? OP_RAVI_NEW_IARRAY : OP_RAVI_NEW_FARRAY; SET_OPCODE(*pc, op); /* modify opcode */ DEBUG_CODEGEN( @@ -1471,11 +1452,10 @@ static void ravi_typecheck(LexState *ls, expdesc *v, int *var_types, luaX_syntaxerror(ls, "expecting array initializer"); } /* if we are calling a function then convert return types */ - else if (v->ravi_type != vartype && - (vartype == RAVI_TNUMFLT || vartype == RAVI_TNUMINT || - vartype == RAVI_TARRAYFLT || vartype == RAVI_TARRAYINT || - vartype == RAVI_TTABLE || vartype == RAVI_TSTRING || - vartype == RAVI_TFUNCTION || vartype == RAVI_TUSERDATA) && + else if ((vartype == RAVI_TM_FLOAT || vartype == RAVI_TM_INTEGER || + vartype == RAVI_TM_FLOAT_ARRAY || vartype == RAVI_TM_INTEGER_ARRAY || + vartype == RAVI_TM_TABLE || vartype == (RAVI_TM_STRING | RAVI_TM_NIL) || + vartype == (RAVI_TM_FUNCTION | RAVI_TM_NIL) || vartype == (RAVI_TM_USERDATA | RAVI_TM_NIL)) && v->k == VCALL) { /* For local variable declarations that call functions e.g. * local i = func() @@ -1502,15 +1482,15 @@ static void ravi_typecheck(LexState *ls, expdesc *v, int *var_types, /* do we need to convert ? */ ravi_code_typecoersion(ls, a + (i - n), var_types[i], NULL); } - else if ((vartype == RAVI_TNUMFLT || vartype == RAVI_TNUMINT) && + else if ((vartype == RAVI_TM_FLOAT || vartype == RAVI_TM_INTEGER) && v->k == VINDEXED) { - if ((vartype == RAVI_TNUMFLT && v->ravi_type != RAVI_TARRAYFLT) || - (vartype == RAVI_TNUMINT && v->ravi_type != RAVI_TARRAYINT)) + if ((vartype == RAVI_TM_FLOAT && v->ravi_type_map != RAVI_TM_FLOAT_ARRAY) || + (vartype == RAVI_TM_INTEGER && v->ravi_type_map != RAVI_TM_INTEGER_ARRAY)) luaX_syntaxerror(ls, "Invalid local assignment"); } - else if ((vartype == RAVI_TSTRING && v->ravi_type != RAVI_TSTRING) || - (vartype == RAVI_TFUNCTION && v->ravi_type != RAVI_TFUNCTION) || - vartype == RAVI_TUSERDATA) { + else if ((vartype == (RAVI_TM_STRING | RAVI_TM_NIL) && v->ravi_type_map != RAVI_TM_STRING) || + (vartype == (RAVI_TM_FUNCTION | RAVI_TM_NIL) && v->ravi_type_map != RAVI_TM_FUNCTION) || + vartype == (RAVI_TM_USERDATA | RAVI_TM_NIL)) { // TODO this is wrong since nil is ignored TString *usertype = usertypes[n]; // NULL if var_types[n] is not userdata /* we need to make sure that a register is assigned to 'v' so that we can emit type assertion instructions. This would have @@ -1530,7 +1510,7 @@ static void ravi_typecheck(LexState *ls, expdesc *v, int *var_types, * types provided in vars array. This is a modified version of explist() to be * used to local variable declaration statement only. */ -static int localvar_explist(LexState *ls, expdesc *v, int *vars, TString** usertypes, int nvars) { +static int localvar_explist(LexState *ls, expdesc *v, ravi_type_map *vars, TString** usertypes, int nvars) { /* explist -> expr { ',' expr } */ int n = 1; /* at least one expression */ expr(ls, v); @@ -2323,7 +2303,7 @@ static void localstat (LexState *ls) { * instead. */ enum { N = MAXVARS + 10 }; - int vars[N] = { 0 }; + ravi_type_map vars[N] = { 0 }; TString *usertypes[N] = { NULL }; do { /* RAVI changes start */ diff --git a/src/lparser.h b/src/lparser.h index 018b367..6737962 100644 --- a/src/lparser.h +++ b/src/lparser.h @@ -243,7 +243,9 @@ LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, Dyndata *dyd, const char *name, int firstchar); /** RAVI extensions **/ -LUAI_FUNC const char *raviY_typename(ravitype_t tt); +#define RAVI_TYPEMAP_MAX_LEN (sizeof("nil|boolean|integer|number|integer[]|number[]|table|string|function|userdata|?|")) + +LUAI_FUNC void raviY_typemap_string(uint32_t tm, char* buf); /* Special printf that recognises following conversions: * %e - expdesc * @@ -261,7 +263,7 @@ LUAI_FUNC void raviY_printf(FuncState *fs, const char *format, ...); * Else RAVI_TANY is returned. Note that this function only looks * at active local variables - see note on FuncState on what this means. */ -LUAI_FUNC ravitype_t raviY_get_register_typeinfo(FuncState *fs, int reg, TString **); +LUAI_FUNC ravi_type_map raviY_get_register_typeinfo(FuncState *fs, int reg, TString **); #define DEBUG_EXPR(p) \ if ((ravi_parser_debug & 1) != 0) { \ diff --git a/src/ltable.c b/src/ltable.c index 4bdd5fd..4fe8f7b 100644 --- a/src/ltable.c +++ b/src/ltable.c @@ -503,19 +503,19 @@ Table *luaH_new (lua_State *L) { return t; } -RaviArray *raviH_new(lua_State *L, ravitype_t tt, int is_slice) { - lua_assert(tt == RAVI_TARRAYFLT || tt == RAVI_TARRAYINT); - GCObject *o = luaC_newobj(L, tt == RAVI_TARRAYFLT ? RAVI_TFARRAY : RAVI_TIARRAY, sizeof(RaviArray)); +RaviArray *raviH_new(lua_State *L, ravi_type_map tm, int is_slice) { + lua_assert(tm == RAVI_TM_FLOAT_ARRAY || tm == RAVI_TM_INTEGER_ARRAY); + GCObject *o = luaC_newobj(L, tm == RAVI_TM_FLOAT_ARRAY ? RAVI_TFARRAY : RAVI_TIARRAY, sizeof(RaviArray)); RaviArray *t = gco2array(o); t->len = 0; t->size = RAVI_ARRAY_MAX_INLINE; /* Initially we use inline storage */ - t->flags = (tt == RAVI_TARRAYFLT) ? RAVI_ARRAY_ISFLOAT : 0; - t->data = (tt == RAVI_TARRAYFLT) ? (char *) &t->numarray : (char *) &t->intarray; /* data */ + t->flags = (tm == RAVI_TM_FLOAT_ARRAY) ? RAVI_ARRAY_ISFLOAT : 0; + t->data = (tm == RAVI_TM_FLOAT_ARRAY) ? (char *) &t->numarray : (char *) &t->intarray; /* data */ t->parent = NULL; t->metatable = NULL; if (!is_slice) { /* Note following will set len to 1 */ - if (tt == RAVI_TARRAYFLT) { + if (tm == RAVI_TM_FLOAT_ARRAY) { raviH_set_float_inline(L, t, 0, 0.0); } else { @@ -904,7 +904,7 @@ void raviH_set_float(lua_State *L, RaviArray *t, lua_Unsigned u1, lua_Number val RaviArray *raviH_new_integer_array(lua_State *L, unsigned int len, lua_Integer init_value) { - RaviArray *t = raviH_new(L, RAVI_TARRAYINT, 0); + RaviArray *t = raviH_new(L, RAVI_TM_INTEGER_ARRAY, 0); unsigned int new_len = len + 1; // Ravi arrays have an extra slot at offset 0 if (new_len < len) { // Wrapped? luaG_runerror(L, "array length out of range"); @@ -924,7 +924,7 @@ RaviArray *raviH_new_integer_array(lua_State *L, unsigned int len, RaviArray *raviH_new_number_array(lua_State *L, unsigned int len, lua_Number init_value) { - RaviArray *t = raviH_new(L, RAVI_TARRAYFLT, 0); + RaviArray *t = raviH_new(L, RAVI_TM_FLOAT_ARRAY, 0); unsigned int new_len = len + 1; // Ravi arrays have an extra slot at offset 0 if (new_len < len) { // Wrapped? luaG_runerror(L, "array length out of range"); @@ -975,7 +975,7 @@ RaviArray *raviH_new_slice(lua_State *L, TValue *parent, unsigned int start, luaG_runerror( L, "cannot create slice from dynamic integer[] or number[] array"); /* Create the slice table */ - RaviArray *t = raviH_new(L, (orig->flags & RAVI_ARRAY_ISFLOAT) ? RAVI_TARRAYFLT : RAVI_TARRAYINT, 1); + RaviArray *t = raviH_new(L, (orig->flags & RAVI_ARRAY_ISFLOAT) ? RAVI_TM_FLOAT_ARRAY : RAVI_TM_INTEGER_ARRAY, 1); /* Add a reference to the parent table. From GC perspective the slice is a white object so we do not need a write barrier */ t->parent = orig; diff --git a/src/ltable.h b/src/ltable.h index 5f90d38..d5a91cf 100644 --- a/src/ltable.h +++ b/src/ltable.h @@ -124,7 +124,7 @@ LUAI_FUNC lua_Unsigned luaH_getn (Table *t); /* Creates a specialized version of Lua Table to support Ravi's * integer[] and number[] arrays. */ -LUAI_FUNC RaviArray *raviH_new(lua_State *L, ravitype_t array_type, int is_slice); +LUAI_FUNC RaviArray *raviH_new(lua_State *L, ravi_type_map array_type, int is_slice); LUAI_FUNC void raviH_free(lua_State* L, RaviArray* t); LUAI_FUNC int raviH_next(lua_State* L, RaviArray* t, StkId key); diff --git a/src/ltests.c b/src/ltests.c index 174855e..b01e8d1 100644 --- a/src/ltests.c +++ b/src/ltests.c @@ -644,7 +644,7 @@ static int listlocals (lua_State *L) { int pc = cast_int(luaL_checkinteger(L, 2)) - 1; int i = 0; const char *name; - ravitype_t tt; + ravi_type_map tt; luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, "Lua function expected"); p = getproto(obj_at(L, 1)); diff --git a/src/lundump.c b/src/lundump.c index 69509cb..0f9f068 100644 --- a/src/lundump.c +++ b/src/lundump.c @@ -183,6 +183,23 @@ static void LoadUpvalues (LoadState *S, Proto *f) { } } +static ravi_type_map ravi_old_type_to_type_map(lu_byte old) { + switch (old) { + case 0: return RAVI_TM_ANY; + case 1: return RAVI_TM_INTEGER; + case 2: return RAVI_TM_FLOAT; + case 3: return RAVI_TM_INTEGER_ARRAY; + case 4: return RAVI_TM_FLOAT_ARRAY; + case 5: return RAVI_TM_FUNCTION | RAVI_TM_NIL; + case 6: return RAVI_TM_TABLE; + case 7: return RAVI_TM_STRING | RAVI_TM_NIL; + case 8: return RAVI_TM_NIL; + case 9: return RAVI_TM_BOOLEAN | RAVI_TM_NIL; + case 10: return RAVI_TM_USERDATA | RAVI_TM_NIL; + default: return RAVI_TM_ANY; + } +} + static void LoadDebug (LoadState *S, Proto *f) { int i, n; @@ -201,13 +218,13 @@ static void LoadDebug (LoadState *S, Proto *f) { f->locvars[i].varname = LoadString(S); f->locvars[i].startpc = LoadInt(S); f->locvars[i].endpc = LoadInt(S); - f->locvars[i].ravi_type = LoadByte(S); + f->locvars[i].ravi_type_map = ravi_old_type_to_type_map(LoadByte(S)); f->locvars[i].usertype = LoadString(S); } n = LoadInt(S); for (i = 0; i < n; i++) { f->upvalues[i].name = LoadString(S); - f->upvalues[i].ravi_type = LoadByte(S); + f->upvalues[i].ravi_type_map = ravi_old_type_to_type_map(LoadByte(S)); f->upvalues[i].usertype = LoadString(S); } } diff --git a/src/lvm.c b/src/lvm.c index 80e9894..eb96425 100644 --- a/src/lvm.c +++ b/src/lvm.c @@ -2188,7 +2188,7 @@ int luaV_execute (lua_State *L) { vmcase(OP_RAVI_NEW_IARRAY) { RaviArray *t; savepc(L); /* in case of allocation errors */ - t = raviH_new(L, RAVI_TARRAYINT, 0); + t = raviH_new(L, RAVI_TM_INTEGER_ARRAY, 0); setiarrayvalue(L, ra, t); checkGC(L, ra + 1); vmbreak; @@ -2196,7 +2196,7 @@ int luaV_execute (lua_State *L) { vmcase(OP_RAVI_NEW_FARRAY) { RaviArray *t; savepc(L); /* in case of allocation errors */ - t = raviH_new(L, RAVI_TARRAYFLT, 0); + t = raviH_new(L, RAVI_TM_FLOAT_ARRAY, 0); setfarrayvalue(L, ra, t); checkGC(L, ra + 1); vmbreak; @@ -2768,13 +2768,13 @@ void raviV_debug_trace(lua_State *L, int opCode, int pc) { } void raviV_op_newarrayint(lua_State *L, CallInfo *ci, TValue *ra) { - RaviArray *t = raviH_new(L, RAVI_TARRAYINT, 0); + RaviArray *t = raviH_new(L, RAVI_TM_INTEGER_ARRAY, 0); setiarrayvalue(L, ra, t); checkGC_(L, ra + 1); } void raviV_op_newarrayfloat(lua_State *L, CallInfo *ci, TValue *ra) { - RaviArray *t = raviH_new(L, RAVI_TARRAYFLT, 0); + RaviArray *t = raviH_new(L, RAVI_TM_FLOAT_ARRAY, 0); setfarrayvalue(L, ra, t); checkGC_(L, ra + 1); } diff --git a/tests/language/ravi_tests1.ravi b/tests/language/ravi_tests1.ravi index 22f1e0e..3c9fc8b 100644 --- a/tests/language/ravi_tests1.ravi +++ b/tests/language/ravi_tests1.ravi @@ -1523,7 +1523,7 @@ print 'Test 58 OK' function x(s1: string, s2: string) return @string( s1 .. s2 ) end -check(x, 'TOSTRING', 'TOSTRING', 'MOVE', 'MOVE', 'CONCAT', 'RETURN', 'RETURN') +check(x, 'TOSTRING', 'TOSTRING', 'MOVE', 'MOVE', 'CONCAT', 'TOSTRING', 'RETURN', 'RETURN') assert(x('a', 'b') == 'ab') compile(x) assert(x('a', 'b') == 'ab')