facebookarchive / prepack

A JavaScript bundle optimizer.
http://prepack.io
Other
14.22k stars 424 forks source link

Deal with read/write conflicts in serializer #977

Open hermanventer opened 7 years ago

hermanventer commented 7 years ago

Consider this program:

let NativeEnvironment = __abstract({ someStringProperty: __abstract("string") }, "NativeEnvironment");
let p2 = NativeEnvironment.someStringProperty + " " + NativeEnvironment.someStringProperty;
console.log(p2);
NativeEnvironment.someStringProperty = "abc";
let p3 = NativeEnvironment.someStringProperty + " " + NativeEnvironment.someStringProperty;
console.log(p2);

Prepacking it gives this output:

(function () {
  var _0 = NativeEnvironment;
  var _$0 = _0.someStringProperty;

  if (typeof _$0 !== "string") {
    throw new Error("Prepack model invariant violation: " + _$0);
  }

  var _2 = _$0 + " ";

  var _1 = _2 + _$0;

  console.log(_1);
  var _4 = NativeEnvironment;
  var _3 = _4;
  _3.someStringProperty = "abc";
  console.log(_1);
})();

Note that the modification to NativeEnvironment.someStringProperty is not reflected in the value output by the subsequent console.log statement.

My understanding of what is going on here is that the value of "NativeEnvironment.someStringProperty" is treated as non temporal, which means that it can be read at any point and is not expected to ever change.

If that is what we want, the assignment NativeEnvironment.someStringProperty = "abc"; should be flagged as a likely error.

NTillmann commented 6 years ago

I think the "leaking" concept brought in by the "pure" mode addresses this issue, however, it is not something that's enabled by default (yet).