Skip to content

Commit

Permalink
Handle lists being modified by use of ~
Browse files Browse the repository at this point in the history
Adjust how lists are built when ~ is used, so we do not crash
even if the list is modified as it is being constructed.

This also makes the behaviour of GAP consistent between bytecode
and immediate code.
  • Loading branch information
ChrisJefferson committed May 17, 2018
1 parent 5dcbb49 commit d0ba07a
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 14 deletions.
52 changes: 38 additions & 14 deletions src/exprs.c
Original file line number Diff line number Diff line change
Expand Up @@ -919,9 +919,18 @@ Obj EvalPermExpr (
**
** 'EvalListExpr' just calls 'ListExpr1' and 'ListExpr2' to evaluate the
** list expression.
**
** The 'safe' argument to ListExpr1 and ListExpr2 handle code which abuses ~
** access and change the partially built list.
**
** When 'safe' is 1, we use a slower code path which ensures the list is
** in a valid state after each element is added, and not crash if the
** size or TNUM of the list is changed during the construction of elements
** in the list.
**
*/
Obj ListExpr1 ( Expr expr );
void ListExpr2 ( Obj list, Expr expr );
Obj ListExpr1 ( Expr expr, Int safe );
void ListExpr2 ( Obj list, Expr expr, Int safe );
Obj RecExpr1 ( Expr expr );
void RecExpr2 ( Obj rec, Expr expr );

Expand All @@ -931,8 +940,8 @@ Obj EvalListExpr (
Obj list; /* list value, result */

/* evaluate the list expression */
list = ListExpr1( expr );
ListExpr2( list, expr );
list = ListExpr1( expr, 0 );
ListExpr2( list, expr, 0 );

/* return the result */
return list;
Expand Down Expand Up @@ -964,13 +973,13 @@ Obj EvalListTildeExpr (
tilde = STATE( Tilde );

/* create the list value */
list = ListExpr1( expr );
list = ListExpr1( expr, 1 );

/* assign the list to '~' */
STATE(Tilde) = list;

/* evaluate the subexpressions into the list value */
ListExpr2( list, expr );
ListExpr2( list, expr, 1 );

/* restore old value of '~' */
STATE(Tilde) = tilde;
Expand Down Expand Up @@ -999,8 +1008,9 @@ Obj EvalListTildeExpr (
** '[ [1], ~[1] ]' requires that the value of one subexpression is entered
** into the list value before the next subexpression is evaluated.
*/
Obj ListExpr1 (
Expr expr )
ALWAYS_INLINE Obj ListExpr1 (
Expr expr,
Int safe )
{
Obj list; /* list value, result */
Int len; /* logical length of the list */
Expand All @@ -1015,15 +1025,21 @@ Obj ListExpr1 (
else {
list = NEW_PLIST( T_PLIST, len );
}
SET_LEN_PLIST( list, len );
if(safe) {
SET_LEN_PLIST( list, 0 );
}
else {
SET_LEN_PLIST( list, len );
}

/* return the list */
return list;
}

void ListExpr2 (
ALWAYS_INLINE void ListExpr2 (
Obj list,
Expr expr )
Expr expr,
Int safe )
{
Obj sub; /* value of a subexpression */
Int len; /* logical length of the list */
Expand Down Expand Up @@ -1053,17 +1069,25 @@ void ListExpr2 (
{
if (posshole == 1)
{
SET_FILT_LIST(list, FN_IS_NDENSE);
if(!safe || TNUM_OBJ(list) == T_PLIST) {
SET_FILT_LIST(list, FN_IS_NDENSE);
}
posshole = 2;
}
sub = EVAL_EXPR( ADDR_EXPR(expr)[i-1] );
SET_ELM_PLIST( list, i, sub );
if(safe) {
ASS_LIST( list, i, sub );
}
else {
SET_ELM_PLIST( list, i, sub );
}
CHANGED_BAG( list );
}

}
if (!posshole)
if (!posshole && !safe) {
SET_FILT_LIST(list, FN_IS_DENSE);
}

}

Expand Down
11 changes: 11 additions & 0 deletions tst/testinstall/tilde.tst
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,15 @@ true
gap> i := InputTextString( "local a; a := 10; return rec(a := a*10, b := ~);" );;
gap> r := rec(a := ~, b := ReadAsFunction(i)(), c := ~.b.a);
rec( a := ~, b := rec( a := 100, b := ~.b ), c := 100 )
gap> [Length(~),Length(~),Length(~)];
[ 0, 1, 2 ]
gap> (function() return [Length(~),Length(~),Length(~)]; end)();
[ 0, 1, 2 ]
gap> rem := function(l) Remove(l); return 1; end;;
gap> [2,rem(~),rem(~),rem(~)];
[ ,,, 1 ]
gap> [2,rem(~),3,4,rem(~),5,6,rem(~)];
[ , 1, 3,, 1, 5,, 1 ]
gap> (function() return [2,rem(~),3,4,rem(~),5,6,rem(~)]; end)();
[ , 1, 3,, 1, 5,, 1 ]
gap> STOP_TEST( "tilde.tst", 1);

0 comments on commit d0ba07a

Please sign in to comment.