Commit Graph

656 Commits

Author SHA1 Message Date
Dan Abramov
9725823d4f Add regression tests for #1837, #1840, and #1848
Summary:
Since #1837 and #1848 got fixed at some point, this adds tests to verify they don't regress.
Closes https://github.com/facebook/prepack/pull/2066

Differential Revision: D8221658

Pulled By: gaearon

fbshipit-source-id: a31fc733964ae697252225993b813e8d5a445ed1
2018-05-31 08:23:02 -07:00
Dominic Gannaway
bcf7255ce3 Do not emit final property assignments when havocing
Summary:
Release notes: none

When in strict mode, emitting property assignments to a frozen object (ReactElement in this case) causes a runtime error. We shouldn't be emitting ReactElement properties when we havoc the object. Unfortunately, we can't do this to all final objects, because our internal snapshot test fails when doing this (because the final object has properties that are conditional and thus delayed, so we need all its bindings to be "flushed" at the point of havocing). As a more thorough future fix, we should probably add a separate codepath for serializing objects that are final (we delay the entire object being emitted until all its properties are ready, like the ReactElement serializer does).

Interestingly, the output contains an unused variable that should be removed NTillmann?

```js
var _0 = function (props, context) {
    "use strict";

    var _J = props;
    var _$0 = _J.b;

    var _1 = _$0 !== null;

    if (_1) {
      var _$1 = _J.b;
      var _$2 = _$1.x;

      var _5 = _$2 !== null;

      if (_5) {
        var _$3 = _J.b;
        var _$4 = _$3.x;
      }
    }

    var _$5 = _J.c;
    var _$6 = _J.someAbstractFunction;

    var _A = _1 ? _5 ? _$4 : null : null;

    var _8 = {  // <-- why has this not been removed? can we not mark the entry as "pure"
      a: 1,
      b: _A,
      c: _$5
    };
    _8.a = 1;
    _8.b = _A;
    _8.c = _$5;

    var _F = <div a={1} b={_A} c={_$5} />;

    var _$7 = props.someAbstractFunction(_F);

    return _F;
  };
```
Closes https://github.com/facebook/prepack/pull/2065

Differential Revision: D8221498

Pulled By: trueadm

fbshipit-source-id: e508cba2e930bec9c913efae3c653637671098c6
2018-05-31 07:27:44 -07:00
Herman Venter
bb12168a0d Make joinPossiblyNormalCompletionWithAbruptCompletion live up to its advertised behavior
Summary:
Release note: none

joinPossiblyNormalCompletionWithAbruptCompletion said that it always returned effects with completions of type JoinedAbruptCompletions. Some callers took it at is word. Turns out it was lying.

Fixed things so that the advertising is correct. Also fixed an issue with a generator being lost during joining. (This was a latent bug uncovered by this fix.)

Refactored the code that fails when a loop body contains both break and continue completions governed by abstract conditions.
Closes https://github.com/facebook/prepack/pull/2030

Reviewed By: trueadm

Differential Revision: D8188966

Pulled By: gaearon

fbshipit-source-id: 7b74d63ee34b6492614a4386e6ad7955c96cbf78
2018-05-31 06:51:12 -07:00
Nikolai Tillmann
0b0b675fbd A step forward towards fixing havocing object property bindings.
Summary:
Release notes: Improvements towards fully supporting havocing object property bindings.

This fixes #2013 and fixes #2017.

There are varios TODOs in the new code; whatever didn't violate any existing tests throws a FatalError,
while the other cases still silently do the wrong thing.
Once this PR lands, I'll file issues for the various TODOs which can then be worked on separately.
In any case, the changes in this PR are strictly making things better.

Adding regression tests from the fixed issues.
Closes https://github.com/facebook/prepack/pull/2023

Reviewed By: trueadm

Differential Revision: D8174176

Pulled By: NTillmann

fbshipit-source-id: 299af8546ea7474a67fc0d75ce6ad8649b060db7
2018-05-30 16:02:06 -07:00
Dominic Gannaway
fdc7ba549f Cleanup of all the React reconciler logic + remove mutations on ReactElements
Summary:
Release notes: none

This PR is a general spring cleaning of all the React logic. Nothing is fixed, but the logic for many of the aspects of the React reconciliation have been simplified and tidied up.

- I've removed all cases of mutating ReactElements, we now create new ReactElements instead of mutating – because, well, ReactElements are immutable (as are props).
- Removed ReactSerializerState and moved the logic that previous existed into `realm.react`.
- Simplified the branching logic of the reconciler so we no longer need to pass around state and instead use the existing conditional logic.

Manually tested on all our internal bundles are we have no failures.
Closes https://github.com/facebook/prepack/pull/2039

Reviewed By: gaearon

Differential Revision: D8205619

Pulled By: trueadm

fbshipit-source-id: a84c363038086b490d761dbe18711d617058f05c
2018-05-30 12:39:22 -07:00
Dominic Gannaway
bd29f451fd Tidy up simple tests and fix refuseSerialization bug
Summary:
Release note: none

This PR remove `firstRenderOnly` from a bunch of tests that shouldn't have had it and adds a new test for a big with `props` being incorrectly marked for `refuseSerialization` – `props` can be serialialized without the ReactElement, and the test shows how this might happen.
Closes https://github.com/facebook/prepack/pull/2057

Differential Revision: D8203483

Pulled By: gaearon

fbshipit-source-id: fbfb9cc3bbdadaba5884f87319cb5b54e4a0657a
2018-05-30 10:49:05 -07:00
Dan Abramov
f55285012e Back out "[prepack][PR] Support call expressions where the base might be an abstract conditional"
Summary: It caused some regressions but we're not sure why. Need to increase test coverage first. Reverting for now.

Reviewed By: trueadm

Differential Revision: D8205062

fbshipit-source-id: fe03f8ea9e8c3d85b3ce96912c5135019f407a56
2018-05-30 09:45:00 -07:00
Dominic Gannaway
24181252fe Support call expressions where the base might be an abstract conditional
Summary:
Release notes: support call expressions where the base might be an abstract conditional

This PR is a follow up on a TODO I left in last week. We currently don't fully use the power of Prepack  around abstract conditional function calls. This adds support for them when calling NativeFunctionValues. For example:

```js
function fn(a)  {
  var array = (a === null ? [1,2,3] : [4,5,6]);

  return array.join("-");
}

global.__optimize && __optimize(fn);
```

Now becomes:

```js
  var _1 = function (a) {
    return a === null ? "1-2-3" : "4-5-6";
  };
```

Beforehand, it compiled to:

```js
  var _1 = function (a) {
    var _$0 = (a === null ? [1, 2, 3] : [4, 5, 6]).join("-");

    return _$0;
  };
```
Closes https://github.com/facebook/prepack/pull/2051

Differential Revision: D8201793

Pulled By: trueadm

fbshipit-source-id: c9a570ef9da844d84d0d5548b5c2d7b600dd4226
2018-05-30 04:10:08 -07:00
Nadav Kaner
45750d84ad remove verbose error when invariant level is zero
Summary:
Release Note: none

fix #1893
remove verbose error when invariant level is zero
Closes https://github.com/facebook/prepack/pull/2038

Differential Revision: D8180698

Pulled By: NTillmann

fbshipit-source-id: e0f9504ef84215292a9b4182d23d0898e7ef6c32
2018-05-28 16:56:15 -07:00
Nikolai Tillmann
459f3dc802 Mutations of final objects are not allowed.
Summary:
Release notes: None

This fixes #2040.
Adding regression error handler test.
Closes https://github.com/facebook/prepack/pull/2042

Differential Revision: D8180569

Pulled By: NTillmann

fbshipit-source-id: 2fd2dff79a8d78db91e8d089df44476083e66b89
2018-05-28 15:22:30 -07:00
Nikolai Tillmann
2cf7e98cb2 Adding regression test for #2015.
Summary:
Release notes: None

This closes #2015.
Adding regression test, as this was fixed by #2008 and #2010.
Closes https://github.com/facebook/prepack/pull/2035

Differential Revision: D8177974

Pulled By: NTillmann

fbshipit-source-id: dcc014f57a7d3e6ad42ed1c61535b6991e06bbde
2018-05-27 14:21:12 -07:00
Dominic Gannaway
829acd5f64 Properly handle defaultProps with creation of ReactElements
Summary:
Release notes: none

After discussions last night with sebmarkbage, I noticed that we apply defaultProps in the wrong place when the config is partial object or an abstract object. This now uses a helper function, which is injected once for the entire bundle, that handles `defaultProps` cases as a temporal function entry. Added a regression test too.
Closes https://github.com/facebook/prepack/pull/2036

Differential Revision: D8175799

Pulled By: trueadm

fbshipit-source-id: b6bb4f30ee07f0bd9ac07fc91018c26936696f4b
2018-05-26 10:30:33 -07:00
Dominic Gannaway
47f84b405a Re-factor of the React createElement logic
Summary:
Release notes: none

Now that we have snapshotting from Object.assign and ToObject for abstracts, we can now upgrade the ReactElement creation logic, simplifying a bunch of routes which actually resulted in a bunch of components inlining in tests where they didn't before. Furthermore, it allows us to tighten up the Flow typings in the React reconciler and tidy up some of the checks for `key`s or `ref`s logic, which was a bit hard to read before and didn't take into account objects with multiple values in their values domain. This also fixes a bug with abstract conditional component types not getting the deafultProps values correctly.
Closes https://github.com/facebook/prepack/pull/1996

Differential Revision: D8172083

Pulled By: trueadm

fbshipit-source-id: 0a8a1e0631883c92e914aba1308a109b3afda137
2018-05-25 18:34:12 -07:00
Nikolai Tillmann
62636d4b2a When havocing immutable bindings, keep around and later use the leaked value
Summary:
Release notes: None

Adding regression test.
While this really just does something for const bindings that we probably don't care much about,
this is leading up to a similar change for final objects which is much more relevant.

(And eventually, the last known value of a havoced mutable binding and havoced non-final objects in between external calls should be handled in this way as well.)
Closes https://github.com/facebook/prepack/pull/2031

Differential Revision: D8172560

Pulled By: NTillmann

fbshipit-source-id: 4e839113d7e5cd0f676e0017dd774da82b6dcdcf
2018-05-25 18:04:09 -07:00
Dominic Gannaway
531b4972da Better support indexOf and reverse on unknown arrays with numeric properties
Summary:
Release notes: support `indexOf` and `reverse` on unknown arrays with numeric properties

This PR aims to better support `indexOf` and `reverse` on unknown arrays with numeric properties. Previously, these two methods on the array would cause a FatalError in pure mode that would recover and havoc the array itself and the arguments. I don't believe this is necessary for these two methods in pure mode because they don't mutate the arguments passed. In pure mode we expect that calling `toString` on the arguments won't affect global scope, so these operations should be fine to be emitted as temporals with them being havoced.

I also added a TODO to an area I want to look at next week that I feel will unlock many more optimizations and inlining possibilities (with regards to handling conditional abstract objects as the context of the function call).
Closes https://github.com/facebook/prepack/pull/2033

Differential Revision: D8172837

Pulled By: trueadm

fbshipit-source-id: 846e28c0e0a6d0d475ad6ba6ef705bf0eae55b85
2018-05-25 17:25:18 -07:00
Dominic Gannaway
3ec7ef254c Fix havoc bindings regression
Summary:
Release notes: none

Was a mistake on the original PR. Fixes https://github.com/facebook/prepack/issues/2032
Closes https://github.com/facebook/prepack/pull/2034

Differential Revision: D8172823

Pulled By: trueadm

fbshipit-source-id: 734c026331c78497f7261228f4c1995619fbc5bd
2018-05-25 17:10:42 -07:00
Dominic Gannaway
7a8dba42e9 Add Prepack __makeFinal global helper
Summary:
Release notes: adds a `__makeFinal` Prepack global helper

This is to be used in follow up PR tests.
Closes https://github.com/facebook/prepack/pull/2029

Differential Revision: D8164904

Pulled By: trueadm

fbshipit-source-id: 3f167ff683235e6e083467818ad6a489619205cc
2018-05-25 11:11:00 -07:00
Nikolai Tillmann
01ab307aa8 Fixing binding value after havocing
Summary:
Release notes: Fixing havocing of bindings.

This fixes #1973 and it fixes #2003.

When havocing a binding,
the binding's value at that point in time would remain in the binding,
and participate in the whole value merging process,
which was meant to compute final values and caused issues.

To fix this, an explicit assignment is now emitted at binding havocing time with the current binding value, and afterwards, the current binding value, which is irrelevant from then on, is set to undefined.

This effectively fixes the issue for bindings, but the whole way binding havocing works is a bit inefficient (after havocing, Prepack effectively stops tracking that binding); even worse, similar problems that we observed here for bindings should exist for object properties as well; and the generated code looks a bit awful. I'll follow up creating separate issues for those, but they are out of scope for this change.

Adding regression tests.
Closes https://github.com/facebook/prepack/pull/2010

Differential Revision: D8153779

Pulled By: NTillmann

fbshipit-source-id: 9d64980e0bf2c8afe018ba0814907b90d19a9f77
2018-05-24 18:27:55 -07:00
Nikolai Tillmann
e24b90aeec Havoc all the bindings, deal with havoced bindings that get assigned to.
Summary:
Release notes: None

This fixes #2001: `let` bindings didn't get properly havoced,
and things could got generally wrong when dealing with havoced bindings that get assigned to.
This fixes those basic issues, strictly making things better.

However, havoced bindings in general remains a conceptually flawed feature
as described in #2007.

Adding a few regression tests.
Closes https://github.com/facebook/prepack/pull/2008

Differential Revision: D8148798

Pulled By: NTillmann

fbshipit-source-id: 34b821915bb5f0416ac55b4e347f956959ae0594
2018-05-24 12:35:25 -07:00
Dominic Gannaway
75dfdea8d2 Havoc unknown array values
Summary:
Release notes: none

This was missed off when we created unknown array values. This makes it so they can be havoced.
Closes https://github.com/facebook/prepack/pull/2016

Differential Revision: D8139928

Pulled By: trueadm

fbshipit-source-id: e0ec54fe573f6b6b7f4e44f04d08a2d23976ed0a
2018-05-24 06:24:56 -07:00
Dominic Gannaway
74ae4f86dd Add ReactDOM.createPortal inlining
Summary:
Release notes: adds support for ReactDOM.createPortal inlining

Allows the React reconciler to inline components passed to ReactDOM.createPortal.
Closes https://github.com/facebook/prepack/pull/2006

Differential Revision: D8125418

Pulled By: trueadm

fbshipit-source-id: a25a2c23d1dcaa2edaada6fecb39ef80bb829cff
2018-05-23 15:24:35 -07:00
Dominic Gannaway
87591341b1 Add __doNotRender flag to React reconcilation
Summary:
Release notes: opt out of optimizing a React component in a tree with `__doNotRender`

This PR makes it possible to opt out of a single component in a React component tree by detecting a `__doNotRender` flag. For example:

```js
function MyComponent(props) {
   ...
}

MyComponent.__doNotRender = true;

class MyComponent extends React.Component {
  render() {
    ...
  }
}

MyComponent.__doNotRender = true;
```
Closes https://github.com/facebook/prepack/pull/2004

Differential Revision: D8123009

Pulled By: trueadm

fbshipit-source-id: d5fc54aea2ea1253e260e41c1fb7d4f2d4717ffd
2018-05-23 11:53:46 -07:00
Dominic Gannaway
cde1af298d Do not mutate arrays or ReactElements during React reconciliation
Summary:
Release notes: none

This fixes an issue that we were experiencing, that turned out to be the correct fix after looking at https://github.com/facebook/prepack/pull/1997. We shouldn't mutate arrays in the reconciliation process, instead we should create new ones when we have new values. Also, we should ensure that we don't mutate ReactElements during reconciliation too, instead we should just create new ones. Mutating existing objects and values breaks down completely when we enter nested effects that need to re-evaluate the same original values, so this fixes a bunch of internal issues we were seeing on our internal FB bundle.
Closes https://github.com/facebook/prepack/pull/1999

Differential Revision: D8105499

Pulled By: trueadm

fbshipit-source-id: 4e6ceb8b02c886c42156a8903c347765f101c840
2018-05-22 16:35:40 -07:00
Sapan Bhatia
373c6d917d Fix nit that crept through
Summary:
This line that refers to a missing variable slipped though a previous commit.
Closes https://github.com/facebook/prepack/pull/1988

Reviewed By: trueadm

Differential Revision: D8105162

Pulled By: sb98052

fbshipit-source-id: 6e35b882f0af94c2acd8096f955bd9ab7275ed77
2018-05-22 15:54:22 -07:00
Dominic Gannaway
393eba15ad Ensures all serializer test case output passes linting validation
Summary:
Release notes: all serializer tests now get linted via ESlint for correct output

This PR is pretty gigantic, but almost 99% of it is changing all the serializer tests so they pass the linting rules – which means that there must be no undefined variables or if they are, they are explicitly accesses via `global`. Furthermore, the linting also checks to ensure that all variables are defined before they are used.

Also I added a regression test `conditions3` that further validates some complex cases I was seeing fail in other cases. The ESlint config is also in its own module so it can be shared between `debug-fb-www`.
Closes https://github.com/facebook/prepack/pull/1998

Differential Revision: D8099445

Pulled By: trueadm

