issue #215 adapt fix by XmiliaH from pull request

pull/216/head
Dibyendu Majumdar 3 years ago
parent 8fd3a1bbab
commit 658f04c3d8

@ -1367,14 +1367,28 @@ 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,
TString **usertypes, int nvars, int n) {
static void ravi_typecheck(LexState *ls, expdesc *v, int *var_types, TString **usertypes, int nvars, int n) {
/* NOTE that 'v' may not have register assigned yet */
if (n >= nvars)
return;
ravitype_t vartype = var_types[n];
if (n < nvars && vartype != RAVI_TANY) {
if (v->ravi_type != vartype &&
(vartype == RAVI_TARRAYFLT || vartype == RAVI_TARRAYINT) &&
v->k == VNONRELOC) {
if (vartype == RAVI_TANY)
return;
ravitype_t v_type = v->ravi_type;
if (v->k == VINDEXED) {
if (v_type == RAVI_TARRAYINT) {
v_type = RAVI_TNUMINT;
}
else if (v_type == RAVI_TARRAYFLT) {
v_type = RAVI_TNUMFLT;
}
else {
v_type = RAVI_TANY;
}
}
if (v_type == vartype)
return;
if ((vartype == RAVI_TARRAYFLT || vartype == RAVI_TARRAYINT) && 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
* better approach. The location of the OP_NEWTABLE instruction is in
@ -1385,18 +1399,14 @@ static void ravi_typecheck(LexState *ls, expdesc *v, int *var_types,
// and about to assign to a
int ok = 0;
if (v->pc >= 0) {
Instruction *pc =
&ls->fs->f->code[v->pc]; /* Get the OP_NEWTABLE instruction */
Instruction *pc = &ls->fs->f->code[v->pc]; /* Get the OP_NEWTABLE instruction */
OpCode op = GET_OPCODE(*pc);
if (op == OP_NEWTABLE) { /* check before making changes */
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_RAVI_NEW_FARRAY;
if (reg == v->u.info) { /* double check that register is as expected */
op = (vartype == RAVI_TARRAYINT) ? OP_RAVI_NEW_IARRAY : OP_RAVI_NEW_FARRAY;
SET_OPCODE(*pc, op); /* modify opcode */
DEBUG_CODEGEN(
raviY_printf(ls->fs, "[%d]* %o ; modify opcode\n", v->pc, *pc));
DEBUG_CODEGEN(raviY_printf(ls->fs, "[%d]* %o ; modify opcode\n", v->pc, *pc));
ok = 1;
}
}
@ -1405,10 +1415,8 @@ 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 ||
else if ((vartype == RAVI_TNUMFLT || vartype == RAVI_TNUMINT || vartype == RAVI_TARRAYFLT ||
vartype == RAVI_TARRAYINT || vartype == RAVI_TTABLE || vartype == RAVI_TSTRING ||
vartype == RAVI_TFUNCTION || vartype == RAVI_TUSERDATA) &&
v->k == VCALL) {
/* For local variable declarations that call functions e.g.
@ -1418,8 +1426,7 @@ static void ravi_typecheck(LexState *ls, expdesc *v, int *var_types,
* necessary. So that means that we need to coerce the return values
* in situ.
*/
Instruction *pc =
&getinstruction(ls->fs, v); /* Obtain the instruction for OP_CALL */
Instruction *pc = &getinstruction(ls->fs, v); /* Obtain the instruction for OP_CALL */
lua_assert(GET_OPCODE(*pc) == OP_CALL);
int a = GETARG_A(*pc); /* function return values will be placed from
register pointed by A and upwards */
@ -1436,15 +1443,7 @@ 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) &&
v->k == VINDEXED) {
if ((vartype == RAVI_TNUMFLT && v->ravi_type != RAVI_TARRAYFLT) ||
(vartype == RAVI_TNUMINT && v->ravi_type != RAVI_TARRAYINT))
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_TSTRING || vartype == RAVI_TFUNCTION || vartype == RAVI_TUSERDATA) {
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
@ -1454,11 +1453,10 @@ static void ravi_typecheck(LexState *ls, expdesc *v, int *var_types,
luaK_exp2nextreg(ls->fs, v);
ravi_code_typecoersion(ls, v->u.info, vartype, usertype);
}
else if (vartype != v->ravi_type){
else {
luaX_syntaxerror(ls, "Invalid local assignment");
}
}
}
/* parse expression list, and validate that the expressions match expected
* types provided in vars array. This is a modified version of explist() to be

Loading…
Cancel
Save