revise debug messages and allow them to be enabled when env variable RAVI_DEBUG_EXPR is set; reorder opcodes to be contiguous, add luac to the build, and ensure luac can dump Ravi bytecode

Dibyendu Majumdar 9 years ago
parent c4a646ba1e
commit ff30553186

@ -74,6 +74,9 @@ target_link_libraries(ravi ${EXTRA_LIBRARIES})
add_executable(lua src/lua.c)
target_link_libraries(lua ravi)
add_executable(luac src/luac.c)
target_link_libraries(luac ravi)
#VM test
add_executable(test_vm tests/test_vm.c)
target_link_libraries(test_vm ravi)

@ -325,6 +325,12 @@ OP_RAVI_LEIIKR,/* A B C if ((Kst(B) <= R(C)) ~= A) then pc++ */
OP_RAVI_LEIIRK,/* A B C if ((R(B) <= Kst(C)) ~= A) then pc++ */
OP_RAVI_LEIIRR,/* A B C if ((R(B) <= R(C)) ~= A) then pc++ */
OP_RAVI_TOINT, /* A R(A) := toint(R(A)) */
OP_RAVI_TOFLT, /* A R(A) := tofloat(R(A)) */
OP_RAVI_MOVEI, /* A B R(A) := R(B) */
OP_RAVI_MOVEF, /* A B R(A) := R(B) */
OP_RAVI_ARRAYGET_SIK,/* A B C R(A) := R(B)[Kst(C)] */
OP_RAVI_ARRAYGET_SIR,/* A B C R(A) := R(B)[R(C)] */
OP_RAVI_ARRAYGET_IIK,/* A B C R(A) := R(B)[Kst(C)] */
@ -351,16 +357,10 @@ OP_RAVI_ARRAYSET_ILKR,/* A B C R(A)[Kst(B)] := R(C) */
OP_RAVI_ARRAYSET_ILRK,/* A B C R(A)[R(B)] := Kst(C) */
OP_RAVI_ARRAYSET_ILRR,/* A B C R(A)[R(B)] := R(C) */
OP_RAVI_TOINT, /* A R(A) := toint(R(A)) */
OP_RAVI_TOFLT, /* A R(A) := tofloat(R(A)) */
OP_RAVI_MOVEI, /* A B R(A) := R(B) */
OP_RAVI_MOVEF, /* A B R(A) := R(B) */
} OpCode;
#define NUM_OPCODES (cast(int, OP_RAVI_MOVEF) + 1)
#define NUM_OPCODES (cast(int, OP_RAVI_ARRAYSET_ILRR) + 1)
/*===========================================================================
Notes:

@ -125,8 +125,6 @@ LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
Dyndata *dyd, const char *name, int firstchar);
LUAI_FUNC int ravi_parser_debug;
LUAI_FUNC void ravi_printf(FuncState *fs, const char *format, ...);
LUAI_FUNC int getlocvartype(FuncState *fs, int reg);

@ -457,6 +457,8 @@ struct lua_Debug {
/* }====================================================================== */
LUAI_FUNC int ravi_parser_debug;
/******************************************************************************
* Copyright (C) 1994-2015 Lua.org, PUC-Rio.

@ -349,6 +349,12 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
,opmode(1, 0, OpArgR, OpArgK, iABC) /*RAVI_LEIIRK A B C if ((R(B) <= Kst(C)) ~= A) then pc++ */
,opmode(1, 0, OpArgR, OpArgR, iABC) /*RAVI_LEIIRR A B C if ((R(B) <= R(C)) ~= A) then pc++ */
, opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_RAVI_TOINT A R(A) := toint(R(A)) */
, opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_RAVI_TOFLT A R(A) := tonumber(R(A)) */
, opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_RAVI_MOVEI A B R(A) := tointeger(R(B)) */
, opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_RAVI_MOVEF A B R(A) := tonumber(R(B)) */
,opmode(0, 1, OpArgR, OpArgK, iABC) /*RAVI_ARRAYGET_SIK A B C R(A) := R(B)[Kst(C)] */
,opmode(0, 1, OpArgR, OpArgR, iABC) /*RAVI_ARRAYGET_SIR A B C R(A) := R(B)[R(C)] */
,opmode(0, 1, OpArgR, OpArgK, iABC) /*RAVI_ARRAYGET_IIK A B C R(A) := R(B)[Kst(C)] */
@ -375,12 +381,6 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
,opmode(0, 0, OpArgR, OpArgK, iABC) /*RAVI_ARRAYSET_ILRK A B C R(A)[R(B)] := Kst(C) */
,opmode(0, 0, OpArgR, OpArgR, iABC) /*RAVI_ARRAYSET_ILRR A B C R(A)[R(B)] := R(C) */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_RAVI_TOINT A R(A) := toint(R(A)) */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_RAVI_TOFLT A R(A) := tonumber(R(A)) */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_RAVI_MOVEI A B R(A) := tointeger(R(B)) */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_RAVI_MOVEF A B R(A) := tonumber(R(B)) */
};
LUAI_DDEF const lu_byte luaP_optypes[NUM_OPCODES] = {
@ -530,6 +530,12 @@ LUAI_DDEF const lu_byte luaP_optypes[NUM_OPCODES] = {
, LUA_TNONE /*RAVI_LEIIRK A B C if ((R(B) <= Kst(C)) ~= A) then pc++ */
, LUA_TNONE /*RAVI_LEIIRR A B C if ((R(B) <= R(C)) ~= A) then pc++ */
, LUA_TNUMINT /* OP_RAVI_TOINT A R(A) := toint(R(A)) */
, LUA_TNUMFLT /* OP_RAVI_TOFLT A R(A) := tofloat(R(A)) */
, LUA_TNUMINT /* OP_RAVI_MOVEI A B R(A) := tointeger(R(B)) */
, LUA_TNUMFLT /* OP_RAVI_MOVEF A B R(A) := tonumber(R(B)) */
, LUA_TSTRING /*RAVI_ARRAYGET_SIK A B C R(A) := R(B)[Kst(C)] */
, LUA_TSTRING /*RAVI_ARRAYGET_SIR A B C R(A) := R(B)[R(C)] */
, LUA_TNUMINT /*RAVI_ARRAYGET_IIK A B C R(A) := R(B)[Kst(C)] */
@ -556,12 +562,6 @@ LUAI_DDEF const lu_byte luaP_optypes[NUM_OPCODES] = {
, LUA_TNONE /*RAVI_ARRAYSET_ILRK A B C R(A)[R(B)] := Kst(C) */
, LUA_TNONE /*RAVI_ARRAYSET_ILRR A B C R(A)[R(B)] := R(C) */
, LUA_TNUMINT /* OP_RAVI_TOINT A R(A) := toint(R(A)) */
, LUA_TNUMFLT /* OP_RAVI_TOFLT A R(A) := tofloat(R(A)) */
, LUA_TNUMINT /* OP_RAVI_MOVEI A B R(A) := tointeger(R(B)) */
, LUA_TNUMFLT /* OP_RAVI_MOVEF A B R(A) := tonumber(R(B)) */
};
#define MYK(x) (-1-(x))

@ -29,10 +29,7 @@
#include "ltable.h"
int ravi_parser_debug = 0;
#define DEBUG0(s) if (ravi_parser_debug) printf(s); else {}
#define DEBUG1(s,p1) if (ravi_parser_debug) printf(s,p1); else {}
#define DEBUG2(s,p1,p2) if (ravi_parser_debug) printf(s,p1,p2); else {}
#define DEBUG(p) if (ravi_parser_debug) {p;} else;
#define DEBUG_EXPR(p) if ((ravi_parser_debug & 1) != 0) {p;} else {}
/* maximum number of local variables per function (must be smaller
@ -79,64 +76,64 @@ 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));
fprintf(fp, "{p=%p, k=VVOID, type=%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));
fprintf(fp, "{p=%p, k=VNIL, type=%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));
fprintf(fp, "{p=%p, k=VTRUE, type=%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));
fprintf(fp, "{p=%p, k=VFALSE, type=%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,
fprintf(fp, "{p=%p, k=VK, Kst=%d, type=%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,
fprintf(fp, "{p=%p, k=VKFLT, n=%f, type=%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,
fprintf(fp, "{p=%p, k=VKINT, n=%ld, type=%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,
fprintf(fp, "{p=%p, k=VNONRELOC, register=%d %s, type=%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,
fprintf(fp, "{p=%p, k=VLOCAL, register=%d, type=%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,
fprintf(fp, "{p=%p, k=VUPVAL, idx=%d, type=%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));
fprintf(fp, "{p=%p, k=VINDEXED, tablereg=%d, indexreg=%d, vtype=%s, type=%s}", e, e->u.ind.t,
e->u.ind.idx, (e->u.ind.vt == VLOCAL) ? "VLOCAL": "VUPVAL", 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,
fprintf(fp, "{p=%p, k=VJMP, pc=%d, instruction=(%s), type=%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,
fprintf(fp, "{p=%p, k=VRELOCABLE, pc=%d, instruction=(%s), type=%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,
fprintf(fp, "{p=%p, k=VCALL, pc=%d, instruction=(%s %s), type=%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,
fprintf(fp, "{p=%p, k=VVARARG, pc=%d, instruction=(%s), type=%s}", e, e->u.info,
print_instruction(buf, sizeof buf, getcode(fs, e)),
get_typename(e->ravi_type));
break;
@ -160,6 +157,7 @@ void ravi_printf(FuncState *fs, const char *format, ...)
Instruction i;
i = va_arg(ap, Instruction);
print_instruction(buf, sizeof buf, i);
fputs(buf, stdout);
cp++;
}
else if (cp[0] == '%' && cp[1] == 'd') {
@ -357,13 +355,17 @@ static LocVar *getlocvar (FuncState *fs, int i) {
/* get type of a local var */
int getlocvartype(FuncState *fs, int i) {
lua_assert(i < dyd->actvar.n);
lua_assert(i < fs->ls->dyd->actvar.n);
if (i < 0 || i >= fs->ls->dyd->actvar.n)
return LUA_TNONE;
return fs->ls->dyd->actvar.arr[fs->firstlocal + i].ravi_type;
}
/* set type of a local var */
static void setlocvartype(FuncState *fs, int i, int tt) {
lua_assert(i < dyd->actvar.n);
lua_assert(i < fs->ls->dyd->actvar.n);
if (i < 0 || i >= fs->ls->dyd->actvar.n)
return;
fs->ls->dyd->actvar.arr[fs->firstlocal + i].ravi_type = tt;
}
@ -1361,7 +1363,10 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
subexpr(ls, v, UNARY_PRIORITY);
luaK_prefix(ls->fs, uop, v, line);
}
else simpleexp(ls, v);
else {
simpleexp(ls, v);
DEBUG_EXPR(ravi_printf(ls->fs, "subexpr -> simpleexpr %e\n", v));
}
/* expand while operators have priorities higher than 'limit' */
op = getbinopr(ls->t.token);
while (op != OPR_NOBINOPR && priority[op].left > limit) {
@ -1373,7 +1378,9 @@ static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
luaK_infix(ls->fs, op, v);
/* read sub-expression with higher priority */
nextop = subexpr(ls, &v2, priority[op].right);
DEBUG_EXPR(ravi_printf(ls->fs, "subexpr-> %e binop(%d) %e\n", v, (int)op, &v2));
luaK_posfix(ls->fs, op, v, &v2, line);
DEBUG_EXPR(ravi_printf(ls->fs, "subexpr-> after posfix %e\n", v));
op = nextop;
}
leavelevel(ls);
@ -1462,6 +1469,7 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
nv.v.ravi_type = LUA_TNONE;
nv.prev = lh;
suffixedexp(ls, &nv.v);
DEBUG_EXPR(ravi_printf(ls->fs, "assignment -> suffixedexp %e\n", &nv.v));
if (nv.v.k != VINDEXED)
check_conflict(ls, lh, &nv.v);
checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS,
@ -1472,6 +1480,7 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
int nexps;
checknext(ls, '=');
nexps = explist(ls, &e);
DEBUG_EXPR(ravi_printf(ls->fs, "assignment -> = explist %e\n", &e));
if (nexps != nvars) {
adjust_assign(ls, nvars, nexps, &e);
if (nexps > nvars)
@ -1480,11 +1489,13 @@ static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
else {
luaK_setoneret(ls->fs, &e); /* close last expression */
luaK_storevar(ls->fs, &lh->v, &e);
DEBUG_EXPR(ravi_printf(ls->fs, "assignment -> lhs = %e, rhs = %e\n", &lh->v, &e));
return; /* avoid default */
}
}
init_exp(&e, VNONRELOC, ls->fs->freereg-1, LUA_TNONE); /* default assignment */
luaK_storevar(ls->fs, &lh->v, &e);
DEBUG_EXPR(ravi_printf(ls->fs, "assignment lhs = %e, rhs = %e\n", &lh->v, &e));
}
/* parse condition in a repeat statement or an if control structure

@ -4,6 +4,11 @@
** See Copyright Notice in lua.h
*/
#ifdef _WIN32
// FIXME a hack
#define LUA_BUILD_AS_DLL
#endif
#define lua_c
#include "lprefix.h"
@ -599,6 +604,9 @@ int main (int argc, char **argv) {
l_message(argv[0], "cannot create state: not enough memory");
return EXIT_FAILURE;
}
if (getenv("RAVI_DEBUG_EXPR"))
ravi_parser_debug = 1;
lua_pushcfunction(L, &pmain); /* to call 'pmain' in protected mode */
lua_pushinteger(L, argc); /* 1st argument */
lua_pushlightuserdata(L, argv); /* 2nd argument */

