Skip to content

Commit

Permalink
issue #163 'defer' implementation now controlled via RAVI_DEFER_STATE…
Browse files Browse the repository at this point in the history
…MENT macro. This allows testing of performance with and without the 'defer' statement
  • Loading branch information
dibyendumajumdar committed Mar 29, 2020
1 parent ab9fb1f commit b8af715
Show file tree
Hide file tree
Showing 22 changed files with 265 additions and 11 deletions.
8 changes: 8 additions & 0 deletions include/lfunc.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,12 @@
*/
struct UpVal {
TValue *v; /* points to stack or to its own value */
#ifdef RAVI_DEFER_STATEMENT
unsigned int refcount; /* reference counter */
unsigned int flags; /* Used to mark deferred values */
#else
lu_mem refcount; /* reference counter */
#endif
union {
struct { /* (when open) */
UpVal *next; /* linked list */
Expand All @@ -54,7 +58,11 @@ LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems);
LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems);
LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
#ifdef RAVI_DEFER_STATEMENT
LUAI_FUNC int luaF_close (lua_State *L, StkId level, int status);
#else
LUAI_FUNC void luaF_close (lua_State *L, StkId level);
#endif
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,
Expand Down
4 changes: 4 additions & 0 deletions include/llex.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ enum RESERVED {
/* terminal symbols denoted by reserved words */
TK_AND = FIRST_RESERVED, TK_BREAK,
TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
#ifdef RAVI_DEFER_STATEMENT
TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_DEFER, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
#else
TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
#endif
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
/* other terminal symbols */
TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
Expand Down
9 changes: 6 additions & 3 deletions include/lopcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,13 +280,16 @@ OP_RAVI_GETFIELD, /* A B C R(A) := R(B)[RK(C)], string key */
OP_RAVI_SELF_SK, /* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)], string key */
OP_RAVI_SETFIELD, /* A B C R(A)[RK(B)] := RK(C), string key */
OP_RAVI_GETTABUP_SK, /* A B C R(A) := UpValue[B][RK(C)], string key */

#ifdef RAVI_DEFER_STATEMENT
OP_RAVI_DEFER, /* A mark variable A "deferred" */

#endif
} OpCode;


#ifdef RAVI_DEFER_STATEMENT
#define NUM_OPCODES (cast(int, OP_RAVI_DEFER) + 1)
#else
#define NUM_OPCODES (cast(int, OP_RAVI_GETTABUP_SK) + 1)
#endif

/*===========================================================================
Notes:
Expand Down
2 changes: 2 additions & 0 deletions include/luaconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,8 @@
/* If following is defined as true then LLVM instructions emitted for arithmetic ops
priority floating point ops, else default is to prioritise integer ops */
#define RAVI_USE_LLVM_ARITH_FLOATPRIORITY 1
/* Enables the 'defer' statement - RAVI extension */
#define RAVI_DEFER_STATEMENT 1

#endif

2 changes: 2 additions & 0 deletions include/lvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ LUAI_FUNC void raviV_gettable_i(lua_State *L, const TValue *t, TValue *key, StkI
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_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);
#endif
LUAI_FUNC void raviV_debug_trace(lua_State *L, int opCode, int pc);

#endif
6 changes: 6 additions & 0 deletions include/ravi_llvmcodegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,9 @@ struct LuaLLVMTypes {
llvm::FunctionType *raviV_gettable_iT;
llvm::FunctionType *raviV_settable_iT;
llvm::FunctionType *raviV_op_totypeT;
#ifdef RAVI_DEFER_STATEMENT
llvm::FunctionType *raviV_op_deferT;
#endif

llvm::FunctionType *raviH_set_intT;
llvm::FunctionType *raviH_set_floatT;
Expand Down Expand Up @@ -830,7 +832,9 @@ struct RaviFunctionDef {
llvm::Function *raviV_gettable_iF;
llvm::Function *raviV_settable_iF;
llvm::Function *raviV_op_totypeF;
#ifdef RAVI_DEFER_STATEMENT
llvm::Function *raviV_op_deferF;
#endif

// array setters
llvm::Function *raviH_set_intF;
Expand Down Expand Up @@ -1373,7 +1377,9 @@ class RaviCodeGenerator {

void emit_BNOT(RaviFunctionDef *def, int A, int B, int pc);

#ifdef RAVI_DEFER_STATEMENT
void emit_DEFER(RaviFunctionDef *def, int A, int pc);
#endif

void emit_bitwise_shiftl(RaviFunctionDef *def, llvm::Value *ra, int B, lua_Integer y);

Expand Down
4 changes: 4 additions & 0 deletions ravi-tests/ravi_tests1.ravi
Original file line number Diff line number Diff line change
Expand Up @@ -1736,6 +1736,8 @@ compile(x)
assert(x(2,3) == 2^3)
print 'Test 77 OK'

--

-- Test defer statement
y = 0
function x()
Expand Down Expand Up @@ -1836,6 +1838,8 @@ assert(z.count == 0)
assert(y == 1)
print 'Test 82 OK'

--

for k,v in pairs(opcodes_coverage)
do
print(k, v)
Expand Down
10 changes: 10 additions & 0 deletions src/ldo.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,11 @@ static int recover (lua_State *L, int status) {
if (ci == NULL) return 0; /* no recovery point */
/* "finish" luaD_pcall */
oldtop = restorestack(L, ci->extra);
#ifdef RAVI_DEFER_STATEMENT
luaF_close(L, oldtop, status);
#else
luaF_close(L, oldtop);
#endif
luaD_seterrorobj(L, status, oldtop);
L->ci = ci;
L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
Expand Down Expand Up @@ -826,12 +830,18 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
status = luaD_rawrunprotected(L, func, u);
if (status != LUA_OK) { /* an error occurred? */
StkId oldtop = restorestack(L, old_top);
#ifndef RAVI_DEFER_STATEMENT
luaF_close(L, oldtop); /* close possible pending closures */
luaD_seterrorobj(L, status, oldtop);
#endif
L->ci = old_ci;
L->allowhook = old_allowhooks;
L->nny = old_nny;
#ifdef RAVI_DEFER_STATEMENT
status = luaF_close(L, oldtop, status); /* close possible pending closures */
oldtop = restorestack(L, old_top);
luaD_seterrorobj(L, status, oldtop);
#endif
luaD_shrinkstack(L);
}
L->errfunc = old_errfunc;
Expand Down
24 changes: 24 additions & 0 deletions src/lfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,22 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
lua_assert(isintwups(L) || L->openupval == NULL);
while (*pp != NULL && (p = *pp)->v >= level) {
lua_assert(upisopen(p));
#ifdef RAVI_DEFER_STATEMENT
if (p->v == level && !p->flags) /* found a corresponding upvalue that is not a deferred value? */ {
return p; /* return it */
}
#else
if (p->v == level) /* found a corresponding upvalue? */
return p; /* return it */
#endif
pp = &p->u.open.next;
}
/* not found: create a new upvalue */
uv = luaM_new(L, UpVal);
uv->refcount = 0;
#ifdef RAVI_DEFER_STATEMENT
uv->flags = 0;
#endif
uv->u.open.next = *pp; /* link it to list of open upvalues */
uv->u.open.touched = 1;
*pp = uv;
Expand All @@ -88,6 +95,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
return uv;
}

#ifdef RAVI_DEFER_STATEMENT
static void calldeferred(lua_State *L, void *ud) {
UNUSED(ud);
luaD_callnoyield(L, L->top - 2, 0);
Expand Down Expand Up @@ -167,6 +175,22 @@ int luaF_close (lua_State *L, StkId level, int status) {
}
return status;
}
#else
void luaF_close (lua_State *L, StkId level) {
UpVal *uv;
while (L->openupval != NULL && (uv = L->openupval)->v >= level) {
lua_assert(upisopen(uv));
L->openupval = uv->u.open.next; /* remove from 'open' list */
if (uv->refcount == 0) /* no references? */
luaM_free(L, uv); /* free upvalue */
else {
setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */
uv->v = &uv->u.value; /* now current value lives here */
luaC_upvalbarrier(L, uv);
}
}
}
#endif


Proto *luaF_newproto (lua_State *L) {
Expand Down
4 changes: 4 additions & 0 deletions src/llex.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@
static const char *const luaX_tokens [] = {
"and", "break", "do", "else", "elseif",
"end", "false", "for", "function", "goto", "if",
#ifdef RAVI_DEFER_STATEMENT
"in", "local", "defer", "nil", "not", "or", "repeat",
#else
"in", "local", "nil", "not", "or", "repeat",
#endif
"return", "then", "true", "until", "while",
"//", "..", "...", "==", ">=", "<=", "~=",
"<<", ">>", "::", "<eof>",
Expand Down
6 changes: 4 additions & 2 deletions src/lopcodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
"SELF_SK", /* _SK*/ /* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
"SETFIELD", /*_SK */ /* A B C R(A)[RK(B)] := RK(C), string key */
"GETTABUP_SK",
#ifdef RAVI_DEFER_STATEMENT
"DEFER",
#endif
NULL
};

Expand Down Expand Up @@ -306,9 +308,9 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_RAVI_SELF_SK */
,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_RAVI_SETFIELD */
,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_RAVI_GETTABUP_SK */

#ifdef RAVI_DEFER_STATEMENT
,opmode(0, 1, OpArgN, OpArgN, iABC) /* OP_RAVI_DEFER */

#endif
};


Expand Down
60 changes: 59 additions & 1 deletion src/lparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,7 @@ static Proto *addprototype (LexState *ls) {
** so that, if it invokes the GC, the GC knows which registers
** are in use at that time.
*/
#ifdef RAVI_DEFER_STATEMENT
static void codeclosure (LexState *ls, expdesc *v, int deferred) {
FuncState *fs = ls->fs->prev;
int pc = -1;
Expand All @@ -933,6 +934,14 @@ static void codeclosure (LexState *ls, expdesc *v, int deferred) {
}
DEBUG_VARS(raviY_printf(ls->fs, "codeclosure -> closure created %e\n", v));
}
#else
static void codeclosure (LexState *ls, expdesc *v) {
FuncState *fs = ls->fs->prev;
init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1), RAVI_TFUNCTION, NULL);
luaK_exp2nextreg(fs, v); /* fix it at the last register */
DEBUG_VARS(raviY_printf(ls->fs, "codeclosure -> closure created %e\n", v));
}
#endif


static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
Expand Down Expand Up @@ -1290,7 +1299,7 @@ static void parlist (LexState *ls) {
}
}


#ifdef RAVI_DEFER_STATEMENT
static void body (LexState *ls, expdesc *e, int ismethod, int line, int deferred) {
/* body -> '(' parlist ')' block END */
FuncState new_fs;
Expand All @@ -1313,6 +1322,28 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line, int deferred
codeclosure(ls, e, deferred);
close_func(ls);
}
#else
static void body (LexState *ls, expdesc *e, int ismethod, int line) {
/* body -> '(' parlist ')' block END */
FuncState new_fs;
BlockCnt bl;
new_fs.f = addprototype(ls);
new_fs.f->linedefined = line;
open_func(ls, &new_fs, &bl);
checknext(ls, '(');
if (ismethod) {
new_localvarliteral(ls, "self"); /* create 'self' parameter */
adjustlocalvars(ls, 1);
}
parlist(ls);
checknext(ls, ')');
statlist(ls);
new_fs.f->lastlinedefined = ls->linenumber;
check_match(ls, TK_END, TK_FUNCTION, line);
codeclosure(ls, e);
close_func(ls);
}
#endif

/* parse expression list */
static int explist (LexState *ls, expdesc *v) {
Expand Down Expand Up @@ -1602,7 +1633,11 @@ static void simpleexp (LexState *ls, expdesc *v) {
}
case TK_FUNCTION: {
luaX_next(ls);
#ifdef RAVI_DEFER_STATEMENT
body(ls, v, 0, ls->linenumber, 0);
#else
body(ls, v, 0, ls->linenumber);
#endif
return;
}
default: {
Expand Down Expand Up @@ -2187,6 +2222,7 @@ static void ifstat (LexState *ls, int line) {
}

/* parse a local function statement - called from statement() */
#ifdef RAVI_DEFER_STATEMENT
static void localfunc (LexState *ls, int defer) {
expdesc b = {.ravi_type = RAVI_TANY, .pc = -1};
FuncState *fs = ls->fs;
Expand All @@ -2203,6 +2239,18 @@ static void localfunc (LexState *ls, int defer) {
/* debug information will only see the variable after this point! */
getlocvar(fs, b.u.info)->startpc = fs->pc;
}
#else
static void localfunc (LexState *ls) {
expdesc b = {.ravi_type = RAVI_TANY, .pc = -1};
FuncState *fs = ls->fs;
/* RAVI change - add type */
new_localvar(ls, str_checkname(ls), RAVI_TFUNCTION, NULL); /* new local variable */
adjustlocalvars(ls, 1); /* enter its scope */
body(ls, &b, 0, ls->linenumber); /* function created in next register */
/* debug information will only see the variable after this point! */
getlocvar(fs, b.u.info)->startpc = fs->pc;
}
#endif

/* parse a local variable declaration statement - called from statement() */
static void localstat (LexState *ls) {
Expand Down Expand Up @@ -2262,7 +2310,11 @@ static void funcstat (LexState *ls, int line) {
luaX_next(ls); /* skip FUNCTION */
ismethod = funcname(ls, &v);
DEBUG_VARS(raviY_printf(ls->fs, "funcstat -> declaring function %e\n", &v));
#ifdef RAVI_DEFER_STATEMENT
body(ls, &b, ismethod, line, 0);
#else
body(ls, &b, ismethod, line);
#endif
luaK_storevar(ls->fs, &v, &b);
luaK_fixline(ls->fs, line); /* definition "happens" in the first line */
}
Expand Down Expand Up @@ -2355,16 +2407,22 @@ static void statement (LexState *ls) {
case TK_LOCAL: { /* stat -> localstat */
luaX_next(ls); /* skip LOCAL */
if (testnext(ls, TK_FUNCTION)) /* local function? */
#ifdef RAVI_DEFER_STATEMENT
localfunc(ls, 0);
#else
localfunc(ls);
#endif
else
localstat(ls);
break;
}
#ifdef RAVI_DEFER_STATEMENT
case TK_DEFER: { /* stat -> deferstat */
luaX_next(ls); /* skip DEFER */
localfunc(ls, 1);
break;
}
#endif
case TK_DBCOLON: { /* stat -> label */
luaX_next(ls); /* skip double colon */
labelstat(ls, str_checkname(ls), line);
Expand Down
Loading

0 comments on commit b8af715

Please sign in to comment.