issue #163 simplify defer statement and fix memory leak

defer
Dibyendu Majumdar 5 years ago
parent edce55b997
commit 51eeb4e8c2

@ -149,14 +149,15 @@ int luaF_close (lua_State *L, StkId level, int status) {
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? */
if (uv->flags && ttisfunction(uv->v)) {
L->openupval = uv->u.open.next; /* remove from 'open' list */
if (uv->refcount == 0) { /* no references? */
UpVal uv1 = *uv; /* copy the upvalue as we will free it below */
luaM_free(L, uv); /* free upvalue before invoking any deferred functions */
if (uv1.flags && ttisfunction(uv1.v)) {
ptrdiff_t levelrel = savestack(L, level);
status = calldeferredfunction(L, uv->v, status);
status = calldeferredfunction(L, uv1.v, status);
level = restorestack(L, levelrel);
}
luaM_free(L, uv); /* free upvalue */ /* FIXME leak if error occurs above */
}
else {
setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */

@ -1298,13 +1298,15 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line, int deferred
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);
if (!deferred) {
checknext(ls, '(');
if (ismethod) {
new_localvarliteral(ls, "self"); /* create 'self' parameter */
adjustlocalvars(ls, 1);
}
parlist(ls);
checknext(ls, ')');
}
parlist(ls);
checknext(ls, ')');
statlist(ls);
new_fs.f->lastlinedefined = ls->linenumber;
check_match(ls, TK_END, TK_FUNCTION, line);
@ -2359,8 +2361,7 @@ static void statement (LexState *ls) {
break;
}
case TK_DEFER: { /* stat -> deferstat */
luaX_next(ls); /* skip LOCAL */
checknext(ls, TK_FUNCTION);
luaX_next(ls); /* skip DEFER */
localfunc(ls, 1);
break;
}

Loading…
Cancel
Save