@ -4,6 +4,11 @@
** See Copyright Notice in lua.h
*/
#ifdef _WIN32
// FIXME a hack
#define LUA_BUILD_AS_DLL
#endif
#define luac_c
#define LUA_CORE
@ -285,6 +290,27 @@ static void PrintConstant(const Proto* f, int i)
#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
#define MYK(x) (-1-(x))
static void PrintRaviCode(const Proto* f, Instruction i, int pc)
{
OpCode o = GET_OPCODE(i);
int a = GETARG_A(i);
int b = GETARG_B(i);
int c = GETARG_C(i);
int line = getfuncline(f, pc);
printf("\t%d\t", pc + 1);
if (line>0) printf("[%d]\t", line); else printf("[-]\t");
printf("%-9s\t", luaP_opnames[o]);
switch (getOpMode(o))
{
case iABC:
printf("%d", a);
if (getBMode(o) != OpArgN) printf(" %d", getBMode(o) == OpArgK ? (MYK(INDEXK(b))) : b);
if (getCMode(o) != OpArgN) printf(" %d", getCMode(o) == OpArgK ? (MYK(INDEXK(c))) : c);
break;
}
printf("\n");
}
static void PrintCode(const Proto* f)
{
const Instruction* code=f->code;
@ -293,7 +319,11 @@ static void PrintCode(const Proto* f)
{
Instruction i=code[pc];
OpCode o=GET_OPCODE(i);
int a=GETARG_A(i);
if (o >= OP_RAVI_UNMF) {
PrintRaviCode(f, i, pc);
continue;
}
int a = GETARG_A(i);
int b=GETARG_B(i);
int c=GETARG_C(i);
int ax=GETARG_Ax(i);

@ -550,6 +550,7 @@ static int test_luacompexec1(const char *code, int expected)
int main(const char *argv[])
{
int failures = 0;
failures += test_luacomp1("local i,j; j = i*j+i");
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()");

Loading…
Cancel
Save