add MUL, SUB and DIV type specific op codes

Dibyendu Majumdar 9 years ago
parent cf2638a431
commit c4a646ba1e

@ -30,7 +30,12 @@ typedef enum {
VUPVAL, /* info = index of upvalue in 'upvalues' */
VINDEXED, /* t = table register/upvalue; idx = index R/K */
VJMP, /* info = instruction pc */
VRELOCABLE, /* info = instruction pc */
VRELOCABLE, /* info = instruction pc;
op code may be OP_CLOSURE,OP_NEWTABLE,OP_CONCAT,OP_GETUPVAL,
OP_GETTABUP,OP_GETTABLE,OP_NOT,Code for binary and unary expressions
that produce values (arithmetic operations, bitwise operations,
concat, length)
*/
VCALL, /* info = instruction pc */
VVARARG /* info = instruction pc */
} expkind;
@ -122,7 +127,7 @@ LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
LUAI_FUNC int ravi_parser_debug;
LUAI_FUNC void print_expdesc(FILE *fp, const char *desc, const expdesc *e);
LUAI_FUNC void ravi_printf(FuncState *fs, const char *format, ...);
LUAI_FUNC int getlocvartype(FuncState *fs, int reg);
#endif

@ -472,6 +472,7 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
}
case VNONRELOC: {
if (reg != e->u.info) {
/* code a MOVEI or MOVEF if the target register is a local typed variable */
int ravi_type = getlocvartype(fs, reg);
switch (ravi_type) {
case LUA_TNUMINT:
@ -602,6 +603,7 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
static void check_valid_store(FuncState *fs, expdesc *var, expdesc *ex) {
#if RAVI_ENABLED
/* VNONRELOC means we have fixed register and do we know the type? */
if (ex->k == VNONRELOC && (var->ravi_type == LUA_TNUMFLT || var->ravi_type == LUA_TNUMINT)) {
/* handled by MOVEI or MOVEF at runtime */
return;
@ -922,6 +924,177 @@ static void codeexpval (FuncState *fs, OpCode op,
e1->u.info = luaK_codeABC(fs, OP_RAVI_ADDIIRR, 0, o1, o2); /* generate opcode */
}
}
else if (op == OP_SUB && e1->ravi_type == LUA_TNUMFLT && e2->ravi_type == LUA_TNUMFLT) {
if (ISK(o1) && ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBFFKK, 0, o1, o2); /* generate opcode */
}
else if (ISK(o1)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBFFKR, 0, o1, o2); /* generate opcode */
}
else if (ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBFFRK, 0, o1, o2); /* generate opcode */
}
else {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBFFRR, 0, o1, o2); /* generate opcode */
}
}
else if (op == OP_SUB && e1->ravi_type == LUA_TNUMFLT && e2->ravi_type == LUA_TNUMINT) {
if (ISK(o1) && ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBFIKK, 0, o1, o2); /* generate opcode */
}
else if (ISK(o1)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBFIKR, 0, o1, o2); /* generate opcode */
}
else if (ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBFIRK, 0, o1, o2); /* generate opcode */
}
else {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBFIRR, 0, o1, o2); /* generate opcode */
}
}
else if (op == OP_SUB && e1->ravi_type == LUA_TNUMINT && e2->ravi_type == LUA_TNUMFLT) {
if (ISK(o1) && ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBIFKK, 0, o1, o2); /* generate opcode */
}
else if (ISK(o1)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBIFKR, 0, o1, o2); /* generate opcode */
}
else if (ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBIFRK, 0, o1, o2); /* generate opcode */
}
else {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBIFRR, 0, o1, o2); /* generate opcode */
}
}
else if (op == OP_SUB && e1->ravi_type == LUA_TNUMINT && e2->ravi_type == LUA_TNUMINT) {
if (ISK(o1) && ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBIIKK, 0, o1, o2); /* generate opcode */
}
else if (ISK(o1)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBIIKR, 0, o1, o2); /* generate opcode */
}
else if (ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBIIRK, 0, o1, o2); /* generate opcode */
}
else {
e1->u.info = luaK_codeABC(fs, OP_RAVI_SUBIIRR, 0, o1, o2); /* generate opcode */
}
}
else if (op == OP_MUL && e1->ravi_type == LUA_TNUMFLT && e2->ravi_type == LUA_TNUMFLT) {
if (ISK(o1) && ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULFFKK, 0, o1, o2); /* generate opcode */
}
else if (ISK(o1)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULFFKR, 0, o1, o2); /* generate opcode */
}
else if (ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULFFRK, 0, o1, o2); /* generate opcode */
}
else {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULFFRR, 0, o1, o2); /* generate opcode */
}
}
else if (op == OP_MUL && e1->ravi_type == LUA_TNUMFLT && e2->ravi_type == LUA_TNUMINT) {
if (ISK(o1) && ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULFIKK, 0, o1, o2); /* generate opcode */
}
else if (ISK(o1)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULFIKR, 0, o1, o2); /* generate opcode */
}
else if (ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULFIRK, 0, o1, o2); /* generate opcode */
}
else {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULFIRR, 0, o1, o2); /* generate opcode */
}
}
else if (op == OP_MUL && e1->ravi_type == LUA_TNUMINT && e2->ravi_type == LUA_TNUMFLT) {
if (ISK(o1) && ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULIFKK, 0, o1, o2); /* generate opcode */
}
else if (ISK(o1)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULIFKR, 0, o1, o2); /* generate opcode */
}
else if (ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULIFRK, 0, o1, o2); /* generate opcode */
}
else {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULIFRR, 0, o1, o2); /* generate opcode */
}
}
else if (op == OP_MUL && e1->ravi_type == LUA_TNUMINT && e2->ravi_type == LUA_TNUMINT) {
if (ISK(o1) && ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULIIKK, 0, o1, o2); /* generate opcode */
}
else if (ISK(o1)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULIIKR, 0, o1, o2); /* generate opcode */
}
else if (ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULIIRK, 0, o1, o2); /* generate opcode */
}
else {
e1->u.info = luaK_codeABC(fs, OP_RAVI_MULIIRR, 0, o1, o2); /* generate opcode */
}
}
else if (op == OP_DIV && e1->ravi_type == LUA_TNUMFLT && e2->ravi_type == LUA_TNUMFLT) {
if (ISK(o1) && ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVFFKK, 0, o1, o2); /* generate opcode */
}
else if (ISK(o1)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVFFKR, 0, o1, o2); /* generate opcode */
}
else if (ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVFFRK, 0, o1, o2); /* generate opcode */
}
else {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVFFRR, 0, o1, o2); /* generate opcode */
}
}
else if (op == OP_DIV && e1->ravi_type == LUA_TNUMFLT && e2->ravi_type == LUA_TNUMINT) {
if (ISK(o1) && ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVFIKK, 0, o1, o2); /* generate opcode */
}
else if (ISK(o1)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVFIKR, 0, o1, o2); /* generate opcode */
}
else if (ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVFIRK, 0, o1, o2); /* generate opcode */
}
else {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVFIRR, 0, o1, o2); /* generate opcode */
}
}
else if (op == OP_DIV && e1->ravi_type == LUA_TNUMINT && e2->ravi_type == LUA_TNUMFLT) {
if (ISK(o1) && ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVIFKK, 0, o1, o2); /* generate opcode */
}
else if (ISK(o1)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVIFKR, 0, o1, o2); /* generate opcode */
}
else if (ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVIFRK, 0, o1, o2); /* generate opcode */
}
else {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVIFRR, 0, o1, o2); /* generate opcode */
}
}
else if (op == OP_DIV && e1->ravi_type == LUA_TNUMINT && e2->ravi_type == LUA_TNUMINT) {
if (ISK(o1) && ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVIIKK, 0, o1, o2); /* generate opcode */
}
else if (ISK(o1)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVIIKR, 0, o1, o2); /* generate opcode */
}
else if (ISK(o2)) {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVIIRK, 0, o1, o2); /* generate opcode */
}
else {
e1->u.info = luaK_codeABC(fs, OP_RAVI_DIVIIRR, 0, o1, o2); /* generate opcode */
}
}
else {
#endif
e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); /* generate opcode */
@ -930,13 +1103,13 @@ static void codeexpval (FuncState *fs, OpCode op,
#endif
e1->k = VRELOCABLE; /* all those operations are relocable */
if (isbinary) {
if (op == OP_ADD && e1->ravi_type == LUA_TNUMFLT && e2->ravi_type == LUA_TNUMFLT)
if ((op == OP_ADD||op == OP_SUB || op == OP_MUL || op == OP_DIV) && e1->ravi_type == LUA_TNUMFLT && e2->ravi_type == LUA_TNUMFLT)
e1->ravi_type = LUA_TNUMFLT;
else if (op == OP_ADD && e1->ravi_type == LUA_TNUMFLT && e2->ravi_type == LUA_TNUMINT)
else if ((op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV) && e1->ravi_type == LUA_TNUMFLT && e2->ravi_type == LUA_TNUMINT)
e1->ravi_type = LUA_TNUMFLT;
else if (op == OP_ADD && e1->ravi_type == LUA_TNUMINT && e2->ravi_type == LUA_TNUMFLT)
else if ((op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV) && e1->ravi_type == LUA_TNUMINT && e2->ravi_type == LUA_TNUMFLT)
e1->ravi_type = LUA_TNUMFLT;
else if (op == OP_ADD && e1->ravi_type == LUA_TNUMINT && e2->ravi_type == LUA_TNUMINT)
else if ((op == OP_ADD || op == OP_SUB || op == OP_MUL || op == OP_DIV) && e1->ravi_type == LUA_TNUMINT && e2->ravi_type == LUA_TNUMINT)
e1->ravi_type = LUA_TNUMINT;
else
e1->ravi_type = LUA_TNONE;

@ -571,14 +571,14 @@ static const char* PrintRaviCode(char *buf, size_t n, Instruction i) {
int a = GETARG_A(i);
int b = GETARG_B(i);
int c = GETARG_C(i);
snprintf(buf, n, "%-9s\t", luaP_opnames[o]);
snprintf(buf, n, "%s ", luaP_opnames[o]);
switch (getOpMode(o)) {
case iABC:
snprintf(buf + strlen(buf), n - strlen(buf), "%d", a);
snprintf(buf + strlen(buf), n - strlen(buf), "A=%d", a);
if (getBMode(o) != OpArgN)
snprintf(buf + strlen(buf), n - strlen(buf), " %d", getBMode(o) == OpArgK ? (MYK(INDEXK(b))) : b);
snprintf(buf + strlen(buf), n - strlen(buf), " B=%d", getBMode(o) == OpArgK ? (MYK(INDEXK(b))) : b);
if (getCMode(o) != OpArgN)
snprintf(buf + strlen(buf), n - strlen(buf), " %d", getCMode(o) == OpArgK ? (MYK(INDEXK(c))) : c);
snprintf(buf + strlen(buf), n - strlen(buf), " C=%d", getCMode(o) == OpArgK ? (MYK(INDEXK(c))) : c);
break;
}
return buf;
@ -594,27 +594,27 @@ const char* print_instruction(char *buf, size_t n, Instruction i) {
int ax = GETARG_Ax(i);
int bx = GETARG_Bx(i);
int sbx = GETARG_sBx(i);
snprintf(buf, n, "%s %-9s\t", luaP_opnames[o]);
snprintf(buf, n, "%s ", luaP_opnames[o]);
switch (getOpMode(o)) {
case iABC:
snprintf(buf+strlen(buf), n-strlen(buf), "%d", a);
snprintf(buf+strlen(buf), n-strlen(buf), "A=%d", a);
if (getBMode(o) != OpArgN)
snprintf(buf + strlen(buf), n - strlen(buf), " %d", ISK(b) ? (MYK(INDEXK(b))) : b);
snprintf(buf + strlen(buf), n - strlen(buf), " B=%d", ISK(b) ? (MYK(INDEXK(b))) : b);
if (getCMode(o) != OpArgN)
snprintf(buf + strlen(buf), n - strlen(buf), " %d", ISK(c) ? (MYK(INDEXK(c))) : c);
snprintf(buf + strlen(buf), n - strlen(buf), " C=%d", ISK(c) ? (MYK(INDEXK(c))) : c);
break;
case iABx:
snprintf(buf + strlen(buf), n - strlen(buf), "%d", a);
snprintf(buf + strlen(buf), n - strlen(buf), "A=%d", a);
if (getBMode(o) == OpArgK)
snprintf(buf + strlen(buf), n - strlen(buf), " %d", MYK(bx));
snprintf(buf + strlen(buf), n - strlen(buf), " Bx=%d", MYK(bx));
if (getBMode(o) == OpArgU)
snprintf(buf + strlen(buf), n - strlen(buf), " %d", bx);
snprintf(buf + strlen(buf), n - strlen(buf), " Bx=%d", bx);
break;
case iAsBx:
snprintf(buf + strlen(buf), n - strlen(buf), "%d %d", a, sbx);
snprintf(buf + strlen(buf), n - strlen(buf), "As=%d Bx=%d", a, sbx);
break;
case iAx:
snprintf(buf + strlen(buf), n - strlen(buf), "%d", MYK(ax));
snprintf(buf + strlen(buf), n - strlen(buf), "Ax=%d", MYK(ax));
break;
}
return buf;

@ -9,6 +9,7 @@
#include "lprefix.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
@ -74,28 +75,125 @@ static const char *get_typename(int tt) {
}
}
void print_expdesc(FILE *fp, const char *desc, const expdesc *e) {
char buf[80] = { 0 };
fprintf(fp, desc);
static void print_expdesc(FILE *fp, FuncState *fs, const expdesc *e) {
char buf[80] = {0};
switch (e->k) {
case VVOID: fprintf(fp, "e{p=%p, k=VVOID, tt=%s}", e, get_typename(e->ravi_type)); break;
case VNIL: fprintf(fp, "e{p=%p, k=VNIL, tt=%s}", e, get_typename(e->ravi_type)); break;
case VTRUE: fprintf(fp, "e{p=%p, k=VTRUE, tt=%s}", e, get_typename(e->ravi_type)); break;
case VFALSE: fprintf(fp, "e{p=%p, k=VFALSE, tt=%s}", e, get_typename(e->ravi_type)); break;
case VK: fprintf(fp, "e{p=%p, k=VK, Kst=%d, tt=%s}", e, e->u.info, get_typename(e->ravi_type)); break;
case VKFLT: fprintf(fp, "e{p=%p, k=VKFLT, n=%f, tt=%s}", e, e->u.nval, get_typename(e->ravi_type)); break;
case VKINT: fprintf(fp, "e{p=%p, k=VKINT, n=%d, tt=%s}", e, e->u.ival, get_typename(e->ravi_type)); break;
case VNONRELOC: fprintf(fp, "e{p=%p, k=VNONRELOC, register=%d, tt=%s}", e, e->u.info, get_typename(e->ravi_type)); break;
case VLOCAL: fprintf(fp, "e{p=%p, k=LOCAL, register=%d, tt=%s}", e, e->u.info, get_typename(e->ravi_type)); break;
case VUPVAL: fprintf(fp, "e{p=%p, k=VUPVAL, idx=%d, tt=%s}", e, e->u.info, get_typename(e->ravi_type)); break;
case VINDEXED: fprintf(fp, "e{p=%p, k=VINDEXED, t=%d, idx=%d, tt=%s}", e, e->u.ind.t, e->u.ind.idx, get_typename(e->ravi_type)); break;
case VJMP: fprintf(fp, "e{p=%p, k=VJMP, pc=%d, tt=%s}", e, e->u.info, get_typename(e->ravi_type)); break;
case VRELOCABLE: fprintf(fp, "e{p=%p, k=VRELOCABLE, pc=%d, tt=%s}", e, e->u.info, get_typename(e->ravi_type)); break;
case VCALL: fprintf(fp, "e{p=%p, k=VCALL, pc=%d, tt=%s}", e, e->u.info, get_typename(e->ravi_type)); break;
case VVARARG: fprintf(fp, "e{p=%p, k=VVARARG, pc=%d, tt=%s}", e, e->u.info, get_typename(e->ravi_type)); break;
case VVOID:
fprintf(fp, "e{p=%p, k=VVOID, tt=%s}", e, get_typename(e->ravi_type));
break;
case VNIL:
fprintf(fp, "e{p=%p, k=VNIL, tt=%s}", e, get_typename(e->ravi_type));
break;
case VTRUE:
fprintf(fp, "e{p=%p, k=VTRUE, tt=%s}", e, get_typename(e->ravi_type));
break;
case VFALSE:
fprintf(fp, "e{p=%p, k=VFALSE, tt=%s}", e, get_typename(e->ravi_type));
break;
case VK:
fprintf(fp, "e{p=%p, k=VK, Kst=%d, tt=%s}", e, e->u.info,
get_typename(e->ravi_type));
break;
case VKFLT:
fprintf(fp, "e{p=%p, k=VKFLT, n=%f, tt=%s}", e, e->u.nval,
get_typename(e->ravi_type));
break;
case VKINT:
fprintf(fp, "e{p=%p, k=VKINT, n=%ld, tt=%s}", e, e->u.ival,
get_typename(e->ravi_type));
break;
case VNONRELOC:
fprintf(fp, "e{p=%p, k=VNONRELOC, register=%d %s, tt=%s}", e, e->u.info,
get_typename(getlocvartype(fs, e->u.info)),
get_typename(e->ravi_type));
break;
case VLOCAL:
fprintf(fp, "e{p=%p, k=LOCAL, register=%d, tt=%s}", e, e->u.info,
get_typename(e->ravi_type));
break;
case VUPVAL:
fprintf(fp, "e{p=%p, k=VUPVAL, idx=%d, tt=%s}", e, e->u.info,
get_typename(e->ravi_type));
break;
case VINDEXED:
fprintf(fp, "e{p=%p, k=VINDEXED, t=%d, idx=%d, tt=%s}", e, e->u.ind.t,
e->u.ind.idx, get_typename(e->ravi_type));
break;
case VJMP:
fprintf(fp, "e{p=%p, k=VJMP, pc=%d, i=(%s), tt=%s}", e, e->u.info,
print_instruction(buf, sizeof buf, getcode(fs, e)),
get_typename(e->ravi_type));
break;
case VRELOCABLE:
fprintf(fp, "e{p=%p, k=VRELOCABLE, pc=%d, i=(%s), tt=%s}", e, e->u.info,
print_instruction(buf, sizeof buf, getcode(fs, e)),
get_typename(e->ravi_type));
break;
case VCALL:
fprintf(fp, "e{p=%p, k=VCALL, pc=%d, i=(%s %s), tt=%s}", e, e->u.info,
print_instruction(buf, sizeof buf, getcode(fs, e)),
get_typename(getlocvartype(fs, GETARG_A(getcode(fs, e)))),
get_typename(e->ravi_type));
break;
case VVARARG:
fprintf(fp, "e{p=%p, k=VVARARG, pc=%d, i=(%s), tt=%s}", e, e->u.info,
print_instruction(buf, sizeof buf, getcode(fs, e)),
get_typename(e->ravi_type));
break;
}
}
void ravi_printf(FuncState *fs, const char *format, ...)
{
char buf[80] = { 0 };
va_list ap;
const char *cp;
va_start(ap, format);
for (cp = format; *cp; cp++) {
if (cp[0] == '%' && cp[1] == 'e') {
expdesc *e;
e = va_arg(ap, expdesc*);
print_expdesc(stdout, fs, e);
cp++;
}
else if (cp[0] == '%' && cp[1] == 'o') {
Instruction i;
i = va_arg(ap, Instruction);
print_instruction(buf, sizeof buf, i);
cp++;
}
else if (cp[0] == '%' && cp[1] == 'd') {
int i;
i = va_arg(ap, int);
printf("%d", i);
cp++;
}
else if (cp[0] == '%' && cp[1] == 's') {
const char *s;
s = va_arg(ap, const char *);
fputs(s, stdout);
cp++;
}
else if (cp[0] == '%' && cp[1] == 'f') {
double d;
d = va_arg(ap, double);
printf("%f", d);
cp++;
}
else if (cp[0] == '%' && cp[1] == 't') {
int i;
i = va_arg(ap, int);
fputs(get_typename(i), stdout);
cp++;
}
else {
fputc(*cp, stdout);
}
}
va_end(ap);
}
/*
** prototypes for recursive non-terminal functions
@ -389,7 +487,10 @@ static void singlevar (LexState *ls, expdesc *var) {
}
}
/* n = number of return values to adjust
/* Generate instructions for converting types
* This is needed post a function call to handle
* variable number of return values
* n = number of return values to adjust
*/
static void ravi_coercetype(LexState *ls, expdesc *v, int n)
{
@ -956,6 +1057,11 @@ static int explist (LexState *ls, expdesc *v) {
#if RAVI_ENABLED
static void ravi_typecheck(LexState *ls, expdesc *v, int *vars, int nvars, int n)
{
if (n < nvars && v->k == VRELOCABLE) {
#if 0
ravi_printf(ls->fs, "typechecking local variable type %t = %e\n", vars[n], v);
#endif
}
if (n < nvars && vars[n] != LUA_TNONE && v->ravi_type != vars[n]) {
/* if we are calling a function then convert return types */
if (v->ravi_type != vars[n] && (vars[n] == LUA_TNUMFLT || vars[n] == LUA_TNUMINT) && v->k == VCALL) {
@ -1495,6 +1601,11 @@ static void repeatstat (LexState *ls, int line) {
* called by fornum()
*/
static int exp1 (LexState *ls) {
/* Since the local variable in a fornum loop is local to the loop and does
* not use any variable in outer scope we don't need to check its
* type - also the loop is already optimised so no point trying to
* optimise the iteration variable
*/
expdesc e;
int reg;
e.ravi_type = LUA_TNONE;

@ -550,7 +550,8 @@ static int test_luacompexec1(const char *code, int expected)
int main(const char *argv[])
{
int failures = 0;
failures += test_luacomp1("local i:int, j:double; i,j = f()");
failures += test_luacomp1("local i:int; for i=1,10 do; print(i); end; print(i)");
failures += test_luacomp1("local i:int, j:double; i,j = f(); j = i*j+i");
failures += test_luacomp1("local d; d = f()");
failures += test_luacomp1("local d, e; d, e = f(), g()");
failures += test_luacomp1("local i:int, d:double = f()");

Loading…
Cancel
Save