fbshipit-source-id: 4a03c57beb51e394bc7b334728090b9fc515eca8
2018-05-22 15:41:31 -07:00
Dominic Gannaway
195f68209a Always emit globals safe for strict mode
Summary:
Release notes: all globals emitted reference the global identifier

This is a PR to replace https://github.com/facebook/prepack/pull/1894 that fixes #1890. I found a much simpler fix was to ensure we always treat emitted globals as safe for strict mode regardless. I had to change a test that went against this assumption, but we end up with code that better conforms to strict mode without large changes under the hood to Prepack.
Closes https://github.com/facebook/prepack/pull/1911

Differential Revision: D8095772

Pulled By: trueadm

fbshipit-source-id: d4ed65ba8d52cdb0c8f2171d3f3c02bdd265c32d
2018-05-22 09:37:11 -07:00
Herman Venter
b6536991b0 Stack completion saved effects
Summary:
Release note: none

When forking the normal branch of a PossiblyNormalCompletion into yet another PossiblyNormalCompletion, push the current effects onto a stack of effects, rather than just continuing to use the currently active effects. Not doing so, causes mismatched undo operations.

The modified test case would fail and print 2 for y, without this change.
Closes https://github.com/facebook/prepack/pull/1993

Differential Revision: D8087175

Pulled By: hermanventer

fbshipit-source-id: 6b857b9885aa79a8e90b90e365a2b9688a34152d
2018-05-21 21:55:56 -07:00
Nikolai Tillmann
9c26f640ab Support for --delayInitializations for optimized functions
Summary:
Release notes: Support for --delayInitializations for optimized functions

Supporting this removes a TODO and is in response to #1973 (although more of a work-around than the actual fix).

Added tests.
Closes https://github.com/facebook/prepack/pull/1994

Differential Revision: D8087001

Pulled By: NTillmann

fbshipit-source-id: 572f41ffc024bef7954ebd88068f350fe08a84dc
2018-05-21 21:07:57 -07:00
Tim Seckinger
dd63339992 fix: coerce abstract values into strings for the Error constructor
Summary:
Release Notes: Fix abstract values not being coerced into strings for the Error constructor

Fixes #1827 NTillmann
The exact example from the issue now prepacks to
```javascript
(function () {
  var _0 = function () {
    return 42;
  };

  inspect = _0;
})();
```

I'm new here, so if this approach is completely wrong, please do notify me and guide me the way to a better one ;)
Closes https://github.com/facebook/prepack/pull/1960

Differential Revision: D8043199

Pulled By: NTillmann

fbshipit-source-id: 9c67fc2ab882398a20e6313b2894b5357b5ef038
2018-05-21 15:58:33 -07:00
Dominic Gannaway
3545cd8327 Render optimized react-dom/server renderToString ahead of time
Summary:
Release notes: adds experimental `react-dom/server` ahead-of-time rendering to string

This PR was part of a small 1-2 day hackathton to see the applicability of creating a server-side renderer based almost entirely to be a 1:1 of `ReactDOMServer` from `react-dom/server` package. This is by no means a full, complete server renderer but is the foundations for us to do further work on this path in the future. Currently, it consists of a single Jest test, to ensure the output of the Hacker News benchmark matches that of the current ReactDOMServer `renderToString` output.

The performance results look very promising (there are some `console.time` lines you can comment out in the test to see the performance for yourself). This implantation essentially compiles away `react` and `react-dom/server` and instead injects runtime helper functions that do things that cannot be statically determined ahead of time.

Lots of features are missing behind `invariant` TODOs. This was done intentionally.
Closes https://github.com/facebook/prepack/pull/1940

Differential Revision: D8075964

Pulled By: trueadm

fbshipit-source-id: 33b3c7ba26b41871ccd15ad8bde4ad257009fed6
2018-05-21 08:59:20 -07:00
Herman Venter
21cb2b4da5 Avoid redundant conversions to object
Summary:
Release note: none

When debugging another issue, I noticed that member expressions do explicit conversions of abstract base objects to object and that call expressions obtain a temporal value for the function but then go ahead without it, leaving a useless assignment in the timeline.
Closes https://github.com/facebook/prepack/pull/1983

Reviewed By: trueadm

Differential Revision: D8055038

Pulled By: hermanventer

fbshipit-source-id: 4dd394bb0c4df2f9656be453b8feae57cc0db516
2018-05-18 01:19:22 -07:00
Dominic Gannaway
da243f5b48 Fix bug with arrays with widened numeric properties
Summary:
Release notes: none

This PR fixes a bug where prototype methods on unknown arrays with widened numeric properties were incorrectly being used instead of following the route to filter which methods were safe or not. The functionality and logic for this was pulled out, into its own function so it can be re-used in places and tidied up.
Closes https://github.com/facebook/prepack/pull/1981

Differential Revision: D8043347

Pulled By: trueadm

fbshipit-source-id: 05415e5bdcb85818681a72323df16711a89f7c5c
2018-05-17 14:22:26 -07:00
Herman Venter
529ea0d760 Don't rotate effects trees
Summary:
Release note: fix numerous problems with code ordering
Closes: #1914

We've been seeing an endless stream of bugs where code is either missing or in the wrong place. A lot of these were due to the complexity of joinEffectsAndPromoteNested and some more are due to a fundamental flaw in its algorithm: it rotates branches of the effects tree in order to group together all completions of a given type. That can cause generators to end up in the wrong place in the temporal sequence.

We also had a problem with generators being duplicated in the tree.

This pull request introduces a new algorithm for doing what joinEffectsAndPromoteNested does. This too is complicated and I spent days on debugging and fixing many subtle issues. So, for now, I'm only doing it for calls. More will come in later pull requests.

I am not super confident that I've found and addressed all subtle bugs. I think we can expect to run into quite a few more of those. I am, however, reasonably confident that we now have the right approach to dealing with abrupt control flow.

Please have a careful look, but let's get this landed as soon as possible because it is on the critical path.
Closes https://github.com/facebook/prepack/pull/1979

Differential Revision: D8044482

Pulled By: hermanventer

fbshipit-source-id: 317402c5601fdea7366c9daf7762af0217302b54
2018-05-17 11:45:18 -07:00
Dominic Gannaway
b9d43d5e7d Move React side-effect logic in to the ThrowCompletion
Summary:
Release notes: none

This moves the side-effect detection logic for React component renders into the ThrowCompletion itself.
Closes https://github.com/facebook/prepack/pull/1977

Differential Revision: D8031923

Pulled By: trueadm

fbshipit-source-id: 189a2c7b729276193344a926db8f5a747460a8da
2018-05-16 14:08:52 -07:00
Xun Li
1f02f31308 Fix issue #1841.
Summary:
When either name or msg of Error is abstract, we do not want to partially evaluate it because the checks on string emptiness can be overwhelming, and better done in the VM than in JS.
Added a test to check these cases.
(I messed up my previous pull request. Sending a new one here.)
Closes https://github.com/facebook/prepack/pull/1974

Differential Revision: D8028508

Pulled By: lxfind

fbshipit-source-id: 8e1d1f2151e0b08b519935387298d4ffcd579f9b
2018-05-16 11:56:50 -07:00
Tim Seckinger
5df51ac6f4 stop the prototype cycle check if an object uses non-ordinary prototype methods
Summary:
Release Notes: stop the prototype cycle check if an object (e.g. proxy) uses non-ordinary prototype methods

Fixes #1017
Closes https://github.com/facebook/prepack/pull/1976

Differential Revision: D8027102

Pulled By: NTillmann

fbshipit-source-id: 886e6ce474255dadf937662e30a65adbfac5a1f1
2018-05-16 11:06:51 -07:00
Dominic Gannaway
f807a17b74 Further follow-up Array.from fixes
Summary:
Release notes: none

This is a follow up to the changes in https://github.com/facebook/prepack/pull/1926. This PR correctly fixes the derived values for waiting and ensures that the unknown array objects have their dependencies properly resolved. This fixes part of the issue in https://github.com/facebook/prepack/issues/1962, but it brought about another issue that this PR doesn't aim to solve – dependencies on an abstract function call's unbound/bound bindings.
Closes https://github.com/facebook/prepack/pull/1970

Differential Revision: D8024402

Pulled By: trueadm

fbshipit-source-id: b9f9e725b7b22241209ef5a6f3b29dc0f2eeddeb
2018-05-16 05:15:03 -07:00
Nikolai Tillmann
ea0624b108 Distribute conditionals in certain relational expressions
Summary:
Release notes: More simplification rules

The existing simplifier would never go into relational expressions
and distribute conditional expressions. It does now.

With this change, `AbstractValue.createFromBinaryOp` joins many other
value factory functions that may return non-abstract values.

This caused various changes downstream in types, and dealing with concrete
instead of abstract values.

Adding regression test.
Closes https://github.com/facebook/prepack/pull/1972

Differential Revision: D8023363

Pulled By: NTillmann

fbshipit-source-id: a3cd6f7752ba24d039c6085bec2ee93f7587af26
2018-05-15 23:56:32 -07:00
Nikolai Tillmann
6b3866885f Fixing AbstractObjectValue's $Get
Summary:
Release notes: None

It used to bail out for conditional abstract values when accessing
a prototype that existed on neither side of the condition. No more.
Also, things used to be wrong in the presence of object prototypes.
That's also getting fixed.

Adding regression tests.
Closes https://github.com/facebook/prepack/pull/1963

Differential Revision: D8000539

Pulled By: NTillmann

fbshipit-source-id: 5214f213ea49c63e9637126360d3c90aace92d20
2018-05-14 18:03:46 -07:00
Nikolai Tillmann
ad9ed9ba97 Don't treat original constructor specially in the visitor.
Summary:
Release notes: None

This fixes #1957.
Turns out that the special case is no longer needed, and just removing that code fixes the issue now.
Adding regression test.
Closes https://github.com/facebook/prepack/pull/1958

Differential Revision: D7995563

Pulled By: NTillmann

fbshipit-source-id: 6822c5433679fd88bd5a052ca23824cb3f3eabba
2018-05-14 13:55:47 -07:00
Herman Venter
770bfef8ca Objects that are temporal should set _isScopedTemplate to true
Summary:
Release note: Fixes problem with result of Array.filter (and similar) applied to arrays with unknown properties

Closes: #1924

Generator.deriveConcrete can result in temporal object values. These must be marked with _isScopedTemplate to prevent them from being hoisted.
Closes https://github.com/facebook/prepack/pull/1926

Reviewed By: trueadm

Differential Revision: D7949463

Pulled By: hermanventer

fbshipit-source-id: 2f15117725c37e9b09cae8ac469ee5b2eb481b6c
2018-05-14 13:55:46 -07:00
Nikolai Tillmann
9685f866ce Fix frozen lazy objects
Summary:
Release notes: None

The `Object.freeze` command (or similar) was put into the body
where the object was allocated, not where it got initialized.
This would cause the initialization code to silently fail later on when the object was used for the first time.

This fixes it, and adds a regression test.
Closes https://github.com/facebook/prepack/pull/1936

Differential Revision: D7994911

Pulled By: NTillmann

fbshipit-source-id: 6ec0706357706f7bf80f62690be9aea1f30f8a72
2018-05-14 13:05:44 -07:00
Dan Abramov
b594b283c2 Don't treat makePartial() as a mutation in havoc checker
Summary:
Fixes https://github.com/facebook/prepack/issues/1931.

The issue is that this call may happen on a havoced object:

41e9dcb398/src/intrinsics/ecma262/Object.js (L98-L100)

That fails. But I'm not sure it makes sense to even check havocing for internal properties like `_isPartial_binding`.

Maybe there's a deeper problem here. I don't see it but at least this gets the ball rolling.
Closes https://github.com/facebook/prepack/pull/1955

Differential Revision: D7992958

Pulled By: gaearon

fbshipit-source-id: 3e843ae159896c15b8f9dc2fd6956b148a2ef44f
2018-05-14 11:59:52 -07:00
Dan Abramov
200b5c5f59 Conditional return completions might need to be dereferenced
Summary:
Fixes https://github.com/facebook/prepack/issues/1953.

We used to delegate handling of conditional expression to `IfStatement`. But this is not entirely accurate because conditional expression completion might be an identifier. `IfStatement` rules are too restrictive.

