Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

Bound Functions Referenced Before They're Initialized #449

Closed
sebmarkbage opened this issue Apr 24, 2017 · 4 comments
Closed

Bound Functions Referenced Before They're Initialized #449

sebmarkbage opened this issue Apr 24, 2017 · 4 comments
Assignees
Labels

Comments

@sebmarkbage
Copy link
Contributor

I don't yet know where this happens in the code, nor do I have a small repro yet but I thought I'd flag it early. When I run #397 on Prepack itself I'm getting two cases where properties are added to a function before it is initialized.

_1mZ.resolve = _1n0;
...
var _1mZ = _2zX.bind(null, _1hY);

Maybe it has something to do with the normal serialization relying on hoisting but hoisting doesn't work with the .bind(...) optimization that tries to minimize duplicates.

@NTillmann
Copy link
Contributor

We don't generally rely on function hoisting, but if you hit this there's certainly a bug somewhere in the cycle breaking. I need some help to reproduce it...

@sebmarkbage
Copy link
Contributor Author

Ok, this isn't repro of the same exact issue. Instead of the function being assigned to this is reading the not-yet-bound function. Seems related.

(function() {

  function wrap(obj) {
    function A() {
      return obj.hello();
    }
    function B() {
      return obj.world();
    }
    A.B = B;
    return A;
  }

  let fooObj = {};
  let barObj = {};
  let fooFn = wrap(fooObj);
  let barFn = wrap(barObj);

  // Create a cycle  
  fooObj.bar = barFn;
  barObj.foo = fooFn;

  global.foo = fooFn;

})();

->

(function () {
  function _6(obj) {
    return obj.hello();
  }

  function _7(obj) {
    return obj.world();
  }

  var _3 = {
    foo: _0
  };

  var _2 = _6.bind(null, _3);

  var _4 = _7.bind(null, _3);

  _2.B = _4;
  var _1 = {
    bar: _2
  };

  var _0 = _6.bind(null, _1);

  var _5 = _7.bind(null, _1);

  _0.B = _5;
  foo = _0;
}).call(this);

@sebmarkbage
Copy link
Contributor Author

Here's one that sort of repros the original issue:

(function() {

  function wrap(obj) {
    function A() {
      return obj.hello();
    }
    function B() {
      return obj.world();
    }
    A.B = B;
    return A;
  }

  let fooObj = {};
  let fooFn = wrap(fooObj);
  let barFn = wrap(fooObj);
  fooObj.bar = barFn;

  global.foo = fooFn;

})();

->

(function () {
  function _5() {
    return _1.hello();
  }

  function _6() {
    return _1.world();
  }

  _2.B = _3;
  var _1 = {
    bar: _2
  };

  var _0 = _5.bind(null);

  var _4 = _6.bind(null);

  _0.B = _4;

  var _2 = _5.bind(null);

  var _3 = _6.bind(null);

  foo = _0;
}).call(this);

@NTillmann
Copy link
Contributor

Thanks for distilling the repro! That really helped.
Fixed by referenced merged pull request.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants