prepack icon indicating copy to clipboard operation
prepack copied to clipboard

State built up before a loop is lost

Open sebmarkbage opened this issue 6 years ago • 8 comments

(function () {
  var n = __abstract('number', '(5)');
  var arr = {0: 'a', 1: 'b'};
  var i = 2;
  do {
    arr[i] = 'x';
    i++;
  } while(i < n);
  result = arr;
})();

If a loop is building up state before a loop, it is lost once the unknown property is widened. But that state is not restored by the loop.

sebmarkbage avatar Apr 08 '18 22:04 sebmarkbage

Before we can hope to deal with this, we'll need a range domain (#1066).

hermanventer avatar Apr 09 '18 18:04 hermanventer

If you change the numeric properties to named ones, there's still a problem though.

sebmarkbage avatar Apr 09 '18 18:04 sebmarkbage

Yes, with loops you have to widen and once you widen, precision is lost. Range domains let you regain some of this precision. If you range over an unbounded collection of strings and use them as property names, it's pretty much game over.

hermanventer avatar Apr 09 '18 18:04 hermanventer

When we SetPartial outside a loop, then we weakly update the known properties. Is there a reason we can't do that for widened properties?

sebmarkbage avatar Apr 09 '18 18:04 sebmarkbage

We can do weak updates only if there is a join condition that is stable. A widened property name does not fit the bill.

hermanventer avatar Apr 09 '18 23:04 hermanventer

The interesting thing is that something like this works:

  var arr = {};
  var i = 0;
  do {
    arr[i] = i === 0 ? 'a' : i === 1 ? 'b' : 'x';

So I guess it's just important that the join condition gets evaluated inside the loop. Not after the loop.

sebmarkbage avatar Apr 10 '18 01:04 sebmarkbage

Wouldn’t snapshotting be an appropriate solution here?

In general we’re ok with losing precision later as long as we can serialize the state of an object as it was before we entered the lost precision (eg havocing or Object.assign).

sebmarkbage avatar Apr 10 '18 17:04 sebmarkbage

If you want to use the object before the loop, a snapshot should do the trick. I'm not sure if we can do this without the aid of an annotation. Could you provide a complete test case that represents the scenario you care about?

hermanventer avatar Apr 10 '18 17:04 hermanventer