Skip to content

Commit

Permalink
Deactivate stack mismatch check on a return from a lambda closure
Browse files Browse the repository at this point in the history
In a lambda closure a return opcode can occur in the middle of an expression,
where evaluated parts of the expression are already put on the stack,
resulting in a fatal error indicating that the stack head is higher than
the function frame. Although the message is correct it is normal behaviour
for lambda closures, therefore this check is now deactivated there.
The superfluous values on the stack will be removed later anyway.
(Fixes #868)
  • Loading branch information
amotzkau committed Oct 25, 2018
1 parent a91d988 commit 5dd7726
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/interpret.c
Expand Up @@ -8216,7 +8216,14 @@ eval_instruction (bytecode_p first_instruction
if (efp > sp)
fatal("Bad stack at F_RETURN, %"PRIdMPINT" values too low\n"
, (mp_int)(efp - sp));
else if (efp < sp)
/* In lambda closures the F_RETURN can occur anywhere, even in the
* middle of an expression, so we allow residual values on the stack
* then. The loop below will take care of them anyway.
*/
else if (efp < sp && (current_lambda.type != T_CLOSURE
|| (current_lambda.x.closure_type != CLOSURE_LAMBDA
&& current_lambda.x.closure_type != CLOSURE_BOUND_LAMBDA
&& current_lambda.x.closure_type != CLOSURE_UNBOUND_LAMBDA)))
fatal("Bad stack at F_RETURN, %"PRIdMPINT" values too high\n"
, (mp_int)(sp - efp));
#endif
Expand Down
54 changes: 54 additions & 0 deletions test/t-mantis.c
Expand Up @@ -433,6 +433,60 @@ nosave mixed *tests = ({
return sprintf("%b",1470) == "10110111110";
}
}),
({ "0000868-1", 0,
function int ()
{
return funcall(lambda(0, ({#'+, 3, ({#'return, 2}) }))) == 2;
}
}),
({ "0000868-2", 0,
function int ()
{
return funcall(lambda(0, ({#'=, ({ #'[, ({#'return, 2 }), 0 }), 10 }))) == 2;
}
}),
({ "0000868-3", 0,
function int ()
{
return funcall(lambda(0, ({#'foreach, 'x, '({2,4,6}), ({#'return, 'x}) }))) == 2;
}
}),
({ "0000868-4", 0,
function int ()
{
return funcall(lambda(0, ({#'foreach, ({'x, ({#'[, ({#'return, 2}), 0})}), ([1:'a', 2:'b', 3:'c']), 'x }))) == 2;
}
}),
({ "0000868-5", 0,
function int ()
{
return funcall(lambda(0, ({#'foreach, 'x, ({#'return, 2}), 'x }))) == 2;
}
}),
({ "0000868-6", 0,
function int ()
{
return funcall(lambda(0, ({#'({, 0, 1, ({#'return, 2}), 3}))) == 2;
}
}),
({ "0000868-7", 0,
function int ()
{
return funcall(lambda(0, ({#'+, 1, ({#'return, ({#'({, 0, 1, ({#'return, 2}) }), }) }))) == 2;
}
}),
({ "0000868-8", 0,
function int ()
{
return funcall(lambda(0, ({#'+, ([0,1,2,3]), ({(: 0 :), 0, 1, ({#'return, 2}), 3})}))) == 2;
}
}),
({ "0000868-9", 0,
function int ()
{
return funcall(bind_lambda(unbound_lambda(0, ({#'implode, '({"a","b","c"}), ({#'return, 2})})))) == 2;
}
}),
});

void run_test()
Expand Down

0 comments on commit 5dd7726

Please sign in to comment.