facebookarchive / prepack

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

Regular and "array nested" optimized functions don't work together #2566

Open NTillmann opened 5 years ago

NTillmann commented 5 years ago

Prepacking this, with --instantRender (to trigger realm.arrayNestedOptimizedFunctionsEnabled, which is not otherwise directly exposed via the CLI)...

function f(a) {
  return Array.from(a).map(function() {
    function g() { return 21 + 21; }
    __optimize(g);
    return g;
  });
}
__optimize(f);

...results in...

var f;
(function () {
  var _$2 = this;
  var _$3 = _$2.Array;
  var _$4 = _$3.from;
  var _1 = function (a) {
    var _5 = function () {
      var _8 = function () {
        return 21 + 21;
      };
      return _8;
    };
    var _$0 = _$4(a);
    var _$1 = _$0.map(_5);
    return _$1;
  };
  _$2.f = _1;
}).call(this);

Note that _8 did NOT get optimized!

Also note that this message was produced:

In input file /tmp/test.js(3:5) RecoverableError PP1008: Called __optimize on function in failed speculative context (https://github.com/facebook/prepack/wiki/PP1008)

Not helpful, rather confusing, but likely related?

cblappert commented 5 years ago

Right, so what's happening here is that when we optimize the function in array.map, we record that we should optimize g, but g doesn't exist when we try to optimize it at the end of global code execution unless we apply the effects from the array.map optimized function.

We need to either record that the array.map function is the parent of g and apply it's effects before optimizing g or add a way to optimize g inplace during the call to map #2336