I copy pasted the code from IfStatement and added `GetValue` dereferencing [to match the specification](http://www.ecma-international.org/ecma-262/7.0/#sec-conditional-operator-runtime-semantics-evaluation). I also removed `UpdateEmpty()` calls which seem to only be relevant to `IfStatement` evaluation.

Adds a regression test.
Closes https://github.com/facebook/prepack/pull/1954

Differential Revision: D7988920

Pulled By: gaearon

fbshipit-source-id: ac130076dbaa04d5d661adb984b408b4d3b57fa3
2018-05-14 08:09:16 -07:00
Dan
41e9dcb398 Fix havoc logic for conditional abstracts
Summary:
Fixes https://github.com/facebook/prepack/issues/1883.

As I noted there,

>This seems to happen because the logic in `visitObjectPropertiesWithComputedNames` hasn't been updated in the same way that [its twin in the residual heap visitor has been](aa700a2667/src/serializer/ResidualHeapVisitor.js (L361-L388)).

This brings them in line.

Regression case included. It used to fail with bad output even after this change, but https://github.com/facebook/prepack/pull/1937 fixed that, so now it passes.
Closes https://github.com/facebook/prepack/pull/1942

Reviewed By: trueadm

Differential Revision: D7987993

Pulled By: gaearon

fbshipit-source-id: 1ebda0c38f2f932aa18872bfc9a919938fc2ef96
2018-05-14 02:52:09 -07:00
Dan Abramov
20683624ab Put EmptyValue into correct join branch
Summary:
Fixes https://github.com/facebook/prepack/issues/1935.
The issue was that we'd always put `EmptyValue` into the right branch even if it happened in the left one.

Adds a regression test.
Closes https://github.com/facebook/prepack/pull/1937

Reviewed By: trueadm

Differential Revision: D7967344

Pulled By: gaearon

fbshipit-source-id: ece8550787679e2fc33f040989ceae0cf3a7c2a2
2018-05-11 07:07:02 -07:00
Dan Abramov
10a600854c Fix a simplifer issue
Summary:
This might be wrong, I haven't though about it in depth yet.
Appears to fix https://github.com/facebook/prepack/issues/1930 and https://github.com/facebook/prepack/issues/1830.

Tests pass.
Closes https://github.com/facebook/prepack/pull/1933

Differential Revision: D7954943

Pulled By: gaearon

fbshipit-source-id: e19166cc22efcffbe7c4082d3df5e5c82c9f79e8
2018-05-10 12:09:08 -07:00
Nikolai Tillmann
4b980396c9 Don't serialize changes to property bindings that represent internal slots
Summary:
Release notes: None

This fixes #1856, at least in the sense that Prepack won't silently generate wrong code.
Instead, Prepack will now issue an error indicating that a Prepack limitation was hit.

Adding error-handler regression test.

Also fixed reference to PP1023 (no wiki page) to be PP0023 (matching wiki page) instead.
Closes https://github.com/facebook/prepack/pull/1929

Differential Revision: D7954903

Pulled By: NTillmann

fbshipit-source-id: f9676f33e74ff36067832333a7ee9a26ec77126d
2018-05-10 12:09:01 -07:00
Dominic Gannaway
00d8a1a820 Throw an error when side-effectful logic happens in a React component tree
Summary:
Release notes: the React reconciler now throw a FatalError upon encountering side-effects in a render

This PR revamps the current React system's restrictions for what you can and can't do during the React reconcilation phase. This is a pretty large update but provides much better boundaries between what is "safe" and not "safe", thus reducing the constraints.

1. A new error `ReconcilerRenderBailOut` is thrown if something occurs in the React reconciliation that causes the render to fail and it's a hard fail – no recovering and continuing.
2. If you mutate a binding/object outside the render phase, given the React component render phase is meant to be "pure", a `ReconcilerRenderBailOut` will be thrown.
3. If you `throw` during the React reconciliation phase, again a `ReconcilerRenderBailOut` will be thrown.

In the future, we should maybe loosen the constraints around all this and maybe allow `throw`, but right now it's causing too much friction. We should attempt to make React components render phase as pure as possible – as it results in much better optimizations by a compiler because we can assert far more without things tripping us up.

Another point, regarding (1), is that we should ideally be able to recover from the error thrown in Prepack. The reason we can't and is something that might be a very deep issue in Prepack, is that effects don't properly restore when we have nested PossiblyNormalCompletions at work. Bindings get mutated on records from changes made within `evaluateForEffects` but never get reset when in nested PossiblyNormalCompletion. If I remove all the things that can cause `PossiblyNormalCompletion`s then everything works fine and bindings do get restored. We can remove the constraint on (1) once we've found and fixed that issue.
Closes https://github.com/facebook/prepack/pull/1860

Differential Revision: D7950562

Pulled By: trueadm

fbshipit-source-id: 4657e68b084c7069622e88c9655823b5f1f9386f
2018-05-10 07:50:24 -07:00
Herman Venter
8f2e2fe353 Prevent CSE from hoisting Object.assign calls.
Summary:
Release note: none

Resolves issue #1865

Abstract values that are known to result in objects (of unknown identity) should not be eligible for Common Subexpression Elimination (CSE).
Closes https://github.com/facebook/prepack/pull/1925

Differential Revision: D7941893

Pulled By: hermanventer

fbshipit-source-id: 454e26c6d042093b9fbae06d73110202083731b6
2018-05-09 15:49:56 -07:00
Nikolai Tillmann
693250fea2 Adding regression test for #1881
Summary:
Release notes: None

Closes https://github.com/facebook/prepack/pull/1919

Differential Revision: D7936510

Pulled By: NTillmann

fbshipit-source-id: 5165537ff8d3b9800ab3cbdda250d38f13059a2c
2018-05-09 12:12:19 -07:00
Dominic Gannaway
19b2bde1bb Fixes an issue with getOwnPropertyDescriptor
Summary:
Release notes: fixes an issue with getOwnPropertyDescriptor when dealing with a native prototype function

This PR fixes #1285, specifically when using `Object.getOwnPropertyDescriptor` on a native prototype function, we have to resort to returning a temporal abstract as this function isn't available at build time. I also renamed all the tests with typos in them.

cc anilanar
Closes https://github.com/facebook/prepack/pull/1913

Differential Revision: D7935215

Pulled By: trueadm

fbshipit-source-id: d7e33cf8bd73aa2c1156966ad86e9da9fb0404e4
2018-05-09 11:09:05 -07:00
Herman Venter
bfde1606e1 Stop processing statements after program terminating exception
Summary:
Release note: Do not generate code for unreachable global code statements

Resolves issue #1906

If an unconditional throw is encountered, it does not make sense to keep processing top level statements.
Closes https://github.com/facebook/prepack/pull/1908

Differential Revision: D7934963

Pulled By: hermanventer

fbshipit-source-id: d6e6b26d7ad7c54a065e43a74ad1b27959159c7a
2018-05-09 10:50:17 -07:00
Dan Abramov
c4c1593b22 Add a serializer regression test for #1833
Summary:
Regression test.
Closes https://github.com/facebook/prepack/pull/1916

Differential Revision: D7931571

Pulled By: gaearon

fbshipit-source-id: a442ad2cb68c97d731dd8fbe03886562c8dde18c
2018-05-09 09:40:25 -07:00
Nikolai Tillmann
6fe3600e05 Fix various issues in serializer and emitter around target body selection.
Summary:
Release notes: None

This fixes #1821.

Improve tracking of target bodies in Emitter,
which is necessary now that generators can have effects
and one should not attempt to emit into a body
with the wrong effects in place; removed some dubious code there.

It turned out that the exact placement of `Object.freeze` and similar statements
was always a bit fragile; this issue came out after fixing the Emitter, and so
this is made robust by keeping track of the
emission of all other object property mutations, and only emitting the
`Object.freeze` after they are all done.

When visiting modified property bindings, re-visit object in case it was
previously visited from a different scope.

For objects visited (only) in scopes where additional generator effects have been
applied, record additional information for serialization to ensure that these
objects get serialized in their creation scopes, so that the initial values
of the object properties are not polluted by the additional generator effects
of some nested scope.

Adding regression test.
Closes https://github.com/facebook/prepack/pull/1850

Differential Revision: D7928970

Pulled By: NTillmann

fbshipit-source-id: e8587be393fb078cc503718932057d7b10d0df72
2018-05-09 07:13:49 -07:00
Herman Venter
8008859a43 Do not apply the effects of JoinedAbruptCompletions.
Summary:
Release note: Fix problems with duplicated and missing statements

Resolves issue: #1842

Code duplication happened because the joined effects of two abrupt completions were applied first in aggregate and then again individually.

While debugging through this, I found it much simpler to understand Generator.fromEffects when applied to an Effects that has not been joined, so now things are closer to what they were before I started trying to hack past issues. The main difference is that a fully joined up set of effects is applied before serializing the result from Generator.fromEffects.

All of this caused an invariant to fail during a test. The invariant is complicated, fails in other new scenarios and is being reworked by Nikolai, so I've removed it for now in order to get these fixes in so that we are all on the same page again.
Closes https://github.com/facebook/prepack/pull/1903

Differential Revision: D7920610

Pulled By: hermanventer

fbshipit-source-id: 89b6ac9f1b8df776657c3a93550fdd3eb2ae4cd7
2018-05-09 03:18:20 -07:00
Dominic Gannaway
32d9973c30 Adds react-dom/server mocks
Summary:
Release notes: adds ReactDOMServer mocks

This adds ReactDOMServer mocks plus a test.
Closes https://github.com/facebook/prepack/pull/1896

Differential Revision: D7908920

Pulled By: trueadm

fbshipit-source-id: 1889efc3a0a9ff6e4d8d5ec26de5196d528e7eb0
2018-05-08 06:43:22 -07:00
Nikolai Tillmann
3371257f29 Properly serialize object of modified object property
Summary:
Release notes: None

This fixes #1857.

The implementation to serialize modified object properties
didn't actually kick off serialization of the modified object.

Added regression test.
Closes https://github.com/facebook/prepack/pull/1882

Differential Revision: D7889917

Pulled By: NTillmann

fbshipit-source-id: c665c685a4d2f3b0a06238ea5b04c40c294bb45a
2018-05-05 17:38:05 -07:00
Dan Abramov
e72989cad6 Add a serializer regression test for #1832
Summary:
Adds a regression test for https://github.com/facebook/prepack/issues/1832.

It was fixed in https://github.com/facebook/prepack/pull/1863 but the regression tests in it didn't cover against the specific invariant I was bumping into.

I checked this test fails before the fix.
Closes https://github.com/facebook/prepack/pull/1880

Reviewed By: trueadm

Differential Revision: D7889850

Pulled By: gaearon

fbshipit-source-id: de8b534466b6a28dd3b87f9834344aeda248c29b
2018-05-05 17:05:22 -07:00
Nikolai Tillmann
118d31aa49 Remove simple closures.
Summary:
Release notes: Removing --simpleClosures option.

This feature was never fully implemented and remained buggy.
Instead of having two distinct modes, let's rather try to improve
pointwise what we perceive as inacceptible for the regular way of
why closures work in the serializer.
Closes https://github.com/facebook/prepack/pull/1876

Differential Revision: D7889689

Pulled By: NTillmann

fbshipit-source-id: 782a6754408a9b250d45691274902c6bb2ed6924
2018-05-05 16:24:14 -07:00
Herman Venter
1570474ed6 Avoid duplicating generators
Summary:
Release note: none

When joining PossiblyNormalCompletions/JoinedAbruptCompletions while promoting particular kinds of completions (such as return completions), do not compose normal effects since that has already happened.

Thanks to Sapan for finding the issue, making a nice test case and identifying the code that is at fault.

This PR supersedes #1872.
Closes https://github.com/facebook/prepack/pull/1875

Reviewed By: trueadm

Differential Revision: D7888926

Pulled By: hermanventer

fbshipit-source-id: 58071b80ce68e89e5a38c0b7b5a2061c5539a304
2018-05-05 06:22:18 -07:00
Dominic Gannaway
3005452448 Fixes issues with React reconcilers abstract conditional evaluator
Summary:
Release notes: none

This fixes https://github.com/facebook/prepack/issues/1866. The React reconciler previously had somewhat broken logic when dealing with conditional that may require effects being joined together for things such as if statements. This re-uses the logic in `IfStatement` to ensure we get it right. Furthermore, I found a bug in `fb20.js` that failed unless we made sure we throw a `FatalError` in `AbstractObjectValue` where both consequent and alternate values are not found – like done in other methods in `AbstractObjectValue` joining together a value in this scenario actually generated broken output.
Closes https://github.com/facebook/prepack/pull/1874

Differential Revision: D7887489

Pulled By: trueadm

fbshipit-source-id: 64595296e5090b55a1670ab989e6737d7febab55
2018-05-05 04:18:35 -07:00
Herman Venter
697073b72a Deal with joins of joins when promoting
Summary:
Release note: none

While debugging various issues with generators, I noticed that joinEffectsAndPromoteNested does not quite live up to its advertising because it does not handle all the permutations of results that could contain abrupt completions of the given type.

Fixed this and added test cases. The tree manipulations are quite subtle. I went to some trouble to verify that they are correct, using diagrams, but did not want to put the diagrams in the code, so the reading may be a bit tough.
Closes https://github.com/facebook/prepack/pull/1873

Differential Revision: D7886038

Pulled By: hermanventer

fbshipit-source-id: df874ca5fad771932490428d54ff22b022fec74c
2018-05-04 17:24:08 -07:00
Sapan Bhatia
9fe584fe9f Fix while and for loops with unlabeled breaks
Summary:
BreakCompletions that were not joined previously fall through joinAllLoops. This change converts such cases to NormalCompletions. Without this change, prepacking fails with an invariant failure.
Closes https://github.com/facebook/prepack/pull/1863

Differential Revision: D7876263

Pulled By: sb98052

fbshipit-source-id: fed191c1163da412291c6a09674220b6133a99b1
2018-05-04 04:35:30 -07:00
Sapan Bhatia
8ec0b2efaa Set value of joined BreakCompletions
Summary:
Small fix to value of joined BreakCompletions
Closes https://github.com/facebook/prepack/pull/1861

Differential Revision: D7867413

Pulled By: sb98052

fbshipit-source-id: 94ff51ae0225b8381a79d9fd53128b18448b65a4
2018-05-03 16:01:33 -07:00
Herman Venter
4af05bd908 Deal with possibly normal completions from joined switch
Summary:
Release note: Support switch statements where the switch value is abstract and one or more cases throw

Resolves #1838

When only some of the cases in a switch statement throws, the join results in a possibly normal completion and this has to get composed with the saved completion.

The test case also revealed that the join was happening in the wrong order, so that is fixed as well.
Closes https://github.com/facebook/prepack/pull/1844

Differential Revision: D7861034

Pulled By: hermanventer

fbshipit-source-id: f4a8614e1f8769f942018345e2e1024d8013cf67
2018-05-03 11:51:00 -07:00
Herman Venter
838c26d7a0 Fix _WrapAbstractInObject to deal with mixed primitive types
Summary:
Release note: Fixed bug with implicitly converting unknown values to Object

Resolves #1845

Joined values can be of type PrimitiveValue, so the invariant in the default case of the switch in _WrapAbstractInObject is actually not true.

Added handling for this case, throwing an error if the joined value might be null, undefined or missing and converting it lazily to Object otherwise.
Closes https://github.com/facebook/prepack/pull/1849

Differential Revision: D7853117

Pulled By: hermanventer

fbshipit-source-id: eb8e8d85c13f9eee4320badb2209c5581f27ef0c
2018-05-02 18:35:51 -07:00
Sebastian Markbage
71248cd967 Follow up to UpdateExpression
Summary:
Follow up to #1839

It's not safe to mutate an expression in a build function. Those needs to be emitted as statements.

We don't have to deal with the assignment part of it though. We can just calculate the new value and deal with the fact that ToNumber might throw or mutate.

The new value we can just pass to PutValue which takes care of the rest.
Closes https://github.com/facebook/prepack/pull/1847

Differential Revision: D7853622

Pulled By: sebmarkbage

fbshipit-source-id: 1e370c2961048f5ce22becb7385a84b92ecc7045
2018-05-02 17:04:06 -07:00
Herman Venter
41817e5915 Do not apply joined generators in incorporateSavedCompletion
Summary:
Release note: Fixed code duplication bug

Issue: #1829

When joining up a saved possibly abrupt completion with the current completion (in Functions.incorporateSavedCompletion), the state must be updated with the effects of the normal part of the join. The normal part of the join does not include the joined generator, so that must be explicitly excluded when applying the effects.

The subtle reason for this is that the type of join point is only known to the caller of incorporateSavedCompletion and, depending on the type of join point, some parts of the joined completion may be excised from the join and put back into a saved completion. This means that only the caller knows exactly which parts of the abrupt completions should have their effects (and generators) reflected in the current state.
Closes https://github.com/facebook/prepack/pull/1834

Differential Revision: D7848979

Pulled By: hermanventer

fbshipit-source-id: 80e61692ea8f3b57930b5125178b560fa3d47af5
2018-05-02 13:30:25 -07:00
Dominic Gannaway
3d86c16d30 Support abstract temporal fall back in UpdateExpression
Summary:
Release notes: Adds pure scope support for abstract arguments with UpdateExpression

Whilst trying to get more things to inline with the React compiler, I ran into `UpdateExpression` again. Specifically, where throwing a FatalError won't help – as the expression is at the root/body of a function that has no fallback. So digging into it, when in pure scope, we can assume that there will be no effectual `toString` on the `AbstractValue` – so we can emit a temporal to the generator body and havoc the abstract value.

With this PR applied, we can do further inlining. Here's the Hacker News benchmark (test included):

```jsx
(function() {

const React = require('React');
const PropTypes = require('PropTypes');
// the JSX transform converts to React, so we need to add it back in
this['React'] = React;

if (!this.__evaluatePureFunction) {
  this.__evaluatePureFunction = function(f) {
    return f();
  };
}

module.exports = this.__evaluatePureFunction(() => {

  function timeAge(time) {
    const now = new Date(2042, 1, 1).getTime() / 1000;
    const minutes = (now - time) / 60;

    if (minutes < 60) {
      return Math.round(minutes) + ' minutes ago';
    }
    return Math.round(minutes / 60) + ' hours ago';
  }

  function getHostUrl(url) {
    return (url + '').replace('https://', '').replace('http://', '').split('/')[
      0
    ];
  }

  function Story({story, rank}) {
    return (
      <React.Fragment>
        <tr className="athing">
          <td
            style={{
              verticalAlign: 'top',
              textAlign: 'right',
            }}
            className="title">
            <span className="rank">{rank}.</span>
          </td>
          <td
            className="votelinks"
            style={{
              verticalAlign: 'top',
            }}>
            <center>
              <a href="#">
                <div className="votearrow" titl="upvote" />
              </a>
            </center>
          </td>
          <td className="title">
            <a href="#" className="storylink">{story.title}</a>
            {story.url
              ? <span className="sitebit comhead">
                  {' ('}<a href="#">{getHostUrl(story.url)}</a>)
                </span>
              : null}
          </td>
        </tr>
        <tr>
          <td colSpan="2" />
          <td className="subtext">
            <span className="score">{story.score + ' points'}</span>
            {' by '}
            <a href="#" className="hnuser">{story.by}</a>
            {' '}
            <span className="age">
              <a href="#">{timeAge(story.time)}</a>
            </span>
            {' | '}
            <a href="#">hide</a>
            {' | '}
            <a href="#">{story.descendants || 0 + ' comments'}</a>
          </td>
        </tr>
        <tr
          style={{
            height: 5,
          }}
          className="spacer"
        />
      </React.Fragment>
    );
  }

  Story.propTypes = {
    story: PropTypes.shape({
      title: PropTypes.string,
      url: PropTypes.string,
      score: PropTypes.number,
      descendants: PropTypes.number,
      by: PropTypes.string,
      time: PropTypes.number,
    }),
    rank: PropTypes.number,
  };

  function StoryList({stories}) {
    return (
      <tr>
        <td>
          <table cellPadding="0" cellSpacing="0" className="itemlist">
            <tbody>
              {
                // we use Array.from to tell the compiler that this
                // is definitely an array object
                Array.from(stories).map((story, i) => (
                  <Story story={story} rank={++i} key={story.id} />
                ))
              }
            </tbody>
          </table>
        </td>
      </tr>
    );
  }

  function HeaderBar(props) {
    return (
      <tr style={{backgroundColor: '#222'}}>
        <table
          style={{
            padding: 4,
          }}
          width="100%"
          cellSpacing="0"
          cellPadding="0">
          <tbody>
            <tr>
              <td style={{width: 18, paddingRight: 4}}>
                <a href="#">
                  <img
                    src="logo.png"
                    width="16"
                    height="16"
                    style={{
                      border: '1px solid #00d8ff',
                    }}
                  />
                </a>
              </td>
              <td style={{lineHeight: '12pt'}} height="10">
                <span className="pagetop">
                  <b className="hnname">{props.title}</b>
                  <a href="#">new</a>
                  {' | '}
                  <a href="#">comments</a>
                  {' | '}
                  <a href="#">show</a>
                  {' | '}
                  <a href="#">ask</a>
                  {' | '}
                  <a href="#">jobs</a>
                  {' | '}
                  <a href="#">submit</a>
                </span>
              </td>
            </tr>
          </tbody>
        </table>
      </tr>
    );
  }

  HeaderBar.defaultProps = {
    title: 'React HN Benchmark',
  };

  class AppBody extends React.Component {
    render() {
      return (
        <React.Fragment>
          <HeaderBar />
          <tr height="10" />
          <StoryList stories={this.props.stories} limit={this.props.storyLimit} />
        </React.Fragment>
      );
    }
  }

  AppBody.defaultProps = {
    storyLimit: 10,
  };

  function App({stories}) {
    return (
      <center>
        <table
          id="hnmain"
          border="0"
          cellPadding="0"
          cellSpacing="0"
          width="85%"
          style={{
            backgroundColor: '#f6f6ef',
          }}>
          <tbody>
            {stories.length > 0 ? <AppBody stories={stories} /> : null}
          </tbody>
        </table>
      </center>
    );
  }

  App.getTrials = function(renderer, Root, data) {
    let results = [];
    renderer.update(<Root stories={data} />);
    results.push(['clone element (true)', renderer.toJSON()]);

    return results;
  };

  App.propTypes = {
    stories: PropTypes.array.isRequired,
  };

  if (this.__optimizeReactComponentTree) {
  	__optimizeReactComponentTree(App);
  }

  return App;
});

})();
```

Here is after using `createElement` output and with Google Closure Compiler then Prettier run on the output. As you can see, it's inlined all the components into a single functional component and hoisted out a large amount of completely static ReactElement nodes.

```jsx
(function() {
  var Q = require("React"),
    m = this.Object.assign,
    R = this.Array.from,
    S = require("React").createElement,
    f = function(p, f) {
      var b = p.stories,
        e = 0 < m(b).length;
      b = R(b).map(function(p, b) {
        var e = ++b,
          d = m(p),
          n = d.title,
          l = d.url;
        if (l) {
          var c = (d.url + "").replace("https://", "");
          m(c);
          c = c.replace("http://", "");
          m(c);
          c = c.split("/");
          var g = m(c)["0"];
        }
        var f = d.score + " points",
          k = d.by;
        c = 2274825600 - d.time;
        d = d.descendants;
        e = a("span", { className: "rank" }, e, ".");
        e = a(
          "td",
          {
            style: { verticalAlign: "top", textAlign: "right" },
            className: "title"
          },
          e
        );
        if (void 0 === q) {
          var h = a;
          q = h("div", { className: "votearrow", titl: "upvote" });
          u = h("a", { href: "#" }, q);
          v = h("center", null, u);
          w = h(
            "td",
            { className: "votelinks", style: { verticalAlign: "top" } },
            v
          );
          x = h("td", { colSpan: "2" });
          y = h("a", { href: "#" }, "hide");
          z = h("tr", { style: { height: 5 }, className: "spacer" });
        }
        n = a("a", { href: "#", className: "storylink" }, n);
        g = a("a", { href: "#" }, g);
        g = a("span", { className: "sitebit comhead" }, " (", g, ")");
        l = a("td", { className: "title" }, n, l ? g : null);
        l = a("tr", { className: "athing" }, e, w, l);
        f = a("span", { className: "score" }, f);
        k = a("a", { href: "#", className: "hnuser" }, k);
        c /= 60;
        n = Math.round(c);
        g = Math.round(c / 60);
        c = a(
          "a",
          { href: "#" },
          60 > c ? n + " minutes ago" : g + " hours ago"
        );
        c = a("span", { className: "age" }, c);
        d = a("a", { href: "#" }, d || "0 comments");
        d = a(
          "td",
          { className: "subtext" },
          f,
          " by ",
          k,
          " ",
          c,
          " | ",
          y,
          " | ",
          d
        );
        d = a("tr", null, x, d);
        return a(r.Fragment, null, l, d, z);
      });
      void 0 === k && T(a);
      b = a("tbody", null, b);
      b = a(
        "table",
        { cellPadding: "0", cellSpacing: "0", className: "itemlist" },
        b
      );
      b = a("td", null, b);
      b = a("tr", null, b);
      b = a(r.Fragment, null, A, B, b);
      e = a("tbody", null, e ? b : null);
      e = a(
        "table",
        {
          id: "hnmain",
          border: "0",
          cellPadding: "0",
          cellSpacing: "0",
          width: "85%",
          style: { backgroundColor: "#f6f6ef" }
        },
        e
      );
      return a("center", null, e);
    },
    t = function() {},
    r = Q;
  React = r;
  f.getTrials = _2J;
  t.isRequired = t;
  f.propTypes = { stories: t };
  var a = S,
    q,
    u,
    v,
    w,
    x,
    y,
    z,
    T = function(a) {
      k = a("img", {
        src: "logo.png",
        width: "16",
        height: "16",
        style: { border: "1px solid #00d8ff" }
      });
      C = a("a", { href: "#" }, k);
      D = a("td", { style: { width: 18, paddingRight: 4 } }, C);
      E = a("b", { className: "hnname" }, "React HN Benchmark");
      F = a("a", { href: "#" }, "new");
      G = a("a", { href: "#" }, "comments");
      H = a("a", { href: "#" }, "show");
      I = a("a", { href: "#" }, "ask");
      J = a("a", { href: "#" }, "jobs");
      K = a("a", { href: "#" }, "submit");
      L = a(
        "span",
        { className: "pagetop" },
        E,
        F,
        " | ",
        G,
        " | ",
        H,
        " | ",
        I,
        " | ",
        J,
        " | ",
        K
      );
      M = a("td", { style: { lineHeight: "12pt" }, height: "10" }, L);
      N = a("tr", null, D, M);
      O = a("tbody", null, N);
      P = a(
        "table",
        {
          style: { padding: 4 },
          width: "100%",
          cellSpacing: "0",
          cellPadding: "0"
        },
        O
      );
      A = a("tr", { style: { backgroundColor: "#222" } }, P);
      B = a("tr", { height: "10" });
    },
    k,
    C,
    D,
    E,
    F,
    G,
    H,
    I,
    J,
    K,
    L,
    M,
    N,
    O,
    P,
    A,
    B;
  module.exports = f;
}.call(this));
```
Closes https://github.com/facebook/prepack/pull/1839

Differential Revision: D7846721

Pulled By: trueadm

fbshipit-source-id: 761aab09721d05050ea8e71721cebb5ecdf371ee
2018-05-02 12:07:32 -07:00
Nikolai Tillmann
005bc1fa90 Aligning serializer with visitor for modified object properties
Summary:
Release notes: None

This fixes #1820.

Adding regression test.
Closes https://github.com/facebook/prepack/pull/1825

Differential Revision: D7845744

Pulled By: NTillmann

fbshipit-source-id: bd45ea0ae814fc585f1f3e1cb9013d8215021e80
2018-05-02 10:53:59 -07:00
Dominic Gannaway
057e48c96a Tidies up the React mock logic + ReactDOM mocks + few tweaks
Summary:
Release notes: adds ReactDOM mocks to fb-www compatibility mode

This PR aims to do a bunch of things:
- Tidy up the spaghetti React mock logic by adding in some helper functions
- Add ReactDOM mocks, pathing the way for greater optimizations for first render
- Swap the `Get` to a `getProperty` in `isReactElement` function
- Make the fb-www mocks not ignored by eslint and fix the eslint issues after doing so
Closes https://github.com/facebook/prepack/pull/1835

Differential Revision: D7845112

Pulled By: trueadm

fbshipit-source-id: 7173c543da6af2c20a38fbc70f962825647f8f3e
2018-05-02 09:08:00 -07:00
Dominic Gannaway
4fcc238259 Ensure we visit ReactLibrary with React.Fragment usage
Summary:
Release notes: none

This PR ensures we visit the React library when `React.Fragment` is used in a ReactElement. Fixes https://github.com/facebook/prepack/issues/1831.
Closes https://github.com/facebook/prepack/pull/1836

Differential Revision: D7844218

Pulled By: trueadm

fbshipit-source-id: 58d9391ee8ef8acc1363c74b66de8ad5f792657e
2018-05-02 07:41:45 -07:00
Herman Venter
72994a6851 Generalize temporal unknown property assignments
Summary:
Release note: Support multiple assignments to unknown properties in optimized functions

Issue #1818.

The code in #1822 can only deal correctly with a single assignment. This generalizes that code to generate separate assignments for each different (key, value) pair found in the conditional value tree that is used to model a group of assignments to unknown properties of known objects.
Closes https://github.com/facebook/prepack/pull/1828

Differential Revision: D7840880

Pulled By: hermanventer

fbshipit-source-id: 8f2bb12cfd5246dc13d5a360ff9bb16a9326dd41
2018-05-01 19:24:58 -07:00
Herman Venter
c3a1fd3c46 Special handling for temporal assignments to unknown properties
Summary:
Release note: Support temporal assignment to object properties using unknown property names

Resolves issue: #1818

There was no code for dealing with assignments using unknown property names that showed up in generator entries.
Closes https://github.com/facebook/prepack/pull/1822

Differential Revision: D7833068

Pulled By: hermanventer

fbshipit-source-id: 2c3e8d211bd4770ba736ff9be03a0f4d85adad34
2018-05-01 13:10:49 -07:00
Dominic Gannaway
ee1b47625a Extend invariant check in AbstractObjectValue
Summary:
Release notes: none

This PR fixes https://github.com/facebook/prepack/issues/1819. It expands on the existing invariant check in `AbstractObjectValue` by also allowing abstract object values to pass through.
Closes https://github.com/facebook/prepack/pull/1824

Differential Revision: D7829938

Pulled By: trueadm

fbshipit-source-id: 7e198bc626b4fd2737d0ef9d2a7207bd17b0b02a
2018-05-01 09:19:01 -07:00
Nikolai Tillmann
065fa2765b Refine type of PropertyBinding.key
Summary:
Release notes: None

This fixes #1771.

The `PropertyBinding` `key` type used to be just `any`; not sure what the historical story here is,
but the visitor was unaware that this in fact could be an `AbstractValue` as well as a `string`.
This meant that some keys might not get visited when they should have been.

This refines the key type and accounts for the different possible types in all referencing places.
Closes https://github.com/facebook/prepack/pull/1816

Differential Revision: D7827049

Pulled By: NTillmann

fbshipit-source-id: 88fa2e036d1d4393d025af38954e309f6632a839
2018-04-30 22:10:52 -07:00
Herman Venter
ec1b83eb29 Do not simplify c ? NaN : y to y if the path implies (c ? NaN : y) !== NaN.
Summary:
Release note: Fixes simplification bug involving comparisons with NaN

Issue: #1790

Simplification operations that reduce conditional expressions based on inequalities, must guard agains comparisons with NaN.
Closes https://github.com/facebook/prepack/pull/1815

Differential Revision: D7824224

Pulled By: hermanventer

fbshipit-source-id: 34249c8597bb44421742919737f74ca93e2035e5
2018-04-30 18:10:42 -07:00
Herman Venter
6ee4ca00d4 Always apply effects before combining their results with saved_result
Summary:
Release note: Resolves issues with outer declarations moving into nested scopes

Issue: #1808

The fix identified in #1805, needs to be applied in a number of other contexts as well.
Closes https://github.com/facebook/prepack/pull/1813

Differential Revision: D7821306

Pulled By: hermanventer

fbshipit-source-id: dd08198f5d031c2e368bf5da179c2a11ac0f3b3a
2018-04-30 15:40:17 -07:00
Dominic Gannaway
4302d24e51 Add a evaluateForEffectsWithPriorEffects to Realm
Summary:
Release notes: none

This should fix https://github.com/facebook/prepack/issues/1803 and extends from the unsuccessful attempts made in https://github.com/facebook/prepack/pull/1809 to fix this.

When we apply the `priorEffects` inside of the `evaluateForEffects` on TryStatement, we have to ensure that the `canBeApplied` flag is reset (as the bindings on the Realm get restored by `evaluateForEffects`).
Closes https://github.com/facebook/prepack/pull/1811

Differential Revision: D7820907

Pulled By: trueadm

fbshipit-source-id: 248cc0f21be0044de8641e79c5985c7259a88629
2018-04-30 15:40:16 -07:00
Dominic Gannaway
0c45892f45 isReactElement should check for type and props on the obj
Summary:
Release notes: none

This adds more validation that something definitely is a ReactElement, as found from the issue https://github.com/facebook/prepack/issues/1802. Unfortunately, the test in that case does not pass, it fails due to an invariant:

`Invariant Violation: an abstract value with an identifier "_$1" was referenced before being declared`
Closes https://github.com/facebook/prepack/pull/1810

Differential Revision: D7813932

Pulled By: trueadm

fbshipit-source-id: e431887002da83389da4062cfe00afbdc42d21c8
2018-04-30 10:49:37 -07:00
Nikolai Tillmann
acfae3870c Fixing mutations of objects-from-outer-scope in optimized functions.
Summary:
Release notes: None

This fixes #1789.

The visitor already computed the right scopes for all objects,
which the serializer then used to figure out in which code block
to emit an object.
However, the serializer didn't take into account that the wrong
effects might be applied when serializing values in a simple
recursive manner, finding an object from an outer scope while
serializing an optimized function.
To fix this, (re-)introduce an additional roots set which is used
to ensure that all objects belonging to an outer scope get serialized
before we enter an additional function where effects might get applied.

Adding regression test case.
Closes https://github.com/facebook/prepack/pull/1794

Differential Revision: D7814388

Pulled By: NTillmann

fbshipit-source-id: 5709fcd676b9b86dd66b2952155039d09d873a70
2018-04-30 09:55:19 -07:00
Dominic Gannaway
0f60e8c220 Write conflicts possibly normal completions
Summary:
Release notes: none

When digging deeper into detecting write conflicts with React component trees, I found that PossiblyNormalCompletions were not handled properly, so this PR ensures that the effects tree is recursively traversed so all modified bindings are collected, even from PossiblyNormalCompletions.

Update:
With all the latest changes, all tests in this PR now pass, so it's ready to be reviewed again.
Closes https://github.com/facebook/prepack/pull/1742

Differential Revision: D7813778

Pulled By: trueadm

fbshipit-source-id: 425ec505709c83081c7eef3bec9bf95bd651299e
2018-04-30 08:20:39 -07:00
Dominic Gannaway
fb6d352f46 Fixes an issue in the React reconciler when dealing with abstract values
Summary:
Release notes: none

This PR fixes an issue where the React reconciler incorrectly assumed that `createFromConditionalOp` always returned an `AbstractValue`. This changes that and adds the failing test for a regression test.

Fixes https://github.com/facebook/prepack/issues/1804.
Closes https://github.com/facebook/prepack/pull/1807

Differential Revision: D7813026

Pulled By: trueadm

fbshipit-source-id: 5af963fb0e2351d073df554cda33b979d52c9e60
2018-04-30 06:09:09 -07:00
Nikolai Tillmann
3fb0ee1a7b Ensure that the right effects are applied when visiting bindings.
Summary:
Release notes: None

This fixes #1798, and it almost fixes #1797 by reducing it to #1799, and it unblocks #1794.

When the visitor looks at (initial) function bindings, it does so with additional functions still applied if that additional function happens to be the first thing that pull on the function value.
This is being fixed, as well as generally turning _withScope uses into _enqueueWithUnrelatedScope calls which ensure that the right effects are in place.

Added additional output to the serializer runner - it now shows a summary of which tests failed, ordered by their size.

Added regression test.
Closes https://github.com/facebook/prepack/pull/1806

Differential Revision: D7805532

Pulled By: NTillmann

fbshipit-source-id: 274859e9f6f74ebfc4decc37d984cedcbedf990c
2018-04-28 08:54:20 -07:00
Dominic Gannaway
555e18bb62 Provide better abstract function hints for arrays
Summary:
Release notes: none

This PR provides a mechanism for the React reconciler to understand newly created arrays from maps with unknown properties, in this this first case this is only for `Array.from`, `Object.keys`, `Array.prototype.map`, `Array.prototype.filter`, `Array.prototype.reduce` (with constraints), `Array.prototype.slice` and `Array.prototype.concat`.

When we have something completely abstract, like `props.items`, and it's been wrapped in `Array.from`, we can assume that (in a pure render) that it's safe to emit the `Array.from` and make the array with an unknown property that is an abstract widened hint. The reconciler can see this and perform a nested optimized closure to the map callback.

In cases where the third argument `thisVal` is passed to array methods, we bail-out.
Closes https://github.com/facebook/prepack/pull/1770

Differential Revision: D7795295

Pulled By: trueadm

fbshipit-source-id: 3396330da6d4ebe2ffdd1f1610173eb482df9081
2018-04-27 13:19:57 -07:00
Herman Venter
30876d5bec Special case switch over abstract value with known values domain
Summary:
Release note: none

Addresses issue: #1763

If the abstract selector value of a switch statement has a known values domain and ranges over a small set of values, we can generate better code by not having to join up all the case blocks in the switch.
Closes https://github.com/facebook/prepack/pull/1786

Differential Revision: D7792997

Pulled By: hermanventer

fbshipit-source-id: 147f52ad666f2617a8e16c3d7363341742adf2f9
2018-04-27 11:46:13 -07:00
Herman Venter
a2a5d60fc2 Keep generator entries that do not come from joins
Summary:
Release note: none

Fixes issue: #1766

Generators that result from joining two blocks of code have lots of entries that are the joins of the generators of the individual blocks. When generating code for optimized functions, these entries need to get ignored since they will be visited while recursing through the top level result. That much was achieved with the PR #1758.

That turned out to be too simplistic since joined generator entries can get appended into generators with existing entries. This PR restores visiting generators from effects with joined results, but purges them of entries that resulted from the join.

This is somewhat brittle and we need to revisit the entire generator design at some point, but this PR gets us unblocked and does seem to make things strictly better.
Closes https://github.com/facebook/prepack/pull/1795

Differential Revision: D7787380

Pulled By: hermanventer

fbshipit-source-id: 23e8924282cfdabf77969ff716ac936c12daa6ad
2018-04-26 23:36:53 -07:00
Nikolai Tillmann
922ac349e9 Don't emit object property modifications to dead objects.
Summary:
Release notes: None

This fixes #1772.

When an optimized function modifies properties of objects
created outside of its scope, we can omit such property modifications
if the modified object is not used.
This nicely fits in with the fixed point model of the visitor.
(The objects involved in object property modification used to complete bypass the whole visiting process, resulting in the crash.)
Note that as a positive side effect certain double-mutation errors won't be issued to the user.

Added simple regression test.

Manually verified that this also makes the larger React test mentioned in the issue pass.

Also fixed ordering ordering of effects applications when processing queue in residual heap visitor. This bug existed for a while, but was only brought out by the existing serializer tests after the more aggressive queueing of modified object property binding visitng.
Closes https://github.com/facebook/prepack/pull/1793

Differential Revision: D7784644

Pulled By: NTillmann

fbshipit-source-id: 3dd21cc89275a30c5312f7bdd94e7d0364d02959
2018-04-26 22:41:06 -07:00
Nikolai Tillmann
94245b1d14 Fixing equals
Summary:
Fixing equals() on Values

Release notes: None

I found the following bugs in equals():
- For numbers, it didn't take into account NaN.
- For symbols, it was too optimistic.
And for objects, it was overly complicated.

Adding regression test for symbols. Could produce a regression test for numbers, but file a related issue for NaN values.
Closes https://github.com/facebook/prepack/pull/1791

Differential Revision: D7784665

Pulled By: NTillmann

fbshipit-source-id: 96bdcce6c771c8549dc52cd73c646d0e15b5b9b0
2018-04-26 22:41:06 -07:00
Herman Venter
d2446b8de0 Promote empty to undefined for optimized function return values
Summary:
Release note: none

EmptyValue is a signal that the property that (might) have the value could in fact not actually be there. This matters when constructing objects at runtime, since code has to be emitted to deal with the case where the property will not be created at all, due to a runtime switch.

On the other hand, when the value of a missing property is *used*, it should be the undefined value. For that scenario, there is a promoteEmptyToUndefined on Value and this should be called before serializing empty values that are actually used.

This was not done for values returned from optimized functions. This PR plugs that hole.
Closes https://github.com/facebook/prepack/pull/1787

Differential Revision: D7776331

Pulled By: hermanventer

fbshipit-source-id: ebf8f5335e8ed3f6c557e00f3c88b08ccbd9c14d
2018-04-26 14:22:20 -07:00
Dominic Gannaway
d38f0570c2 Fixes a bunch of serialization bugs
Summary:
Release notes: none

This PR came about from trying to fix https://github.com/facebook/prepack/issues/1771. This PR fails on the tests still, so I need some help getting them resolved.

- `_emitProperty` should account for the fact a `key` can be an `AbstractValue`, thus needs to serialize the value.
- `visitObjectPropertiesWithComputedNames` in the visitor and `_getNestedAbstractValues` in the serializer both need to take into account cases where `alternate` and `consequent` might not be `AbstractValue`s.
Closes https://github.com/facebook/prepack/pull/1781

Differential Revision: D7777483

Pulled By: trueadm

fbshipit-source-id: 1b94489ec9c800a68414031e0bc63b06061fe559
2018-04-26 14:22:19 -07:00
Herman Venter
de52327593 Handle abstract conditional break inside definite for loop
Summary:
Release note: Allow break/continue to be guarded by abstract conditions inside loops

This addresses the first example in issue: #1764

Loops represent join points for break and continue completions. They need to be handled much like the return completions that join at function end. The main difficulty is that break and continue can specify a target. For now, we punt on that and give a compile time error.
Closes https://github.com/facebook/prepack/pull/1778

Differential Revision: D7762824

Pulled By: hermanventer

fbshipit-source-id: d8d3699277b7bb20817a27ecc24f3c503904fc74
2018-04-26 01:58:46 -07:00
Dominic Gannaway
9e5cc34819 Fixes an issue with getDerivedStateFromProps
Summary:
Release notes: none

When doing `Object.assign` in `getDerivedStateFromProps`, we need to add back in the fallback for when it might fail otherwise we end up triggering invariants. This fixes https://github.com/facebook/prepack/issues/1773
Closes https://github.com/facebook/prepack/pull/1780

Differential Revision: D7773190

Pulled By: trueadm

fbshipit-source-id: 2539f01cfde3a65136a6e9947a4620dfc81a371a
2018-04-26 01:58:46 -07:00
Dominic Gannaway
fc371688e9 Fix hoisting invariant bug
Summary:
Release notes: none

There was a case where an invariant was firing in the hoisting logic due to a binding value being undefined. This PR stops the invariant from firing in such cases, and includes the regression test. I also found another issue in the evaluatedReactNode debugging output and fixed that too so it was easier to see what was going on with this and other issues.

This fixes https://github.com/facebook/prepack/issues/1775
Closes https://github.com/facebook/prepack/pull/1779

Differential Revision: D7763057

Pulled By: trueadm

fbshipit-source-id: 61c866f7cb7322f5d884262adb85613c97cfa4ca
2018-04-26 01:58:46 -07:00
Dominic Gannaway
d12bcef03e Better handling of this with simple React class components
Summary:
Release notes: none

This fixes bugs around detecting independent dangling `this` keywords in methods of a React class component and correctly bailing out upon finding them. This is typically used in cases where we'd want to bail out, for example:

```js
let self = this;
let handleClick = function () { console.log(self.x) };
return <div onClick={handleClick} />
```

or:

```js
let handleClick = function () { console.log(this.x) };
return <div onClick={handleClick.bind(this)} />
```
Closes https://github.com/facebook/prepack/pull/1777

Differential Revision: D7757435

Pulled By: trueadm

fbshipit-source-id: b06fe29a3ac4a44bdf2b8a7c6e9457e5801b32b7
2018-04-25 04:59:14 -07:00
Herman Venter
64ee2744ee Capture prefix effects when composing pnc
Summary:
Release note: none

When composing a newly constructed PossiblyNormalCompletion with saved one, the resulting completion needs to capture the effects that happened on the normal branch, in between the saved fork point and the fork point of the newly constructed completion, because these effects also apply to the abrupt part of the new completion.

When joining up such a composed completion, the effects need to be applied (and later reversed), otherwise the nested joins might capture values as they were before the first fork, rather than as there were at the time of the nested fork.
Closes https://github.com/facebook/prepack/pull/1769

Differential Revision: D7746284

Pulled By: hermanventer

fbshipit-source-id: d2396f29f93c676e330ac6460f5ac9e638329528
2018-04-24 11:57:49 -07:00
Dominic Gannaway
b798f32ef2 Fold Relay components via createFragmentContainer for firstRenderOnly
Summary:
Release notes: none

This adds the functionality to fold/inline ReactRelay components via `createFragmentContainer`. This is for first-render only for now.
Closes https://github.com/facebook/prepack/pull/1745

Differential Revision: D7686225

Pulled By: trueadm

fbshipit-source-id: 7eb546ff70e92b60bcc1abb69c0cc5091926c012
2018-04-19 14:14:26 -07:00
Nikolai Tillmann
dee52a104a Fixes mismatch between visitor and serializer.
Summary:
Release notes: None

The serializer used simply invoke the serialization
machinery for the special empty value when it was
trying to generate code for a possibly-deleted property.
However, there was no matching visiting of the special empty value.

This fixes issue #1747.

Adding regression test case.
Closes https://github.com/facebook/prepack/pull/1751

Differential Revision: D7672464

Pulled By: NTillmann

fbshipit-source-id: 60b2e4eb4246abb61d2361b8ef88d293de021ef5
2018-04-19 12:32:49 -07:00
Herman Venter
2b1bf611db Do not emit joined generators into optimized function bodies
Summary:
Release note: none

Joining effects results in joined generators that contain all of the I/O operations of the argument effects, but does not change the arguments.

Normally, this does not matter because only the joined generator is used. In the case of an optimized function, however, the generator tree is traversed via the effects tree and this resulted in duplicate I/O operations.

To fix this, the tree walk now ignores joined generators. Also included in this PR, some fixes to make sure that only the (joined) effects resulting from _createAdditionalEffects are used, and not the effects that went into it.
Closes https://github.com/facebook/prepack/pull/1758

Differential Revision: D7687328

Pulled By: hermanventer

fbshipit-source-id: c3a333369bc403bed5f986e5d9d59cc56ab62ced
2018-04-19 10:30:32 -07:00
Dominic Gannaway
d72ce06580 Support null/undefined config object for React.createElement
Summary:
Release notes: none

When a `null` or `undefined` value is passed as the `config` for `createElement`, then we need to create an empty object to be used instead.
Closes https://github.com/facebook/prepack/pull/1759

Differential Revision: D7686087

Pulled By: trueadm

fbshipit-source-id: a8eb917f38ca3afe881af08d07fe8be0943b0a1f
2018-04-19 07:08:41 -07:00
Dominic Gannaway
d109852ffa Ensure we apply nested closure effects in the right order
Summary:
Release notes: none

Ensure we apply the nested closure effects in the right order. This was the underlying bug after doing much digging.

Furthermore, I added case where this fails. I also found that the ReactElement code was causing issues at one point (I forgot to add the props, type, ref and key as dependencies), but that wasn't needed in the end for this fix, but I thought it best to keep those fixes in.

I also had to make a change to the JSON tester as it was incorrectly failing a test because the function closures were not 1:1, which they're not meant to be.
Closes https://github.com/facebook/prepack/pull/1743

Differential Revision: D7686048

Pulled By: trueadm

fbshipit-source-id: 8cf7faed51c86720e519abbbad209820e7e02dc4
2018-04-19 07:08:40 -07:00
Herman Venter
28fd420e29 Use actual location as cache key if available
Summary:
Release note: none

I noticed that the stack properties for Error objects were being set to the same value even when the objects were constructed in separate lines.

It turns out that some recent caching logic used the containing function as key and thus unified all error location descriptions encountered in the same function to a single value. So part of this PR is just a fix that uses the actual location, if available, as the cache key.

This unmasked another recently introduced problem: There are now invariant checks that happen if you get a property from the global object. The function where the checks are triggered is called as part of the describe logic. This logic was largely disabled because of the caching bug, so the checks did not fire in any test case and we missed out on the fact that the check don't work if the property get logic is not part of the source program.

To fix that, all calls to $Get that are done for internal purposes have now been replaced by calls to _SafeGetDataPropertyValue.
Closes https://github.com/facebook/prepack/pull/1755

Differential Revision: D7683687

Pulled By: hermanventer

fbshipit-source-id: 1c811fffc6ecf275f5fabd75afbd9e8cfc051247
2018-04-18 22:10:38 -07:00
Herman Venter
abd21cf0bb Preserve order of joined throw completions at function end
Summary:
Release note: none

The code for disentangling return completions from throw completions uses a recursive algorithm that caused the throw completions to get reversed. Fix this to prepend rather than append so that the order comes out right.

This is also an opportunity to not mess with the path conditions.
Closes https://github.com/facebook/prepack/pull/1752

Differential Revision: D7676676

Pulled By: hermanventer

fbshipit-source-id: f10326e21bdf3f15c2ddf7eac02ef02cf8d155d3
2018-04-18 16:12:56 -07:00
Herman Venter
d4268fd58c Join JoinedAbruptCompletions when optimizing functions.
Summary:
Release note: none

The effects constructed for an optimized function must join all paths that may leave the function in order to provide a full accounting of what the function might do to the global environment. Without this, the global environment can get polluted by side effects in the abrupt branches, because these effects are applied to the environment when constructing the generator from the overall effects, but are not reversed when backing out the overall effects.

This can break things in many different ways, one of which is illustrated in the modification of return-or-throw-simple.js, where the last return x is serialized as undefined rather than the abstract value, because x got polluted during the construction of the effects for func1.
Closes https://github.com/facebook/prepack/pull/1749

Differential Revision: D7664313

Pulled By: hermanventer

fbshipit-source-id: 3b061d16a4f38918f461b792b660954332ae6fa7
2018-04-17 19:40:31 -07:00
Nikolai Tillmann
089729fe94 Leverage generator's path conditions to reduce conditionals
Summary:
Release notes: Improved code generation in the presence of branching

This is fully implemented now:
- The visitor keeps track of whether the consequent or alternate of conditional values are feasible. If something is known to be infeasible, it is never visited.
- This in turn allows the serializer to skip serializing infeasible branches of conditional values.
- The emitter also knows that those infeasible branches are no dependencies.
- Added a test case for the basic functionality, one that shows that complex objects get eliminated, and one that tests the dependency code.
Closes https://github.com/facebook/prepack/pull/1697

Differential Revision: D7606266

Pulled By: NTillmann

fbshipit-source-id: 09bfe8c2a2838ebd252a93a98013b31158909d2f
2018-04-16 11:40:45 -07:00
Herman Venter
42cbfd9233 Make Generator._deconstruct complete
Summary:
Release note: none

Generator._deconstruct did not handle PossiblyNormalCompletion and was asymmetrical for ReturnCompletion. Fixed this and added a test case.

Also deleted a dead method.
Closes https://github.com/facebook/prepack/pull/1744

Differential Revision: D7624647

Pulled By: hermanventer

fbshipit-source-id: edf72696767cf23eaadfb27b5951f172c7a8275a
2018-04-13 16:46:26 -07:00
Dominic Gannaway
d811e0c567 Handle cases where gDSFP is given an abstract state
Summary:
Release notes: none

When working on internal projects, I found cases where the `getDerivedStateFromProps` would throw a FatalError because the partial state wasn't an abstract object value or object value. In this case we can see that the abstract value is a conditional and handle the paths to ensure we get the correct results without failing.
Closes https://github.com/facebook/prepack/pull/1737

Differential Revision: D7615094

Pulled By: trueadm

fbshipit-source-id: 5c868a46936a108c277ac52c2675feabc1f4df8c
2018-04-13 03:00:04 -07:00
Herman Venter
1ca37cb9ff Execute Do/While loop condition in the proper place
Summary:
Release note: Execute Do/While loop condition in the proper place

Fixes issue: #1677

The fixpoint computation computed the while condition of the first iteration as part of the second, and so on.

Refactored the code to make the fixed point computation independent of where the loop condition is executed. This simplifies things and will come in handy when doing while/do.
Closes https://github.com/facebook/prepack/pull/1741

Differential Revision: D7610522

Pulled By: hermanventer

fbshipit-source-id: 5a86b1ea179b5e03c773b642375b91ad3837d868
2018-04-12 20:17:09 -07:00
Nikolai Tillmann
764641ad6d Clean up of visiting bindings
Summary:
Release notes: None

This fixes an internal test failure.

Changes:
- (Re)Visit bindings in the right function scope
- No longer mutate the binding's value field after it's initialized once
- Don't visit/serialize old binding value when it's not needed - adding test case for that
- Delete unnecessary getModifiedBindingOldValues function; whatever it was needed for can be done as part of visitModifiedBinding.
- Delete some code that performed special handling for bindings referring to functions. Doesn't seem to be needed.
Closes https://github.com/facebook/prepack/pull/1733

Differential Revision: D7607978

Pulled By: NTillmann

fbshipit-source-id: faa45963753408a35015ce8c57009cc287d53624
2018-04-12 17:21:36 -07:00
Nikolai Tillmann
62672e69d7 Don't generate redundant calls to query captured scopes
Summary:
Release notes: None

Don't generate redundant calls of the form
`var __captured__scope_2 = __scope_0[0] || __scope_1(0);`

Adding regression test.

This addresses one of the observations of #1732.
Also deleted unneeded left-over code and comment that used to refer #989.
Closes https://github.com/facebook/prepack/pull/1734

Differential Revision: D7602949

Pulled By: NTillmann

fbshipit-source-id: 77d926b236a903eb7927a1471411e8397a0d192a
2018-04-12 12:10:53 -07:00
Nikolai Tillmann
7579c5fc0b Introducting new option --invariantLevel NUMBER and dropping --omitInvariants
Summary:
Release notes: Introducting new option --invariantLevel NUMBER and dropping --omitInvariants

The new default is invariant level 0, which corresponds to the old --omitInvariants.
Level 1 is roughly what we used to do: Check invariants on (derived) abstract values.
Level 2 implements #1180: Checking that all accesses to built-ins do what Prepack expects them to do, including checks for when properties on built-ins are absent.
Level 3 adds checks for internal consistency, basically an internal debug level.

The serializer tests now run with the highest invariant level by default. The added invariants found a few issues that got addressed, including:
- Prepack exposes a TypedArray prototype, which is not a real thing. It's now marked as `__refuseSerialization`, and no invariants are emitted for such things.
- Global variables / properties on the global object are special. Those are not yet handled at level 2.
- Accesses to Prepack magic functions that generally start with `__` should not produce invariant checks.
- Magic code generation for loops should not take into account objects that are `__refuseSerialization`.
- All invariant statements get a unique id to make it easier to locate them.
- I marked some test cases which depend on counting occurrences in the output as "// omit invariants", as the additional invariants increased some such counts.

As part of testing, I also found it necessary to make the --invariantMode more useful; it now also allows specifying nativeLoggingHook which is the preferred way of logging in React Native.

To reduce the number of checks by a few orders of magnitude in practice, each property is only checked on first access. This is tracked by a global variable `__checkedBindings`.

This pull requests incorporates all aspects of the #1709 (which I abandoned).
Closes https://github.com/facebook/prepack/pull/1724

Reviewed By: simonhj

Differential Revision: D7575091

Pulled By: NTillmann

fbshipit-source-id: 585cd224ce66882f8e5f27d88c1ad08afeb96ee1
2018-04-12 11:58:25 -07:00
Dominic Gannaway
cd30805c65 Ensure React component write effects do not conflict one another
Summary:
Release notes: none

This PR adds some sanity around React components roots that when render, mutate the same of bindings as other React component roots. This is currently not supported and thus safely bails out and continues.
Closes https://github.com/facebook/prepack/pull/1736

Differential Revision: D7600373

Pulled By: trueadm

fbshipit-source-id: fe2b2b3055fa3c1b28668da6d67bca3826431eb6
2018-04-12 09:55:14 -07:00
Dominic Gannaway
8264cfffd7 Adds createRef and forwardRef to the React compiler
Summary:
Release notes: Adds`createRef` and `forwardRef` to the React compiler

This PR adds both features from React 16.3, including full inlining of forwardRef functions.
Closes https://github.com/facebook/prepack/pull/1731

Differential Revision: D7599780

Pulled By: trueadm

fbshipit-source-id: 50458546c7a4374baea7fa80feb21262dd5692af
2018-04-12 06:34:44 -07:00
Dominic Gannaway
6ec280b8c8 Adds getDerivedStateFromProps support and updates React version deps
Summary:
Release notes: adds React 16.3 `getDerivedStateFromProps` support to the React compiler

This PR adds support for the React 16.3 `getDerivedStateFromProps` lifecycle event on class components. I've also updated the React testing dependencies to 16.3.1. I also extended the `componentWillMount` logic to support `UNSAFE_componentWillMount` too.
Closes https://github.com/facebook/prepack/pull/1730

Differential Revision: D7586378

Pulled By: trueadm

fbshipit-source-id: 895e74ca86eb9ff9ad04aa93f021c107f08a7b9f
2018-04-11 10:11:33 -07:00
Ariel Mashraki
5bbe3459ee Aggregate common captured scope cases
Summary:
Issues: #995, #1707
Closes https://github.com/facebook/prepack/pull/1721

Differential Revision: D7582788

Pulled By: a8m

fbshipit-source-id: 784189a77f987123069241fbac9dfccc90d0ce6a
2018-04-10 22:39:17 -07:00
Sapan Bhatia
74928ec0bf Compute minimal set of reachable values in the presence of WeakSet, WeakMap
Summary:
Dropped entries in WeakSet and WeakMap that are not referenced elsewhere from serialized output.

This addresses #680.
Closes https://github.com/facebook/prepack/pull/1710

Reviewed By: NTillmann

Differential Revision: D7573234

Pulled By: sb98052

fbshipit-source-id: 64c99b8ea979b3d39c77f80a50959f5534b65274
2018-04-10 19:58:27 -07:00
Herman Venter
57c80e3b6a Join all normal paths together for optimized functions
Summary:
Release note: none

The effects that get applied when serializing an optimized function should include the join of all the normal paths through the function, not just the common prefix.
Closes https://github.com/facebook/prepack/pull/1727

Differential Revision: D7578528

Pulled By: hermanventer

fbshipit-source-id: c2655bfaed30224eb63a27a3335fc239e4d3b86f
2018-04-10 16:53:06 -07:00
Dominic Gannaway
1af47e55e2 Internal bootloader changes
Summary:
Release notes: none

Some internal changes to ensure `Bootloader.loadModules()` global stays as is and doesn't get destructured. Also changed the incorrect usage of `context.$Realm.generator.derive` in the mocks.
Closes https://github.com/facebook/prepack/pull/1726

Differential Revision: D7578301

Pulled By: trueadm

fbshipit-source-id: dd7dce3e46ff01b10eb9206a1ed5d94871ae93fd
2018-04-10 16:10:50 -07:00
Sebastian Markbage
a41911ff76 Various Fixes to SetPartial + Set on abstract object
Summary:
This is the equivalent of #1680 but for assignments.

It's pretty much the same changes, except this one emits assignments.

I also had to implement assignment to topVal.
Closes https://github.com/facebook/prepack/pull/1703

Differential Revision: D7546923

Pulled By: sebmarkbage

fbshipit-source-id: d0e2c356496c009b7f5865ba69784556ab9753d8
2018-04-07 17:56:05 -07:00
Nikolai Tillmann
8c7dc6ff26 Turn leak an EmptyValue from a properties map
Summary:
Release notes: None

We keep track of initialized modules via an internal `__initializedModules` object.
However, after state joins and conditional `require()` calls, some of the
initialized module values `mightHaveBeenDeleted()`, indicating that they
might or might not have been initialized.
In that case, we should treat them just as other uninitialized modules.

Added regression test.
Closes https://github.com/facebook/prepack/pull/1713

Differential Revision: D7528844

Pulled By: NTillmann

fbshipit-source-id: b418a61e53b851f3ab385718c536e4c43fbbd170
2018-04-05 21:43:01 -07:00
Nikolai Tillmann
29a5a15f4e Do not inline functions accessing mutable free variables
Summary:
Release notes: None
Fixes: #1058

Adding regression test.
Closes https://github.com/facebook/prepack/pull/1708

Differential Revision: D7529042

Pulled By: NTillmann

fbshipit-source-id: 12f87f4898cdee7ec06cd4df4dfa85859eed4194
2018-04-05 19:32:56 -07:00
Herman Venter
7d1e3522dc Unknown properties that potentially mask props from prototype
Summary:
Release note: Better support for o[p] where p is unknown and the runtime value denotes a property on the prototype.

Partially fixes issue: #1575

When a known object, say ob = { x: 1, y: 2},  is accessed with an abstract property name (p), we currently emit a cascade of conditions of the form "p === 'x' ? 1 : (p === 'y' ? 2 : undefined)". If there was previously a write the object with an abstract property name (q), say ob[q] = 3, the undefined case is  replaced with "p === q ? 3 : undefined" and the 1 is replaced with "q === 'x' ? 3 : 1" and so on.

If this seems very painful and inefficient to you, I can only agree, but note that it handles intermediate object states because the expression is a-temporal and is derived from the state of the object at a particular point in time. This is kind of important.

Nevertheless, this is not exactly correct either, hence issue 1575. The problem is basically that the undefined case at the end is wrong if the object has a prototype and the prototype has a property with name: (runtime value of p) and the object itself has not.

Fixing this is proving to be tricky and I think it is best get there in baby steps.

The first such step is to replace the undefined value in the expression above with the temporal expression ob[p]. This will run up the prototype chain rather than just return undefined.

Note, however, that this is just less wrong and not an actual solution. The problem is that by the time ob[p] is evaluated, ob may have a different value for p than it had at the temporal point where the expression was encountered. (The reason being that the final version of ob is the only one that actually gets serialized.)

I have some solutions in mind (Sebastian talks about some of them in the issue) but they are sufficiently complicated that I do not want to include them in this pull request, so please bear with me for while longer.
Closes https://github.com/facebook/prepack/pull/1702

Differential Revision: D7519459

Pulled By: hermanventer

fbshipit-source-id: 6387ab0a2be893eec205373c2c53c2f636760bf0
2018-04-05 12:36:59 -07:00
Nikolai Tillmann
ada252125e Adding regression test from #1672.
Summary:
Release notes: None

The issue seems to have been fixed by pull request #1660.
This adds a regression test.
Closes https://github.com/facebook/prepack/pull/1706

Differential Revision: D7518715

Pulled By: NTillmann

fbshipit-source-id: eab46243919283409681a89ffaa162e7a9e4074e
2018-04-05 12:04:29 -07:00
Herman Venter
6f62fa6f51 Disable some simplifier special cases when isCondition is true.
Summary:
Release note: none

If the x and y part of a c ? x : y are simplified under the assumption that they will only be used contexts where they are converted to Booleans, then it is not safe to use them in equality comparisons. Hence the simplification rules that do so must be disabled in this situation.
Closes https://github.com/facebook/prepack/pull/1698

Differential Revision: D7511274

Pulled By: hermanventer

fbshipit-source-id: f0329c00523cb3c06de9e0dde3ab55104dbb07c7
2018-04-04 19:55:05 -07:00
Chris Blappert
1f411a1e4e Make __optimize calls in optimized functions work
Summary:
Steals test case from #1626.

`__optimize` calls now search for newly registered functions. This should allow more test cases, which are all included with the diff.

This also changes the serializer to serialize additional functions when they're first encountered in the serializer instead of at the end.
Closes https://github.com/facebook/prepack/pull/1660

Differential Revision: D7491497

Pulled By: cblappert

fbshipit-source-id: b4b88100d7aa4b8c25dddabb1f82189dd9848fc5
2018-04-03 15:43:47 -07:00
Herman Venter
88fbdcc47b Emit explicit conversion to object
Summary:
Release note: Fix problem where the results of To.ToObject were lost during serialization

Fixes issue: #1595

The serializer will now serialize the abstract result of calling To.ToObjectPartial on an abstract value as "Object.assign(abstract_value)". In the one case where the serialized code is known to implicitly convert the abstract value to an object anyway, the caller of To.ToObjectPartial strips away the wrapper in order to avoid the redundant explicit conversion.

Since I ended up looking at every call of To.ToObjectPartial, I used this an opportunity to merge it into To.ToObject.

I also made AbstractObjectValue.$GetPrototypeOf aware of the wrapper and made it return concrete values if the type of the wrapped primitive is known.
Closes https://github.com/facebook/prepack/pull/1690

Differential Revision: D7490354

Pulled By: hermanventer

fbshipit-source-id: 75146883d8b949c4e3e7848bd2e030f7b7c4d147
2018-04-03 14:38:39 -07:00
Nikolai Tillmann
f15fd8c918 Basic support for implicit this in additional functions
Summary:
Release notes: None

This partially addresses #1640, allowing for read-access to this.
However, just as for any other incoming abstract values, write-accesses are not yet allowed.
Adding regression test.
Closes https://github.com/facebook/prepack/pull/1641

Differential Revision: D7473440

Pulled By: NTillmann

fbshipit-source-id: 140a3c97aa0e3c4f52ef09134b0e43e7f7f84f7d
2018-04-03 11:48:57 -07:00
Ariel Mashraki
fc0d344044 Fix switch statement evaluation bug
Summary:
Issue #1645
Closes https://github.com/facebook/prepack/pull/1681

Differential Revision: D7461828

Pulled By: a8m

fbshipit-source-id: b37a6d15147b277950d50e91ae17a6825fba8b32
2018-03-30 16:23:27 -07:00
Sebastian Markbage
8cc3a0355f Various Fixes to GetPartial
Summary:
This adds havocing in the right places that was not done properly in the previous solution.

This also allows non-self Receivers. For simple objects, this is allowed because they can't possibly have any meaningful impact if the object is truly simple since only getters expose the receiver concept.

More than that we can also make an assumption for non-simple objects, in pure mode. I assume that if the receiver is not self then the only reason we got here is because we concluded that anything else on the prototype chain cannot have had this property key on it. For example, that happens with a ToObject coercion. The original values doesn't have any properties on it.

A fix to #1675 might need to account for this scenario because currently we never propagate up the prototype chain so this can never happen.

However, even if there might be something else shadowing this on the prototype chain, this property access will still be ok since the residual is serialized as a property access on the receiver - which is havoced.

Fixes #1676
Closes https://github.com/facebook/prepack/pull/1680

Differential Revision: D7460594

Pulled By: sebmarkbage

fbshipit-source-id: e71dee4a6edf9b8a32a09016e7ac455ad03ad792
2018-03-30 15:03:59 -07:00
Herman Venter
3d7108a91a ! operator should only care about truthiness
Summary:
Release note: More aggressive simplification of !e expressions

Since only the truthiness of e matters, it can be simplified more aggressively than e can by itself. To do this, one uses Environment.GetConditionValue rather than Environment.GetValue.
Closes https://github.com/facebook/prepack/pull/1688

Differential Revision: D7460139

Pulled By: hermanventer

fbshipit-source-id: 1ac2b799107e9743832979e29f8a79954ac666a8
2018-03-30 14:49:28 -07:00
Herman Venter
b71a169b31 Push path conditions when simplifying conditional expressions.
Summary:
Release note: none

The basic change here is to use path conditions when simplifying conditional expressions. Doing so led to an explosion of work in the simplifier, so I had to introduce more flags to reign in the simplifier and preventing it from trying to simplify things that have already been simplified.
Closes https://github.com/facebook/prepack/pull/1684

Differential Revision: D7457002

Pulled By: hermanventer

fbshipit-source-id: 30ecde01c23b52871cdf43b24bf9ab9c5eecff4f
2018-03-30 11:26:39 -07:00
Herman Venter
6b80e6b139 Add rule to help simplify expressions with conditions involving == and !=
Summary:
Release note: Simplification now works better when == and != are used.

The main goal of this PR is simplify away unnecessary object creations such as the one in the test case.

Working on this, however, I ran into cases where tweaks to the simplifier would cause "push false" invariant failures. This time around I could not find a way to avoid it, so the time has come to exploit it. Consequently, the biggest part of this PR is to recover when we detect a contradiction by reverting to behavior we would have had, had we known that assuming the condition is true (or false) is actually invalid.

While there is a lot of code, the transformations are pretty simple.
Closes https://github.com/facebook/prepack/pull/1679

Differential Revision: D7452855

Pulled By: hermanventer

fbshipit-source-id: 507f0a1a6dbe9432ad5654e488214b8da7f7197c
2018-03-29 20:23:44 -07:00
Herman Venter
ebfd530fb0 Fix serialization of optimized functions that might throw exceptions.
Summary:
Release note: Stop generator entries from being serialized twice

Fixes issue: #1627

When the effects of optimized function is reduced to a generator, care must be taken to avoid duplicating the normal path of a function that could terminate with an exception.

It is a bit unfortunate that the effects has this duplication in there in the first place, but I was not able to figure out a way to avoid this and there are more pressing matters to attend to.
Closes https://github.com/facebook/prepack/pull/1670

Differential Revision: D7431202

Pulled By: hermanventer

fbshipit-source-id: 081713419c7cd46b77c76068fba89c62f49dea70
2018-03-29 11:22:29 -07:00
Sebastian Markbage
c2d535f089 Explicitly allow AbstractObjectValue on the prototype chain
Summary:
Fixes #1598

This is actually already allowed to be abstract since all the internal objectvalue properties can be abstract and there are tests for it. This PR just makes it a bit more explicitly handled and properly typed.

I also need this so I can write more tests around abstract prototype chains so I don't break the code paths that already are designed to support them.

I also did a pass to search for other instanceof ObjectValue checks but I didn't find any obviously similar issues.
Closes https://github.com/facebook/prepack/pull/1603

Differential Revision: D7440114

Pulled By: sebmarkbage

fbshipit-source-id: 45169e8eb5afc6de2de7a7f1f4a4c6076fe7e2ab
2018-03-28 20:37:27 -07:00
Nikolai Tillmann
aa6ece3607 Removing some state from ResidualHeapVisitor that seems unnecessary
Summary:
Release notes: none
Closes https://github.com/facebook/prepack/pull/1664

Differential Revision: D7432796

Pulled By: NTillmann

fbshipit-source-id: b875c0f4c0ec57a881c34f603b298fa4a4ec74eb
2018-03-28 16:59:18 -07:00
Dominic Gannaway
aa2cc273fc Fixes a class serialization bug
Summary:
Release notes: none

Fixes a class serialization found here: https://github.com/facebook/prepack/issues/1317#issuecomment-376361753
Closes https://github.com/facebook/prepack/pull/1662

Differential Revision: D7416654

Pulled By: trueadm

fbshipit-source-id: 3203952d0317dbe7ff699c4daa78895432deb43e
2018-03-27 11:40:52 -07:00
Dominic Gannaway
c9e7ed36cb Add more test coverage to complex cases
Summary:
Release notes: none

I've added more tests that used to fail, but now pass with recent changes to master. Let's keep these tests as regressions tests.
Closes https://github.com/facebook/prepack/pull/1580

Differential Revision: D7414055

Pulled By: trueadm

fbshipit-source-id: 0b53d711b7ffd1de75335071afe8eba14fcae2f8
2018-03-27 06:23:20 -07:00
Dominic Gannaway
923df52786 Adds more replace React test covering "this"
Summary:
Release notes: none

Adds more tests to ensure we don't regress in some cases.
Closes https://github.com/facebook/prepack/pull/1649

Differential Revision: D7392527

Pulled By: trueadm

fbshipit-source-id: 0b34bfd741a5de7ea434f6e3c30f15dab983482e
2018-03-24 08:35:51 -07:00
Dominic Gannaway
156c30f401 Support inlining dynamic ReactElement "type" fields
Summary:
Release notes: none

This adds a really cool feature – dynamic ReactElement type. As per a conversation in Messenger yesterday by gaearon, it got me thinking about how we might "simplify" recursively on a conditional in complex cases and I decided it was probably worth adding to inline components. This PR makes it possible to inline component trees without having to break out when the type is an abstract conditional.
Closes https://github.com/facebook/prepack/pull/1647

Differential Revision: D7392497

Pulled By: trueadm

fbshipit-source-id: 170ae4829bd407410d8882c874144516cfd01190
2018-03-24 07:57:53 -07:00
Nikolai Tillmann
7fbc13667b Follow up on duplicate factory function fix
Summary:
Release notes: None

Adding regression test
Closes https://github.com/facebook/prepack/pull/1639

Differential Revision: D7369872

Pulled By: NTillmann

fbshipit-source-id: 17f49966100456746ed693c06b3d9d1737423dbd
2018-03-22 13:33:36 -07:00
Dan Abramov
b5424bbe5b Make React test deterministic
Summary:
This fixes a React test to be deterministic.
Closes https://github.com/facebook/prepack/pull/1636

Reviewed By: trueadm

Differential Revision: D7366209

Pulled By: gaearon

fbshipit-source-id: c944d6ab638d4914d2a5eab9e341186755264ec1
2018-03-22 11:38:19 -07:00
Dominic Gannaway
3dabacf56e Add nested optimized function support to React reconciler
Summary:
Release notes: none

This PR adds nested optimized function support and bug fixes around them to the React reconciler.

The tests added that fail have been skipped for now until we have the ability to properly serialize nested optimized functions.
Closes https://github.com/facebook/prepack/pull/1614

Differential Revision: D7366102

Pulled By: trueadm

fbshipit-source-id: c18c5a470a31b905a76155e006767f8ec7a73afa
2018-03-22 10:54:42 -07:00
Nikolai Tillmann
fba61624ea Fixing build
Summary:
Release notes: None
Closes https://github.com/facebook/prepack/pull/1635

Differential Revision: D7362605

Pulled By: NTillmann

fbshipit-source-id: 34e3110a489398959094e66b2dea61a195e04d38
2018-03-21 21:09:09 -07:00
Ariel Mashraki
8110ed7742 Generate better code in the presence of arguments in nested residual functions
Summary:
Solve #1621
Closes https://github.com/facebook/prepack/pull/1632

Differential Revision: D7361512

Pulled By: a8m

fbshipit-source-id: 77b18888af9146140a8368a3cb3fd39a201cd5a7
2018-03-21 19:05:13 -07:00
Nikolai Tillmann
40ab722f78 Fixing issues around global let bindings and optimized functions
Summary:
Release notes: None

This fix for #1250 ensures that Prepack properly emits global let bindings,
which was broken in particular in the presence of optimized functions.

(Looking at the code, the whole approach of rewriting residual bindings
while processing optimized values seems quite brittle, but changing that
is for a later pull request.)
Closes https://github.com/facebook/prepack/pull/1631

Differential Revision: D7359200

Pulled By: NTillmann

fbshipit-source-id: 3fcb84e2672dc913c8dd217375de7744cc361746
2018-03-21 16:52:38 -07:00
Nikolai Tillmann
bfcca0a347 Fixing lifetime of objects referenced by optimized functions
Summary:
Release notes: Fixes to optimized function object lifetimes, #1542 and #1543.

Achieved by simplifying `visitBindings`.
Closes https://github.com/facebook/prepack/pull/1630

Differential Revision: D7359192

Pulled By: NTillmann

fbshipit-source-id: e1098142b2f0765c438d95aa881203b1ac261416
2018-03-21 16:52:38 -07:00
Herman Venter
e1e7a819af Provide a way to snapshot objects at temporal points.
Summary:
Release note: Allow subsequent mutating of Object.assign() arguments by snapshotting them

Fixes issue: #1480

The normal mode for Prepack is to run to the end of global code and then serialize the objects as they are at that point. This causes problems if objects are passed to functions that must be called at particular temporal points, since the calls must receive the objects as they are at that point, rather than as they are at the time when Prepack serializes them.

To solve this conundrum, there is now a way to get a snapshot of an object at a particular temporal point. This works by creating a new object and transferring the properties from the original object to the new object. Things are arranged so that the two objects are always referred to by the same name in the generated code. The nice end result is that subsequent modifications to the object does not affect the object that is passed to the function call where the snapshot was taken.

Following the snapshot, the original object has no own properties and must be havoced or marked simple partial, depending on the circumstances at the temporal point where the snapshot is taken.

The latter case arises, for example, when the target object of a call to Object.assign has been snapshotted because one of the other arguments is partial or fully abstract. Following the call, the object can still be used and all property references result in abstract values with runtime lookup behavior. It is also possible to assign new properties to the object and Prepack will track the values of those properties.

In order to deal with the fact that multiple compile time objects now correspond to a single runtime object, the first snapshot gets its own named temporal abstract value and the original object is associated with this object and the name of the latter becomes the name of the original. Once an object gets a name, all further writes to the object results in runtime assignments at the temporal point of the write.

Consequently subsequent snapshots just return this first snapshot, since the runtime object get incrementally updated. The property references are still cleared out, since snapshotting an object implies that it going to be modified in unspecified ways.
Closes https://github.com/facebook/prepack/pull/1563

Differential Revision: D7347283

Pulled By: hermanventer

fbshipit-source-id: 618873abf99bcadc4c74794aa7804a5ac5d04c12
2018-03-20 19:25:06 -07:00
Nikolai Tillmann
032f71403f Removing --abstractEffectsInAdditionalFunctions option
Summary:
Release notes: Removing --abstractEffectsInAdditionalFunctions option

It is now the new default, as nothing seems to depend on the old behavior.
Closes https://github.com/facebook/prepack/pull/1623

Differential Revision: D7342083

Pulled By: NTillmann

fbshipit-source-id: c02d13bddd0ff3d8a113a6a5a83c1bf35c96ba4d
2018-03-20 15:04:24 -07:00
Ariel Mashraki
2c0c943ba2 Generate better code in nested residual functions
Summary:
Solve #886
`ClosureRefVisitor` tracks the depth of the traversing, and sets the `usesArguments`/`useThis` flags only if they were used in the top level function (depth = 1).
Closes https://github.com/facebook/prepack/pull/1618

Differential Revision: D7342100

Pulled By: a8m

fbshipit-source-id: e12afec542a5afa67625b03ee615ebf9f065af74
2018-03-20 15:04:24 -07:00
Herman Venter
4c1691118c Do not use variable before initialization
Summary:
Release note: Fix bug that caused variables to get used before their definitions have been processed.

Resolves: #1585

Following an code sequence that may terminate abruptly, or alternatively carry on normally, the generator that preceded the fork must be emitted into its parent and replaced with a new generator, before carrying on with the normal execution, since the normal execution is effectively nested inside the normal branch of the fork.

Note that this only occurs after the second such fork, which is why the bug was so elusive.
Closes https://github.com/facebook/prepack/pull/1619

Differential Revision: D7338429

Pulled By: hermanventer

fbshipit-source-id: e7463d87d20bde4f13bd6e69e0afe20c548f07c0
2018-03-20 11:52:24 -07:00
Christopher Blappert
1741133230 Make Effects into a Generator
Summary:
Additional Functions duplicates the Effects traversing logic in the serializer and visitor. Consolidate this logic as well as allowing for ordering dependencies by putting all these things needing visiting/serialization into the generator. Adds new `ModifiedPropertyEntry` and `ModifiedBindingEntry` types.
Closes https://github.com/facebook/prepack/pull/1559

Differential Revision: D7311062

Pulled By: cblappert

fbshipit-source-id: e789d48f76879fdee3dd1187b53ba15377d7dcb7
2018-03-19 21:09:31 -07:00
Herman Venter
62f91267bc Tweak simplifier to avoid "push false" invariant
Summary:
Release note: Added more logic to simplifier

The simplifier was ignoring the "isCondition" flag in some cases, which broke symmetry.

Also added this rule: (c ? x : (c || false)) => c

Test cases to come later.
Closes https://github.com/facebook/prepack/pull/1594

Differential Revision: D7293426

Pulled By: hermanventer

fbshipit-source-id: 5d42c0dcb29161c8186ce0964714e6ba1b7c67ae
2018-03-15 14:16:55 -07:00
Nikolai Tillmann
707aa1b63c Disabling abstract recursion check.
Summary:
Release notes: None.

Unfortunately, the abstract recursion check seems to conservative, as it triggered on some large internal tests even though there was no issue.
Disabled test test/serializer/abstract/Fibonacci.js that now fails.
I created an issue to track this.
Closes https://github.com/facebook/prepack/pull/1587

Differential Revision: D7282804

Pulled By: NTillmann

fbshipit-source-id: 4fc924b109c66c3237b14ace4d60d03f994b3715
2018-03-14 18:16:59 -07:00
Dominic Gannaway
e9fe2a5e7c Allow NewExpression constructor to recover in pure wrapper
Summary:
Release notes: none

It's common for a `new Something()` call to exist in pure wrappers where `Something` is an abstract value. Currently, this fails with a FatalError with no recovery. This PR adds a recover for this when in a pure wrapper so we can continue evaluating.
Closes https://github.com/facebook/prepack/pull/1590

Differential Revision: D7271876

Pulled By: trueadm

fbshipit-source-id: fc5192af6b356b7df9eb2f147bd8b53fe3790942
2018-03-14 08:01:24 -07:00
Herman Venter
ae877a9715 Simplify truthy conditionals in condition context
Summary:
Release note: Simplify conditions like c ? {} : null to just c if used in a condition context

Resolves: #1582

The simplifier already simplifies c ? true : false to just c. It can also do this for truthy values that are known to convert to true and false, if the result of the conditional is used as a condition.
Closes https://github.com/facebook/prepack/pull/1583

Differential Revision: D7261552

Pulled By: hermanventer

fbshipit-source-id: cf2c16ffd1dd99a23ea9cf4f8065d0f495b5d749
2018-03-13 14:29:30 -07:00
Dominic Gannaway
6a59b994af Adds failing test and enables possible normal completion logic for React reconciler
Summary:
Release notes: none

This enables the React reconciler to use the work done by cblappert and PossiblyNormalCompletions. Closes https://github.com/facebook/prepack/pull/1455
Closes https://github.com/facebook/prepack/pull/1576

Differential Revision: D7249352

Pulled By: trueadm

fbshipit-source-id: 9bbcca0d85476e1db1f577632329b911ddcff9b6
2018-03-12 17:46:40 -07:00
Dominic Gannaway
46061fc186 Protect against common firstRender issues
Summary:
Release notes: none

firstRender can fail when `Function.prototype.bind` is passed around because the firstRender removes the class component entirely, along with any concept of state etc. To prevent outputting the incorrect value, we now check for bind and if we're given something that is completely abstract as a child from a render, we bail out in that case too.
Closes https://github.com/facebook/prepack/pull/1573

Differential Revision: D7248829

Pulled By: trueadm

fbshipit-source-id: eebd7e6565352a37026928a20944377bb06129f5
2018-03-12 17:46:40 -07:00
Sebastian Markbage
66cd90de1d Don't visit widened length property
Summary:
This needs to line up with: b87d160517/src/serializer/ResidualHeapSerializer.js (L1051)
Closes https://github.com/facebook/prepack/pull/1574

Differential Revision: D7246394

Pulled By: sebmarkbage

fbshipit-source-id: 5e467bb5583aec4232d6b799b267366eec1591a6
2018-03-12 15:28:02 -07:00
Sebastian Markbage
b87d160517 Don't visit a "widened property" value on a path
Summary:
This accidentally checked the pathNode on the key instead of the value.

This is ignored by the serializer and the visitor needs to line up:

21fcfb2a09/src/serializer/ResidualHeapSerializer.js (L261)

Fixes #1551
Closes https://github.com/facebook/prepack/pull/1566

Differential Revision: D7240690

Pulled By: sebmarkbage

fbshipit-source-id: db8c88c4dc7b9c3f87004435866cc87822ee2e81
2018-03-12 12:13:07 -07:00
Chris Blappert
7ca909d617 Support additional function returning PossiblyNormalCompletion
Summary:
Release Notes: Allow additional functions to return PossiblyNormalCompletions.

Similar to the logic in `Program.js`, we need to emit an `if` statement at the end of an additional function that may return or throw.

In `functions.js` we process the PossiblyNormalCompletion, joining the consequent and alternate effects and creating a set of args + buildnode for emitting the conditional throw. Then where we would originally serialize/visit the return value, we will instead apply the joined effects and emit the conditional throw/return.
Closes https://github.com/facebook/prepack/pull/1523

Differential Revision: D7238882

Pulled By: cblappert

fbshipit-source-id: fd51bb4998394930960a70c8ef40b574e3244026
2018-03-12 11:29:18 -07:00
Dominic Gannaway
eab76537fa Fixes a visitor issue for React library
Summary:
Release notes: none

Found an issue on REPL: https://goo.gl/Qz46FJ

This fixes it along with a test.
Closes https://github.com/facebook/prepack/pull/1564

Differential Revision: D7231968

Pulled By: trueadm

fbshipit-source-id: c3ceff7d345f1a48e6fdeccfeaed6740383fbd40
2018-03-12 05:05:09 -07:00
Sebastian Markbage
d83c83c23b Handle property bindings on newly created objects in fixed point logic
Summary:
Release notes: none

First we need to ignore the differences in properties of newly created objects when we compare. Since widening doesn't preserve any knowledge of newly created objects (they just go to topVal), we don't have to be smarter than this.

Second, since all effects including property mutation of newly created objects gets reverted, this always yields empty objects. We need to apply the effects of newly created objects so that the serializer knows how to serialize these objects.

We should also avoid emitting property assignments to these objects since we've already applied them to the object value.
Closes https://github.com/facebook/prepack/pull/1560

Differential Revision: D7229726

Pulled By: sebmarkbage

fbshipit-source-id: f699028a01348934dc0e039263d48a8c3439870a
2018-03-11 19:38:10 -07:00
Dominic Gannaway
21fcfb2a09 Adds React.createContext API support
Summary:
Release notes: none

Adds React.createContext support to the React compiler. Updates Yarn dependencies to use React 16.3 pre-release version so tests can validate new API works with the compiler.
Closes https://github.com/facebook/prepack/pull/1548

Differential Revision: D7209302

Pulled By: trueadm

fbshipit-source-id: fff360ee19d4d9fee6e27b738658d9076449da4b
2018-03-11 13:12:41 -07:00
Dominic Gannaway
8181c419da Detect dead additional functions and do not serialize them
Summary:
Release notes: none

When we evaluate multiple additional functions, they might remove other additional functions that were defined as additional functions. This causes a serializer issue. If we check if they have info from the visitor we can avoid hitting an invariant. This fixes one of the issues flagged in https://github.com/facebook/prepack/pull/1550, thus pulling in the test that was failing from the PR.

This PR is rebased on https://github.com/facebook/prepack/pull/1561
Closes https://github.com/facebook/prepack/pull/1555

Differential Revision: D7220598

Pulled By: trueadm

fbshipit-source-id: 2d0b87e23ecd93b325f44daa3a7c21ff3591d733
2018-03-10 07:13:00 -08:00
Dominic Gannaway
fb2786d433 Fixes a React first render issue with component instance
Summary:
Release notes: none

When rendering a class component on first render, we need to ensure it's instance is intrinsic otherwise it will serialize out incorrectly.
Closes https://github.com/facebook/prepack/pull/1556

Differential Revision: D7220974

Pulled By: trueadm

fbshipit-source-id: 968afb5b7dbfc6f7714862d9cbedf6e793c9e504
2018-03-09 16:54:49 -08:00
Dominic Gannaway
b389598bb5 Rename __registerAdditionalFunction -> __optimize
Summary:
Release notes: `__registerAdditionalFunction` is now `__optimize`

This PR renames `__registerAdditionalFunction` to `__optimize` and removes all tests that use the `// additional functions` logic in favor of declaratively using `__optimize`. Also the serializer option for `additionalFunctions` is removed too.
Closes https://github.com/facebook/prepack/pull/1561

Differential Revision: D7219751

Pulled By: trueadm

fbshipit-source-id: 7984496b3a68db3194fb3696839cb11fdd0b7843
2018-03-09 14:44:46 -08:00
Manas
3101a0a556 Add more binary ops implicit conversion
Summary:
Handles more implicit abstract conversions during binary ops. Addresses #1109
Closes https://github.com/facebook/prepack/pull/1314

Differential Revision: D7217039

Pulled By: hermanventer

fbshipit-source-id: 15cc02dbdd4bb9e15d15010780ae45050e5c9bdd
2018-03-09 11:52:02 -08:00
Dan Abramov
84887ba29d Fixes StringLiterals as JSX text
Summary:
Release notes: none

This PR fixes an issue where a StringLiteral that contained quotes, which resulted in being escaped on output, should have been wrapped in JSXExpressionContainer, otherwise the output becomes invalid.
Closes https://github.com/facebook/prepack/pull/1549

Reviewed By: trueadm

Differential Revision: D7207620

Pulled By: gaearon

fbshipit-source-id: d783475e507f65d0dc20678cc07e1b694397d0c1
2018-03-08 19:05:15 -08:00
Dominic Gannaway
e1c23e98c8 Attempt at fixing #1537
Summary:
A WIP attempt that might not be right – but to help with the discovery of the right solution for #1537.
Closes https://github.com/facebook/prepack/pull/1538

Differential Revision: D7188125

Pulled By: trueadm

fbshipit-source-id: eed37afd3707feaffe779f50ff82b222d2abfd28
2018-03-07 16:57:45 -08:00
Sebastian Markbage
bcedcaa1b9 Follow up to abstract binary expressions
Summary:
This is a follow up to #1473.

See individual commits for comments.
Closes https://github.com/facebook/prepack/pull/1476

Differential Revision: D7185243

Pulled By: sebmarkbage

fbshipit-source-id: c7dd929c15f4e13b80fd6877fc054172655bae6a
2018-03-07 14:23:54 -08:00
Sophie Alpert
6a4f204b3a Revert D7165911: [prepack][PR] When Object.assign bails out, resolve to an AbstractObjectValue
Summary:
This reverts commit 6e5e3472c27b254349a86009cccca2ffc0311faa

bypass-lint

An infra SEV is better than not reverting this diff.
If you copy this password, see you in SEV Review!
cause_a_sev_many_files

Differential Revision:
D7165911

Original commit changeset: 6e5e3472c27b

fbshipit-source-id: 80333d1c03b3b2dff5e4024b6c64f611770a4d7a
2018-03-07 10:51:05 -08:00
Sophie Alpert
905b937043 When Object.assign bails out, resolve to an AbstractObjectValue
Summary:
Release notes: none

This will allow Put to execute successfully on something that has come from an object literal with spread.
Closes https://github.com/facebook/prepack/pull/1533

Differential Revision: D7165911

Pulled By: sophiebits

fbshipit-source-id: 6e5e3472c27b254349a86009cccca2ffc0311faa
2018-03-05 22:33:46 -08:00
Dominic Gannaway
dea24c1644 Change an invariant in Properties.PutValue to a FatalError
Summary:
Release notes: none

Whilst running the UFI code, we encountered this invariant being triggered where the base value was not an ObjectValue or AbstractObjectValue (it was an AbstractValue). I changed the invariant for a FatalError along with a relevant message and PP code.
Closes https://github.com/facebook/prepack/pull/1534

Differential Revision: D7165871

Pulled By: trueadm

fbshipit-source-id: 088731d82e5db770c74ac028ace115ea09eb1bdc
2018-03-05 22:19:01 -08:00
Dominic Gannaway
4b9858f84b Allow simple object property access with an abstract dynamic key
Summary:
Release notes: Allow simple object computed property access with abstract property keys

The aim of this PR is to provide object computed property access when the property key is an abstract value and the object is a simple object. Furthermore, given the key is abstract, and converting it to a key might involve side-effects, this is only handled in a pure scope.
Closes https://github.com/facebook/prepack/pull/1530

Differential Revision: D7164200

Pulled By: trueadm

fbshipit-source-id: dfd8ac86985fd9d96fc18c6c28b954dff51eab27
2018-03-05 18:49:37 -08:00
Dominic Gannaway
079404fafc Adds firstRenderOnly mode
Summary:
Release notes: none

Adds a new React reconciler rendering mode called `firstRenderOnly`, activated by in the config passed to `__optimizeReactComponentTree`. Will add documentation to the wiki once this PR is ready to land.
Closes https://github.com/facebook/prepack/pull/1531

Differential Revision: D7164196

Pulled By: trueadm

fbshipit-source-id: 79cf99f7aad6b4ac9c9c7ea699dab0b266a24788
2018-03-05 18:49:37 -08:00
Neil MacIntosh
07fb1937fc Attempt at abstract evaluation of switch cases using recursion.
Summary:
Adds abstract evaluation for switch cases. Effectively treats the switch case as a series of if-else statements to achieve the same outcome.

Currently does not support case blocks that result in an abrupt completion through `return/throw/continue`. That is work-to-go in the future.

A future PR will also expand on the tests to provide more coverage (and look for corner cases).
Closes https://github.com/facebook/prepack/pull/1519

Differential Revision: D7163238

Pulled By: neilmacintosh

fbshipit-source-id: 7ee824f90821d6a3d0d495ed01f8b09b0d190bbd
2018-03-05 17:48:07 -08:00
Herman Venter
e83ebf9a6b Do not havoc frozen objects
Summary:
Release note: Do not havoc leaked objects if they are frozen

This still traverses the object and makes sure that any unfrozen locally created objects that are reachable from it are havoced.

sebmarkbage What is the rationale for leaving unfrozen objects unhavoced if they were not created in a pure context?
Closes https://github.com/facebook/prepack/pull/1520

Differential Revision: D7145807

Pulled By: hermanventer

fbshipit-source-id: aac41d3d814cb6cc9a0b486c3913a9a2f563458f
2018-03-05 14:33:23 -08:00
Sebastian Markbage
5b12407c33 Fix hasOwnProperty invariant failure
Summary:
Release notes: none

This fatals in the case we try to extract a descriptor from a topVal which can happen.

This lets the CallExpression fallback to leaving the call inact.

Unfortunately that havocs the arguments unnecessarily. So I also special cased it. I guess we should just make this a common pattern for pure built-ins.
Closes https://github.com/facebook/prepack/pull/1524

Reviewed By: trueadm

Differential Revision: D7152130

Pulled By: sebmarkbage

fbshipit-source-id: 24e5c02d36ae6a2e685b5b903c6cdfd0937b0834
2018-03-04 22:23:53 -08:00
Dominic Gannaway
afb0a9e9cb Change how to signal React components for optimization
Summary:
Release notes: none

Currently, you register a React component tree with `__registerReactComponent(component)`.

This PR changes this global to `__optimizeReactComponentTree(rootComponent, config)`. Notice it now supports two arguments `rootComponent` and `config` – although config is optional.

This global now also returns the original component passed in, so it can be added to existing codebase without having to break logic flow.

This config argument allows the user to define how that React component tree will be optimized. More work will be added to this in upcoming PRs, but for now this PR is just a quick rename plus small refactor of the Prepack global.

I've also had to rename the global in all tests. I've also added some doc as to how all this works: https://github.com/facebook/prepack/wiki/React-Compiler
Closes https://github.com/facebook/prepack/pull/1527

Differential Revision: D7149728

Pulled By: trueadm

fbshipit-source-id: 8d04d8dec8c0a03a6ccdb9587884bf6375010203
2018-03-04 02:24:49 -08:00
Nikolai Tillmann
7b1d113c17 Fixing an ordering issue with generators + additional functions
Summary:
Release notes: None

Additional functions can have nested generators, and then ordering of declared values matters between those generators!
Also adding new --debugIdentifiers option to figure out why an identifier is emitted to a particular target bdoy.
Adding regression test case.
Closes https://github.com/facebook/prepack/pull/1526

Differential Revision: D7149708

Pulled By: NTillmann

fbshipit-source-id: cde8d4f1516e1d740a86997215423d30a015a8a2
2018-03-04 02:24:49 -08:00
Dominic Gannaway
2bb791e464 Allow complex React class components to fold into simple class components
Summary:
Release notes: none

This PR introduces a big clean up and re-design of some of the React reconciler code to allow for better folding capabilities. This PR enables complex React class components to be folded into functional/simple React components. This involves cloning the class component data structure and copying it on to the functional component.

Finally, any original properties of the functional component, for example `getTrials` or `defaultProps` are copied from the original back over the top to ensure the existing semantics remain (otherwise `getTrials` etc will be missing from the root component).

This PR is a fundamental stepping stone to allow us to better fold component trees and also tidies up some of the existing logic to make it easier to reason with and understand.
Closes https://github.com/facebook/prepack/pull/1428

Differential Revision: D7146514

Pulled By: trueadm

fbshipit-source-id: 3c0581b4beb341dac1d563a8ec9861afa1bb1708
2018-03-03 11:13:50 -08:00
Dominic Gannaway
90b78fd73e Add missing fb tests
Summary:
Release notes: none

This PR enables fb10.js and adds fb11.js from https://github.com/facebook/prepack/pull/1434, thus closing that PR.
Closes https://github.com/facebook/prepack/pull/1518

Differential Revision: D7131867

Pulled By: trueadm

fbshipit-source-id: ab168809da1e625dfa427addadc465e13b68787f
2018-03-01 17:08:38 -08:00
Chris Blappert
2b600a3d56 Fix additional functions refactor
Summary:
Fix for bug NTillmann encountered with the additional functions refactor.

Every function references itself through its `arguments`, so additional functions were recursively trying to visit themselves while visiting their arguments. It doesn't make sense to visit a function from its own scope, so we add a check to the visitor preventing this.
Closes https://github.com/facebook/prepack/pull/1508

Differential Revision: D7130078

Pulled By: cblappert

fbshipit-source-id: ecb0497456169f3ff41c89f2fcf17e3ae9670d96
2018-03-01 16:16:26 -08:00
Dominic Gannaway
7725abdbce Handle React component render props
Summary:
Release notes: none

This PR is the work to get component render props working with the reconciler. We check if a render prop function is safe to use a new root for a component tree by scanning it's bindings using the leak ref traverser. If we find a binding that was created in the parent component, then it's not safe to make the render prop an additional function.
Closes https://github.com/facebook/prepack/pull/1478

Differential Revision: D7119766

Pulled By: trueadm

fbshipit-source-id: 8d286f1bc0ace009d2304643ba527b9932d2aa93
2018-02-28 22:12:07 -08:00
Nikolai Tillmann
9e97d9aca3 Allowing specifying abstract function result type
Summary:
Release notes: None

In calls to __abstract, the first argument represents a type name or a template object.
Adding a new kind of type name: A colon followed by a simple type name.
This indicates that the abstract value is a function with the given known result type.

Also tweaked handling of Array concat so that it doesn't require knowing the exact elements
being concatenated (this is what motivated the abstract function result type change for me...)
Closes https://github.com/facebook/prepack/pull/1505

Differential Revision: D7102523

Pulled By: NTillmann

fbshipit-source-id: c8f81669eb938e75bde8231544ae42fe1788dbc9
2018-02-27 13:53:56 -08:00
Dominic Gannaway
4b6077c5de Small tidy up of ReactElement logic
Summary:
Release notes: none

This PR cleans up the logic in how ReactElement properties are visited, moving them to the right place in the codebase. `react/utils/getProperty` also now properly deals with missing properties and throws an introspection error for getters/setters.
Closes https://github.com/facebook/prepack/pull/1507

Differential Revision: D7092708

Pulled By: trueadm

fbshipit-source-id: 4064a0cf48b633bd77012afb99e514ac5716e062
2018-02-26 17:30:53 -08:00
Dominic Gannaway
cdec5c1005 Support more unary expression cases in pure scope
Summary:
Release notes: none

Support was added for delete unary expression cases a few days ago. This PR ensures all the other unary expression cases are also handled now too. The abstract temporal logic has been extended to support cases where the BaseValue of a reference was a EnvironmentRecord (when you destructure an object, this occurs).
Closes https://github.com/facebook/prepack/pull/1495

Differential Revision: D7075821

Pulled By: trueadm

fbshipit-source-id: 4cbbdc62ba03be41298c12aa57ce16d8d1225b2d
2018-02-23 16:38:53 -08:00
Chris Blappert
ab4558a6d6 Additional Functions Refactor
Summary:
Add `withEffectsAppliedInGlobalEnv` to Realm which speculatively applies Effects (except the generator) for the duration of the function passed in. Reworks the visitor to use this new function for clarity (and will later be useful for #1474).
Closes https://github.com/facebook/prepack/pull/1485

Differential Revision: D7071689

Pulled By: cblappert

fbshipit-source-id: 7b150c00a3cf1ada28f44b63f0b230863f689a04
2018-02-23 12:25:02 -08:00
Neil MacIntosh
52d4476a77 Support for abstract interpretation of switches
Summary:
Thought I'd (re)start by just adding a hook point to the existing interpreter code to branch off in case of abstract interpretation. The two are likely to look quite different and keeping them separate will be tidier. Also added a basic test case to ensure that it fails when abstract interpretation is required for a switch.

Looking for feedback if this looks repulsive. If not, then I'll go make it do something basic as the next step (and add more tests) ;-)
Closes https://github.com/facebook/prepack/pull/1490

Differential Revision: D7070026

Pulled By: neilmacintosh

fbshipit-source-id: 0c10d0c9c80d1579ddbc128a32009b67f8c9a39b
2018-02-23 10:59:22 -08:00
Dominic Gannaway
67ee4078a7 Fixes named function bindings in additionalFunction scope
Summary:
Release notes: none

This PR fixes a bug where named functions' bindings were being marked as global inside additionalFunctions. This meant that they were incorrectly being assigned to the global.

Fixes https://github.com/facebook/prepack/pull/1432
Closes https://github.com/facebook/prepack/pull/1489

Differential Revision: D7059627

Pulled By: trueadm

fbshipit-source-id: 232753cf591e4cb3f566578e3fe3844c28829d49
2018-02-22 14:10:35 -08:00
Nikolai Tillmann
b24de956ea Fixing _serializeAbstractValue scoping
Summary:
Release notes: none

This fixes #1483.
Adding regression test case.
Closes https://github.com/facebook/prepack/pull/1484

Differential Revision: D7058713

Pulled By: NTillmann

fbshipit-source-id: ef8e417da4078109851242f23797b2480e135a04
2018-02-22 13:00:51 -08:00
Chris Blappert
80feb5e095 Simple arguments for additional functions
Summary:
Release Notes: None

This causes additional functions to automatically convert their arguments into `AbstractValue`s. Later PRs will allow more granular specification of arguments.
Closes https://github.com/facebook/prepack/pull/1466

Differential Revision: D7057474

Pulled By: cblappert

fbshipit-source-id: 47d51dbd0a20328cad9a586ffc3938212fadff99
2018-02-22 12:31:53 -08:00
Chris Blappert
0c94759498 Move __captured_scopes logic to visitor
Summary:
It's easier to reason about the delayInitializations logic when the captured scopes are computed in the visitor. This also makes it easier to centralize the Additional Functions logic and make Additional Functions compatible with delayInitializations.

The visitor now:
- Marks `ResidualFunctionBinding`s as `referencedOnlyFromAdditionalFunctions` if necessary
- `referentialize`s the bindings (recording the groups of bindings by populating the referentializer's `scopes` correctly)

The serializer still:
- calls `referentializeBinding` which records the serializedValue in the `__capturedScopes` function and replaces it with a reference to the `serializedBindingScopeInstance`
Closes https://github.com/facebook/prepack/pull/1445

Differential Revision: D7057660

Pulled By: cblappert

fbshipit-source-id: 0fc22b28c3c3fb1068d3c19a69113dc7aa7f947d
2018-02-22 12:31:52 -08:00
Herman Venter
e561aff47d Partial evaluation of throw statements
Summary:
Release note: Work on partial evaluator

Partial evaluation for throw statements. Needed to eventually create test cases that present other partial evaluation methods with abrupt and possibly abrupt completions.
Closes https://github.com/facebook/prepack/pull/1486

Differential Revision: D7057974

Pulled By: hermanventer

fbshipit-source-id: 5b92dbd19749fc3d1b26c9957ce7847b1126cba9
2018-02-22 12:31:52 -08:00
Herman Venter
825911ca64 Transitively simple objects
Summary:
Release note: Provides a way to make every unknown property value from a simple object be a simple object. Fixes issue: #1410
Closes https://github.com/facebook/prepack/pull/1426

Differential Revision: D7049994

Pulled By: hermanventer

fbshipit-source-id: fe499cb1652e050711ae26ac5776d6939c4fd8dc
2018-02-21 16:47:49 -08:00
Nikolai Tillmann
6b7e21c9ca Don't create a new name generator every time it's needed.
Summary:
Release notes: None

This fixes #1350 and adds a regression test.
Closes https://github.com/facebook/prepack/pull/1482

Differential Revision: D7049835

Pulled By: NTillmann

fbshipit-source-id: dcd16f698f4be3f9bca70daaf45c93a972410346
2018-02-21 16:26:29 -08:00
Dominic Gannaway
273312ecd8 Improve the ReactElement logic for evaluation to improve folding cases
Summary:
Currently, there are too many cases where ReactElement evaluation bails out. This PR aims to solve many of those cases:

- [x] Ensure `props` have a deleted `key` and `ref`
- [x] Refactor JSX evaluation to properly handle and deal with JSX spreads
- [x] Ensure all react-tests run both transpiled and non-transpiled so the `React.createElement` route can be evaluated and tested
- [x] Refactor React.createElement mock to work like the JSX evaluator
- [x] Throw and error when we've detected cases where `key` and `ref` are abstract and not deleted or defined

Will do in a follow up PR once other PRs land:
- Ensure that we internally pass around `reactHint` in cases of `Object.assign`
Closes https://github.com/facebook/prepack/pull/1447

Differential Revision: D7049578

Pulled By: trueadm

fbshipit-source-id: 7f8330c8e4c47c5095b672f686cedc593852a6a8
2018-02-21 16:26:29 -08:00
Dan Abramov
708aa8830c Change PP0023 error code to PP0026
Summary:
I just realized [PP0023 is already taken](https://github.com/facebook/prepack/wiki/PP0023).

I couldn't find it by code search but even if it was removed, we still shouldn't reuse the same error code for a different problem.
Closes https://github.com/facebook/prepack/pull/1479

Reviewed By: trueadm

Differential Revision: D7048029

Pulled By: gaearon

fbshipit-source-id: 74627233da069370722683b8c4295db3e913049c
2018-02-21 15:02:35 -08:00
Dominic Gannaway
4fefa2b1bf Support simple partial object property deletion
Summary:
Release notes: none

This PR does two things:

- when trying to `delete` a simple partial object property, we now emit the deletion
- added logic in `unaryExpression` that we can expand on for catching FatalErrors and recovering from them in pure mode (although this isn't needed as part of this PR anymore, as we now handle all simple partial objects the same)
Closes https://github.com/facebook/prepack/pull/1472

Differential Revision: D7046779

Pulled By: trueadm

fbshipit-source-id: 5db283b8815faa165ae0a85e5618c28c30091b7e
2018-02-21 13:48:31 -08:00