Commit Graph

1237 Commits

Author SHA1 Message Date
Nikolai Tillmann
7f3b5d4caf Make sure all optimized functions are included in IR dumping (#2568)
Summary:
Release notes: None

Dumping happened before `processCollectedNestedOptimizedFunctions`,
which caused them to not be included. This is being fixed, plus some
minor refactoring to hide implementation details.
Pull Request resolved: https://github.com/facebook/prepack/pull/2568

Differential Revision: D10023363

Pulled By: NTillmann

fbshipit-source-id: 6abe2b5358f23705b501fc818536fb30d42a3b17
2018-09-24 19:33:51 -07:00
Dominic Gannaway
0e52d02190 Adds React pe-functional-components benchmark and some React SSR changes (#2560)
Summary:
Release notes: none

All these changes are only internal changes related to React.

This PR adds the `pe-functional-components` benchmark as tests to the React reconciler. The test was taken from: https://github.com/facebook/react/tree/master/scripts/bench/benchmarks/pe-functional-components.

In order to make the server side renderer test pass, a few TODOs had to be filled in (logic was missing) and the JSON logic has to be updated to account for empty strings in children that the compiler merges.
Pull Request resolved: https://github.com/facebook/prepack/pull/2560

Differential Revision: D10008375

Pulled By: trueadm

fbshipit-source-id: 3b39a3e6387e23e17532a2343bd84ebebb7ee9cd
2018-09-24 03:56:52 -07:00
Nikolai Tillmann
465b8defba Speeding up visitor by skipping redundant generator scopes (#2562)
Summary:
Release notes: None

There's no need to re-visit deep value chains in nested generators,
if a value was already visited in a parent generator.
This greatly speeds up certain internal RN scenarios.
Pull Request resolved: https://github.com/facebook/prepack/pull/2562

Differential Revision: D10001612

Pulled By: NTillmann

fbshipit-source-id: a4f66b1a4835121cef4e3bc424f507f5b2c843f9
2018-09-21 19:11:06 -07:00
Nikolai Tillmann
4b911f2138 Refactoring of Generator DAG to Generator Tree. (#2434)
Summary:
Release notes: None

To avoid all kinds of serialization issues, generators should form
a tree, and not a DAG. This is an attempt to establish that.
Pull Request resolved: https://github.com/facebook/prepack/pull/2434

Differential Revision: D9887684

Pulled By: NTillmann

fbshipit-source-id: c11c50c56dcd6eff02bd03448756bf79f6e2c820
2018-09-20 10:09:19 -07:00
Herman Venter
0dced15809 Fix problem where a bind call can use a variable before its definition (#2558)
Summary:
Release note: none

A large internal test case came up with a situation where an optimized function is rewritten with a version that early binds a yet to be declared value to one of its parameters.

This should probably never happen, so the if condition guarding this code path has been strengthened to prevent this.
Pull Request resolved: https://github.com/facebook/prepack/pull/2558

Reviewed By: trueadm

Differential Revision: D9967064

Pulled By: hermanventer

fbshipit-source-id: bf56872ea42ee8faefc347a6393cdcd9b3c518e9
2018-09-20 05:25:32 -07:00
Nikolai Tillmann
cd7cfb45c9 Fixing dependency issues with cyclic prototype dependencies. (#2556)
Summary:
Release notes: none

This fixes #2555.
We were waiting on the wrong thing in the serializer.
Adding regression tests.
Pull Request resolved: https://github.com/facebook/prepack/pull/2556

Differential Revision: D9949808

Pulled By: NTillmann

fbshipit-source-id: a4ef5ece8c5dab6fa579a20dbb35ce7bf794bfc0
2018-09-20 05:25:31 -07:00
Chris Blappert
feb0c2831f Attach Path Condition to Optimized Functions (#2537)
Summary:
Release Notes: None

Optimized functions will now be evaluated with the path condition at the time of function closure creation.

Resolves issue #2422
Pull Request resolved: https://github.com/facebook/prepack/pull/2537

Differential Revision: D9886282

Pulled By: cblappert

fbshipit-source-id: cae0282903d639ff0d94d0f4091c6f8ef9ef9a98
2018-09-19 18:11:38 -07:00
Chris Blappert
571dc330bb Fix referentialization of optimized functions (#2544)
Summary:
Release Notes: None

Before, during referentialization, we would always default to the global scope if the value was accessed in more than one optimized function scope. Now we look for the outermost optimized function.

This logic already existed in ResidualHeapSerializer, so I refactored it out into `serializer/utils.js`.

Fixes #2428
Pull Request resolved: https://github.com/facebook/prepack/pull/2544

Differential Revision: D9926077

Pulled By: cblappert

fbshipit-source-id: c4ee6c07c7409534e9be14df25b582078a7ec77c
2018-09-19 18:11:37 -07:00
Sapan Bhatia
827146302a Helper to inspect values at a particular AST node (#2554)
Summary:
This is a helper for inspecting values at a particular node in the AST. E.g.

```js

let n = global.__abstract ? __abstract("number", "10") : 10;
let x = {foo:1};
let y = {foo:2};
let c = __abstract("boolean", "c");

let i = 0;
let obj = {};
do {
  i++;
  obj.j = i;
  obj.foo = c ? x : y;
} while (i < n);

__debugValue(obj);        // Breaks with obj in context

inspect = function() {
  return i + " " + obj.j;
};
```
Pull Request resolved: https://github.com/facebook/prepack/pull/2554

Differential Revision: D9922908

Pulled By: sb98052

fbshipit-source-id: dab9cae64a461283d8dec7f0bb7f8fae87a01c78
2018-09-18 13:55:33 -07:00
Caleb Meredith
a4620bd4bf Support constructor returning an unknown abstract value (#2535)
Summary:
The following test case currently fails:

```js
function F() {
  this.a = 1;
  this.b = 2;
  if (global.__abstract) return global.__abstract(undefined, "undefined");
}

const result = new F();

global.inspect = () => JSON.stringify(result);
```

We hit this bug in our internal React Native bundle. I only added support for `base` construction kinds since the template for `derived` construction kinds would get more complicated.
Pull Request resolved: https://github.com/facebook/prepack/pull/2535

Differential Revision: D9906309

Pulled By: trueadm

fbshipit-source-id: 49a71ceaf30a851075879295e63e98ce7e1bbe2d
2018-09-18 05:25:19 -07:00
Nikolai Tillmann
6b34650aed Fixing handling of stack overflows. (#2553)
Summary:
Release notes: User-level stack overflows no longer crash Prepack.

This fixes #2552, and actually a bit more:
- We used to piggy-back on `pushContext` to count stack frames. However, there is no one-to-one correspondance of calls and context, so that wasn't a very good proxy. (In fact, there seem to be calls that don't push a context.) So we now count calls and constructs explicitly.
- Instead of just throwing a `FatalError` when the stack space is exceeded, which in turn causes an invariant violation since there must not be a `FatalError` thrown without a compiler diagnostics having beein issue. Now there is a regular error code PP0045.

Added error handler regression test.
Pull Request resolved: https://github.com/facebook/prepack/pull/2553

Differential Revision: D9889090

Pulled By: NTillmann

fbshipit-source-id: f6f863ee9ef73f258692f215ef75b63b737f5394
2018-09-17 18:55:30 -07:00
Sapan Bhatia
2ad7ac2fe7 Enable and constrain optimized array operator support for InstantRender (#2547)
Summary:
This change ensures that the code generated via optimized array loop operators is correct in the InstantRender setting. It enables the optimization of such functions when the `--instantRender` option is set. Materialization is prevented by ensuring that post-optimization, objects that are reachable from the function are not mutated. Recoverable errors are issued. We also degrade all InstantRender bailouts to recoverable errors, to facilitate debugging. We add a constraint that optimized functions may not be reused.

Resolves #2451 #2448
Pull Request resolved: https://github.com/facebook/prepack/pull/2547

Differential Revision: D9816268

Pulled By: sb98052

fbshipit-source-id: 2112b199de50b80a7a9852a794c082be3bf122e9
2018-09-17 14:55:58 -07:00
Sapan Bhatia
47f6f4b495 Return correct recovery code for FatalError (#2548)
Summary:
In support of #2547. Sometimes, it is more desirable (less costly, better for debugging) to flag a warning for a possibly anomalous condition, than to assume that it is anomalous and enforce it as an error. This change exposes warnings that a user upgrades to errors, so that they can then be enforced as such.
Pull Request resolved: https://github.com/facebook/prepack/pull/2548

Differential Revision: D9884632

Pulled By: sb98052

fbshipit-source-id: c47b57a21aa047b0f3fa2672508f8fb23c04942a
2018-09-17 14:39:36 -07:00
Herman Venter
8ba4fbc916 Make sure that adding a path condition clears negative caches. (#2549)
Summary:
Release note: none

When a new path condition is added to an existing path conditions object, the negative caches must be cleared since the new condition might allow previously failed implications to now succeed. This was already done in one case, but a few others were missed. The clearing code is now centralized and all cases go through it.

While debugging the internal test case that failed because of the caching mistake, I also realized that PathConditions.implies and PathConditions.impliesNot can profitably deconstruct expressions of the form !x before doing the implication check. This also has the advantage that it eliminates a subtle endless recursion situation in a nicer way than the current code.

I've also added some comments in places that caught my eye during debugging.
Pull Request resolved: https://github.com/facebook/prepack/pull/2549

Differential Revision: D9883127

Pulled By: hermanventer

fbshipit-source-id: 06faa709dfecaa4f98b7d0ce5e1c7a9efb6b805f
2018-09-17 14:09:15 -07:00
Chris Blappert
c210fc7d9b Eliminate child-parent read-write conflict errors (#2542)
Summary:
Release Notes: None

This PR makes it so we no longer report conflicts for child optimized functions reading from values that their parents have written.

Couple of things for discussion:
- This creates somewhat confusing behavior because the child functions will take the concrete value after the parent functions' effects have been applied:
```javascript
(function () {
    let obj = {p: 42};
    function f() {
        obj.p += 3;
        function g() { return obj.p; } // Will optimize to `return 47;`
        obj.p += 1;
        __optimize(g);
        obj.p += 1;
        return g;
    }
    __optimize(f);
    global.f = f;
})();
```
- This PR creates the Parent/Child relationship based off `AdditionalFunctionEffects.parentAdditionalFunction` which goes off of syntactic nesting of functions instead of nesting of `__optimize` calls as in the issue. I believe basing the nesting off of `__optimize` calls could lead to somewhat unintuitive results (especially considering we store `parentAdditionalFunction` in `AdditionalFunctionEffects` to be the syntactic parent).

I am not sure if it is needed by Instant Render NTillmann? If it is, we may want to consider changing `AdditionalFunctionEffects.parentAdditionalFunction` to be based off of `__optimize` call nesting as well for consistency.

As an example a slight modification on the example above:
```javascript
(function () {
    let obj = {p: 42};
    function g() { return obj.p; }
    function f() {
        obj.p += 3;
        __optimize(g);
        obj.p += 1;
        return [g, obj];
    }
    __optimize(f);
    global.f = f;
})();
```
With this PR, we report an error. Based off of `__optimize` nesting, we would optimize `g` to `return 46;`. I would expect to see `return 42;` `return 45;` or `return obj.p;` in this case.

- To resolve the above issues, in the future, we could make any values modified by parent optimized functions into abstract values during evaluation for child optimized functions to force their accesses to be recorded in generators .

Resolves #2351
Pull Request resolved: https://github.com/facebook/prepack/pull/2542

Differential Revision: D9803741

Pulled By: cblappert

fbshipit-source-id: baca233c8de81633332b25f0776ed1a9d6c95a60
2018-09-12 17:24:48 -07:00
giftkugel
0b434790d3 Bad command-line for debugDiagnosticSeverity does not crashes Prepack anymore (#2545)
Summary:
This can be a possible fix for https://github.com/facebook/prepack/issues/2509

I have removed the `invariant` method call and added a value check as used for the _invariantMode_ option.

`node lib/prepack-cli.js --debugDiagnosticSeverity foo`

will now generate

`Unsupported debugDiagnosticSeverity: foo`
Pull Request resolved: https://github.com/facebook/prepack/pull/2545

Differential Revision: D9800485

Pulled By: hermanventer

fbshipit-source-id: edc24b4a812b4e32f9c48e05a0799bf4af431991
2018-09-12 15:31:13 -07:00
Nikolai Tillmann
1e1c03c533 Check invariant that path conditions no longer get mutated after being used as a base (#2538)
Summary:
Release notes: None

Otherwise, this could cause issues, as path conditions get captured e.g. in generators.
Pull Request resolved: https://github.com/facebook/prepack/pull/2538

Reviewed By: hermanventer

Differential Revision: D9762541

Pulled By: NTillmann

fbshipit-source-id: 4d12681e3921d2c0f10f3c9f3f0702823a2b0d99
2018-09-10 19:06:10 -07:00
Nikolai Tillmann
a973f896ac Fixing regression with default options. (#2541)
Summary:
Release notes: Fixes invariant violation regression when using webpack-prepack-plugin

This fixes #2540.
I didn't actually test it end-to-end webpack-prepack-plugin, would be great if someone could do that. We need some kind of end-to-end test for this to avoid regressions in the future.
Pull Request resolved: https://github.com/facebook/prepack/pull/2541

Differential Revision: D9756803

Pulled By: NTillmann

fbshipit-source-id: 2bded0dcb0a16369f3d3ff41c2f4d5181c75d67c
2018-09-10 14:27:33 -07:00
kdex
eef69b9463 Substitute v8-profiler with v8-profiler-node8 (#2525)
Summary:
This commit addresses issue #2520. In brief, `v8-profiler` fails to build on recent node versions.
Pull Request resolved: https://github.com/facebook/prepack/pull/2525

Reviewed By: hermanventer

Differential Revision: D9689106

Pulled By: NTillmann

fbshipit-source-id: 9169321bdc23dfbfdf24b50fe7885dab36c5322e
2018-09-07 16:39:23 -07:00
Nikolai Tillmann
59c7677b8c When encountering an internal error, make printing of diagnostics summary consistent with failing. (#2534)
Summary:
Release notes: None
Pull Request resolved: https://github.com/facebook/prepack/pull/2534

Differential Revision: D9729267

Pulled By: NTillmann

fbshipit-source-id: ea011056486447136dea4de8e44ead2192db4875
2018-09-07 15:55:54 -07:00
Herman Venter
2457103e19 Compose without tail duplication (#2523)
Summary:
Release note: none

Closes #2435
Closes #1829

Join.composeWithEffects composes a forked completion with subsequent effects. When two or more forks could end normally, this could result in shallow copies of the subsequent effects. These were then joined together and applied, so it was mostly OK. The generator of the subsequent effects, however, ended up being joined with itself and thus transformed the generator tree to a DAG, which is not desirable for the serializer.

The new approach is to extract a join condition from the forked completion and using it to join the subsequent effects with a newly constructed empty effects. The condition ensures that the subsequent effects are applied only in situations where the forked completion is not abrupt.
Extracting this condition makes for complicated abstract expressions and this uncovered some existing bugs and limitations that are also addressed in this pull request. As a side effect, path conditions are now longer and the time to compile unrolled loops with conditional abrupt completions inside their bodies has gone up so much that the unroll limit had to be lowered.

Please note that the expected output React tests has changed because of re-ordering. I'm none too sure that this re-ordering is necessarily benign, so please review carefully.
Pull Request resolved: https://github.com/facebook/prepack/pull/2523

Differential Revision: D9623729

Pulled By: hermanventer

fbshipit-source-id: 737096bba54a7a2ad300dc29882ea1b7829ac745
2018-09-06 21:55:22 -07:00
Nikolai Tillmann
1d4bd237d4 adding new __replaceFunctionImplementation_unsafe built-in (#2533)
Summary:
Release notes: providing __replaceFunctionImplementation_unsafe built-in

This new built-in allows replacing the method implementation (capture environment, body, ...) of source functions.

As a result, all method calls executed by the Prepack interpreter will be redirected,
and the replacement will carry over to the prepacked code.
Pull Request resolved: https://github.com/facebook/prepack/pull/2533

Reviewed By: hermanventer

Differential Revision: D9693654

Pulled By: NTillmann

fbshipit-source-id: bd28997965e641f58f89f7119fa477c535c0e539
2018-09-06 19:09:26 -07:00
Herman Venter
96174b5ebf Clean up implication logic and do more caching (#2530)
Summary:
Release note: none

This attempts to reduce exponential blowup in the simplifier by doing more caching while computing implications and by imposing a depth limit on the number of simplify and implies calls.

It also tries to make implies and impliesNot more symmetrical, so that things are less ad-hoc.
Pull Request resolved: https://github.com/facebook/prepack/pull/2530

Differential Revision: D9664026

Pulled By: hermanventer

fbshipit-source-id: f7a9135b06298a2b77ad05bf377982a9b37e4ad1
2018-09-06 15:26:24 -07:00
Nikolai Tillmann
f319df5d8c Let prepack CLI fail in the presence of recoverable errors. (#2522)
Summary:
Release notes: Let prepack CLI fail in the presence of recoverable errors.
Pull Request resolved: https://github.com/facebook/prepack/pull/2522

Reviewed By: trueadm

Differential Revision: D9615735

Pulled By: NTillmann

fbshipit-source-id: b90deb174b47f0b9b8886be41e7752eade99b916
2018-09-06 13:57:57 -07:00
Dominic Gannaway
4f0bce54c9 Fix reactFailOnUnsupportedSideEffects (#2532)
Summary:
Release notes: none

Fixes a bug where `reactFailOnUnsupportedSideEffects` should evaluate to `false` if passed as false. Also fixes a lint issue on `master`.
Pull Request resolved: https://github.com/facebook/prepack/pull/2532

Differential Revision: D9662462

Pulled By: trueadm

fbshipit-source-id: 1ffeea55e55a2bde9f1d44c64ac85d7e1b1727cf
2018-09-05 13:58:34 -07:00
Dominic Gannaway
6d5f58e08e Adds more debug-fb-www config for internal testing only (#2531)
Summary:
Release notes:

This adds a `reactFailOnUnsupportedSideEffects` flag for React internal testing with `debug-fb-www` and ignores `try/catch` PP0021 errors for internal testing too. These are intended to be temporary changes purely for internal FB testing.
Pull Request resolved: https://github.com/facebook/prepack/pull/2531

Differential Revision: D9656578

Pulled By: trueadm

fbshipit-source-id: 9339dd8245e5a03d567ca2fd8e24e90152f1e22b
2018-09-05 09:25:43 -07:00
Sapan Bhatia
eeb7842584 Fixed bugs involving unsafe atemporals and improved abstract concrete unions (#2513)
Summary:
Release notes: Fixed bugs that could cause generated code to throw

A refactor of my previous attempt to address #2327, which I had to abandon because it was incompatible with the current implementation of certain modeling primitives. Like the previous version, this PR is an intermediate fix that will be refined in a follow up PR. It consists of three changes:

1) It adds a new helper that discharges values from a union after deriving the abstract value in it if needed.

2) It makes conditionally temporal values safe using a helper called `convertToTemporalIfArgsAreTemporal`.

3) It makes the the abstract and concrete members explicit in the interface to Abstract Concrete Unions. Presently, two code sites make the assumption that the abstract member is the first element of `args`, while all others traverse the list to locate it.

Follow ups to come:
1) Update `convertToTemporalIfArgsAreTemporal` to produce a conditional value left to be simplified by the serializer.
2) Enforce the protocol *temporal args should imply temporal results* more generally (#2489).

Fixes #2327 and #2406
Pull Request resolved: https://github.com/facebook/prepack/pull/2513

Differential Revision: D9636173

Pulled By: sb98052

fbshipit-source-id: 22d63dfb9d0da4b1f6eba4e2f6f88760f5eb03ca
2018-09-04 10:40:21 -07:00
Nikolai Tillmann
067a378227 Propagate functionResultType when resolving an abstract template property access. (#2527)
Summary:
Release notes: None

Added regression test.
This fix gets rid of a spurious internal RecoverableError.
Pull Request resolved: https://github.com/facebook/prepack/pull/2527

Reviewed By: trueadm

Differential Revision: D9622296

Pulled By: NTillmann

fbshipit-source-id: 0d0b7927f6c6f97d7ec43d4109dc52eda9ee7d13
2018-09-01 09:09:20 -07:00
Dominic Gannaway
e845131e03 Improve evaluation of abstract conditionals (#2503)
Summary:
Release notes: none

Currently, when don't really fully deal with abstract conditions fully throughout the Prepack codebase and we usually simply leak/emit a temporal to get around them. So this PR aims at tackling many of the code-sites where they are prevalent by using the internal React bundle to find most of them and address them – with the goal of improving evaluation in cases where we run into conditionals.

With this PR, we now try and resolve different parts of the condition, including conditionals such as `||` and `&&`. This allows us to evaluate potentially far more than before when it comes to product code where we inhabit many deep conditionals. These changes also impact `Object.assign` as it triggered an invariant with `getSnapshot` as it never expected a conditional there. This should also fix https://github.com/facebook/prepack/issues/2323.

I've added some tests to show this but here is an example of the output before and after:

```js
// Input
function fn(x, b) {
  var a = x ? b : { a: 2 };
  return a.a;
}

// Before
  var _2 = function (x, b) {
    var _3 = {};
    _3.a = 2;
    var _$0 = (x ? b : _3).a;
    return _$0;
  };

// After
  var _2 = function (x, b) {
    if (x) {
      var _$0 = b.a;
    }
    return x ? _$0 : 2;
  };
```

For conditional `Object.assign`, the output looks like this (note: we need materializing rather than leaking to better improve the output):
```js
// Input
function fn(x) {
  var a = x ? { a: 1 } : { a: 2 };

  return Object.assign({}, a, { b: 1 });
}

// Before
var _2 = function (x) {
  var _$0 = {
    a: 1
  };
  var _$1 = {
    a: 2
  };
  ({}).a = 1;
  ({}).a = 2;
  var _$2 = {
    b: 1
  };
  var _9 = {};

  var _$3 = _$9(_9, x ? _$0 : _$1, _$2);

  return _9;
};

// After
  var _2 = function (x) {
    return {
      a: x ? 1 : 2,
      b: 1
    };
  };
```

I also took the time to apply the same small changes to the existing code in `CallExpression` so the logic there could also handle `&&` and `||` cases too. Including is a React test that shows that we can now inline a component that we previously weren't able to do.
Pull Request resolved: https://github.com/facebook/prepack/pull/2503

Differential Revision: D9616500

Pulled By: trueadm

fbshipit-source-id: 3888a62da330c64b0395723f8764c3590adc8491
2018-09-01 02:40:03 -07:00
Herman Venter
ebab0a7015 Upgrade Flow and fix new warnings (#2526)
Summary:
Release note: Update to Flow v80

Fix new class of warnings.
Pull Request resolved: https://github.com/facebook/prepack/pull/2526

Differential Revision: D9621986

Pulled By: hermanventer

fbshipit-source-id: 365b73a0aaa68b0f509a1931345d8100ca52c94b
2018-08-31 16:29:56 -07:00
Nikolai Tillmann
5ab6651fb5 Making diagnostics configurable. (#2521)
Summary:
Release notes: Adding CLI options --warnaserror, --diagnosticaserror, --nodiagnostic

This resolves #2517.
- --warnAsError: Turns all warnings into errors.
- --diagnosticAsError: Must be followed by a comma-separated list of non-fatal-error PPxxxx diagnostic codes that should get turned into (recoverable) errors.
- --noDiagnostic: Must be followed by a comma-separated list of non-fatal-error PPxxxx diagnostic codes that should get suppressed.

Adding tests.
Pull Request resolved: https://github.com/facebook/prepack/pull/2521

Differential Revision: D9616473

Pulled By: NTillmann

fbshipit-source-id: c66d7396005699d4d50f801a419fa4879bd8ffc4
2018-08-31 12:39:55 -07:00
Dominic Gannaway
8f03c5f445 Add full support for React.Children.map mock (#2519)
Summary:
Release notes: none

The `React.Children.map` mock was not fully finished and had side-effects. This fixes that and adds a test to show it properly working.
Pull Request resolved: https://github.com/facebook/prepack/pull/2519

Differential Revision: D9614166

Pulled By: trueadm

fbshipit-source-id: b646d13cc46f3747b07a111dc5bc9de295e25212
2018-08-31 09:55:09 -07:00
Sapan Bhatia
e0a90f82ba Transitive materialization for Array operators (#2456)
Summary:
This PR implements a step of the way to getting leaked value analysis working for optimized Array operators. It is desirable to leak as little as possible, so that the operators can be specialized to take into account values in the environment in which they run. In the beginning, we are focusing on the narrow range of scenarios in which this is possible. We will start by enforcing the assumptions that we rely on, and make sure that the code that we generate is correct. Once we have correct code, we will start progressively relaxing the assumptions to increase coverage. The overall plan can be found here: #2452.

More specifically, this PR transitively materializes objects reachable via reads to bindings in the optimized function. This is necessary to snapshot the contents of those objects at specialization time.

Fixes #2405.
Pull Request resolved: https://github.com/facebook/prepack/pull/2456

Differential Revision: D9498939

Pulled By: sb98052

fbshipit-source-id: 16853f97dc781505dba29dce7f28996a0a4e7749
2018-08-31 08:39:49 -07:00
Dominic Gannaway
43d480cfad Support bound function values for ReactElement types (#2518)
Summary:
Release notes: none

Add support for bound function values for `ReactElement` `type`.
Pull Request resolved: https://github.com/facebook/prepack/pull/2518

Differential Revision: D9612253

Pulled By: trueadm

fbshipit-source-id: f6d0b937c5892cfa44297c12a48e73197b50756c
2018-08-31 07:24:16 -07:00
Sebastian Markbage
54be9b535c Re-land typed descriptors and printer (#2511)
Summary:
Release notes: landing two previously reverted PRs

I found the issue.

Flow doesn't support optional fields in classes. This effectively becomes enforced with Babel 7 since it treats the type annotations as field initializers. Which means that these fields always gets created.

We happened to only use this newer plugin for class fields internally which broke our builds only there.

2b4546d Use `undefined` instead of missing to represent absent field in descriptors. Fixed all the callsites that checks for `hasOwnProperty` or `in` that I could find.

922d40c Fixes a Flow issue in the text printer.

I filed a [follow up issue for ObjectValue](https://github.com/facebook/prepack/issues/2510) since it has the same problem.
Pull Request resolved: https://github.com/facebook/prepack/pull/2511

Reviewed By: trueadm

Differential Revision: D9569949

Pulled By: sebmarkbage

fbshipit-source-id: f8bf84c4385de4f0ff6bcd45badacd3b8c88c533
2018-08-31 05:54:23 -07:00
Caleb Meredith
69699c2d39 Support constructors that return an object but also throw (#2501)
Summary:
The following example currently fails with a `FatalError`.

```js
function F() {
  const b = global.__abstract ? global.__abstract("boolean", "false") : false;
  if (b) throw new Error("abrupt");
  return { p: 42 };
}

const result = new F();

global.inspect = () => JSON.stringify(result);
```

This is where the `FatalError` is thrown:

f59798b196/src/methods/function.js (L264-L267)

The majority of this PR is refactoring the type of construction functions to return a `Value` (which includes `AbstractValue`) instead of a concrete `ObjectValue`. I updated call sites to include a `throwIfNotConcreteObject()` instead of handling abstract values in many cases.

Would it be useful to add some general `Value.prototype.map` utility function? Which would provide `ConcreteValue`s to a mapper function and abstract over conditional values, `__bottomValue`, and more.

[Babel return an object from constructors for classes that call `super()`](https://babeljs.io/repl#?babili=false&browsers=&build=&builtIns=false&spec=false&loose=false&code_lz=MYGwhgzhAEAa0G8C-AoFpIwJrQKYA8AXXAOwBMZ4EVppgB7EiQgJwFdhD6WAKASkQ1a0CGwAOuXnwDcQ2gEsAZtB4AjAYQAWLegHdoJXPoCiLHbwDkYVezGELMoalRA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=true&fileSize=false&timeTravel=false&sourceType=module&lineWrap=false&presets=es2015%2Creact%2Cstage-1%2Cstage-2&prettier=false&targets=&version=6.26.0&envVersion=) to follow the spec. This means we hit an invariant on all React class components which might throw. Which happens to be quite a few given the prevalent use of `nullthrows()` or `invariant()` in Facebook codebases.
Pull Request resolved: https://github.com/facebook/prepack/pull/2501

Reviewed By: trueadm

Differential Revision: D9602216

Pulled By: calebmer

fbshipit-source-id: a9ba6d4fb6e47cd6524f1a3d7981c08bcdd00a98
2018-08-31 03:39:31 -07:00
Caleb Meredith
8a9457d844 Abstract empty values should fail RequireObjectCoercible (#2515)
Summary:
This fixes a bug it took me a while to track down. Unfortunately creating a repro was really difficult. I was observing the following invariant in `Reference` being triggered.

fddfc6f0c5/src/environment.js (L1425-L1431)

Digging in, the bad base was a deep conditional `AbstractValue` where all the leaf nodes were `EmptyValue` and `__bottomValue`. (Constructed from a number of `try`/`catch`/`throw`s.) This `AbstractValue` _should_ have simplified to just `EmptyValue` then `RequireObjectCoercible()` should have thrown a runtime `TypeError` after seeing the `EmptyValue`. This is what I observed in local tests when trying to reproduce this issue.

After looking at the error in the large React Native bundle I’m working in I discovered that the simplifier was throwing an error since the simplification count was exceeded. This is fine and normal. The issue was that `RequireObjectCoercible()` does not handle complex empty `AbstractValue`s well. If failing simplification is a normal part of Prepack operation we should make sure methods like `RequireObjectCoercible()` can handle complex `AbstractValue`s as well as simple ones.

This PR does that.
Pull Request resolved: https://github.com/facebook/prepack/pull/2515

Reviewed By: trueadm

Differential Revision: D9602146

Pulled By: calebmer

fbshipit-source-id: 359c74c646eeb619ba2e78b50eafe10b2e2fb133
2018-08-31 03:10:19 -07:00
Nikolai Tillmann
b3bcd73102 Add invariant that an object with modified properties must be valid. (#2278)
Summary:
Release notes: None

The uncovered bug is tracked in #2279.
Pull Request resolved: https://github.com/facebook/prepack/pull/2278

Differential Revision: D9472482

Pulled By: NTillmann

fbshipit-source-id: 5d6e24abd76fd83e9078c3908fa0be0e7f0b2c51
2018-08-31 02:39:23 -07:00
Nikolai Tillmann
12ae403cef Removing --serialize and --residual options (#2504)
Summary:
Release notes: Removing --serialize and --residual options from Prepack (CLI)

Pull Request resolved: https://github.com/facebook/prepack/pull/2504

Reviewed By: trueadm

Differential Revision: D9582602

Pulled By: NTillmann

fbshipit-source-id: d30a6ef662de5ebddd5e7d615ea37b3f772ce93d
2018-08-31 02:24:30 -07:00
Herman Venter
3f2445db76 Compose without tail duplication (#2460)
Summary:
Release note: none

Closes #2435
Closes #1829

Join.composeWithEffects composes a forked completion with subsequent effects. When two or more forks could end normally, this could result in shallow copies of the subsequent effects. These were then joined together and applied, so it was mostly OK. The generator of the subsequent effects, however, ended up being joined with itself and thus transformed the generator tree to a DAG, which is not desirable for the serializer.

The new approach is to extract a join condition from the forked completion and using it to join the subsequent effects with a newly constructed empty effects. The condition ensures that the subsequent effects are applied only in situations where the forked completion is not abrupt.

Extracting this condition makes for complicated abstract expressions and this uncovered some existing bugs and limitations that are also addressed in this pull request. As a side effect, path conditions are now longer and the time to compile unrolled loops with conditional abrupt completions inside their bodies has gone up so much that the unroll limit had to be lowered.

Please note that the expected output React tests has changed because of re-ordering. I'm none too sure that this re-ordering is necessarily benign, so please review carefully.
Pull Request resolved: https://github.com/facebook/prepack/pull/2460

Reviewed By: trueadm

Differential Revision: D9486135

Pulled By: hermanventer

fbshipit-source-id: 87147384c285e051542c277e41b3176b91ab165d
2018-08-31 01:58:40 -07:00
Herman Venter
af6a10c93b Fix CSE in back-end (#2516)
Summary:
Release note: none

This fixes two problems uncovered while debugging the failure of PR #2460 when run on a large internal test case:
1) CSE did not fix up recently introduced aliases of expressions.
2) The serializer logic visited array elements that were not visited because of recently introduced leak logic.
Pull Request resolved: https://github.com/facebook/prepack/pull/2516

Differential Revision: D9599235

Pulled By: hermanventer

fbshipit-source-id: a2047227b4aa2e0e2def7d8e7ebe0724a9525160
2018-08-30 18:39:20 -07:00
Caleb Meredith
fddfc6f0c5 Don’t evaluate catch block with an infeasible JoinedNormalAndAbruptCompletions (#2507)
Summary:
The following example fails with an invariant:

```js
try {
  try {
    const b = __abstract("boolean", "false");
    if (b) throw new Error("throw");
  } catch (error) {}
} catch (error) {
  console.log(error.message);
}
```

```
Invariant Violation: assuming that false equals true is asking for trouble
debug-fb-www.js:208
This is likely a bug in Prepack, not your code. Feel free to open an issue on GitHub.
    at invariant (/Users/calebmer/prepack/src/invariant.js:18:15)
    at PathImplementation.withCondition (/Users/calebmer/prepack/src/utils/paths.js:132:17)
    at joinTryBlockWithHandlers (/Users/calebmer/prepack/src/evaluators/TryStatement.js:81:35)
    at _default (/Users/calebmer/prepack/src/evaluators/TryStatement.js:30:47)
    at LexicalEnvironment.evaluateAbstract (/Users/calebmer/prepack/src/environment.js:1379:20)
    at LexicalEnvironment.evaluate (/Users/calebmer/prepack/src/environment.js:1367:20)
    at LexicalEnvironment.evaluateCompletion (/Users/calebmer/prepack/src/environment.js:1102:19)
    at LexicalEnvironment.evaluateCompletionDeref (/Users/calebmer/prepack/src/environment.js:1095:23)
    at _default (/Users/calebmer/prepack/src/evaluators/Program.js:235:17)
    at LexicalEnvironment.evaluateAbstract (/Users/calebmer/prepack/src/environment.js:1379:20)
```

What happens is we end up with a completion structure as follows when going into the outer `catch`:

```
- JoinedNormalAndAbrubtCompletions (joinCondition = x)
  - SimpleNormalCompletion
  - JoinedNormalAndAbrubtCompletions (joinCondition = x)
    - ThrowCompletion
    - SimpleNormalCompletion
```

The inner `JoinedNormalAndAbrubtCompletions` is the inner `try` block completion. The outer `JoinedNormalAndAbrubtCompletions` is the join of the inner `try`/`catch` blocks. Notably the `ThrowCompletion` is completely unreachable. However it is still there.

Ideally we would refine the completions. I tried this, but realized the `composedWith`, `pathConditionsAtCreation`, and `savedEffects` on `JoinedNormalAndAbrubtCompletions` were more to handle then I originally bargained for to fix my original test case. Instead I picked a simple fix for this specific case of `try`/`catch`. When we `AbstractValue.createJoinConditionForSelectedCompletions` we get a concrete `false` value. So I check if it is false and don’t execute the catch block if it is. The condition can never be concretely true. Otherwise we’d unconditionally catch an error in the block above.

Happy to take suggestions for a more general fix.
Pull Request resolved: https://github.com/facebook/prepack/pull/2507

Differential Revision: D9583244

Pulled By: calebmer

fbshipit-source-id: 7693efef5e967c90d5a4c54f10ef2c137f264ef8
2018-08-30 10:56:13 -07:00
Sebastian Markbage
ec3638915e Revert typed descriptors and printer (#2508)
Summary:
23c5da579c
and
2b68c6e405
Pull Request resolved: https://github.com/facebook/prepack/pull/2508

Differential Revision: D9566539

Pulled By: sebmarkbage

fbshipit-source-id: efefa126a141134969bbe94c6033110dae7a7ab0
2018-08-29 19:09:17 -07:00
Dominic Gannaway
f062f3468b Optimize a fast path for instanceof binary expressions (#2506)
Summary:
Release notes: none

Looking through our internal bundles and there are frequent cases where `instanceof` is used where the left-hand side is a primitive and the right-hand side is an abstract value. In the case where the left-hand side is a primitive and the right-hand side is a simple object, the instanceof binary expression should always return `false`.
Pull Request resolved: https://github.com/facebook/prepack/pull/2506

Differential Revision: D9567344

Pulled By: trueadm

fbshipit-source-id: 7333f3b81627657c184c77d4cfffd4511bee0cbf
2018-08-29 18:37:05 -07:00
Caleb Meredith
dfa38c2bc4 Add basic support for throws in React (#2502)
Summary:
Starts adding basic support for throws in React. Concretely there are three things this PR does outside of adding tests:

1. Allowing throw side-effects.
2. Removing an invalid invariant. `createdObjects` changes after calling `realm.captureEffects()` and this is expected. Later code which joins/incorporates effects will merge in the captured `createdObjects`.
3. Don’t catch `AbruptCompletion`s and handle them as errors. Instead let them propagate up to the nearest `realm.evaluateForEffects()`. (Or similar function.)

I have not run this against the internal web bundle yet. Against the internal React Native bundle we get pretty far without removing throws with these changes.
Pull Request resolved: https://github.com/facebook/prepack/pull/2502

Reviewed By: trueadm

Differential Revision: D9566580

Pulled By: calebmer

fbshipit-source-id: 3716a6afd5fc3ae824182ee50e38e51d72126dc2
2018-08-29 18:37:03 -07:00
Dominic Gannaway
e423a076fa Fix for React.cloneElement (#2505)
Summary:
Release notes: none

Fixes mixing functionality from React.cloneElement, where the original ReactElement props where missing from being copied to the new props.
Pull Request resolved: https://github.com/facebook/prepack/pull/2505

Differential Revision: D9565338

Pulled By: trueadm

fbshipit-source-id: f04c15b3a640f87de6de8326511e8e4bdfa328a7
2018-08-29 16:55:42 -07:00
Nikolai Tillmann
23c5da579c Dumping an intermediate representation (#2493)
Summary:
Release notes: None

This resolves #1944.

The functionality that Prepack provides can be seen as being done by two separate engines:
1) There's the "front-end", which does symbolic execution / abstract interpretation,
   computing "effects" / "generator trees" for the global code and optimized functions.
2) There's the "back-end", which takes this intermediate representation, computes what's
   reachable, and then turns it into a new executable program by performing transformations
   such as breaking cycles.

Before, Prepack developers had very few tools available to understand what goes on between the
front-end and back-end. Usually, they just look at the final output, imagine what the
intermediate representation might have been, or maybe use to debugger to poke around
memory locations, or to invoke helper functions to inspect live state that way, hoping the debugger doesn't crash along the way.

This PR (and other associated PRs such as #2490, #2491) try to improve that state by turning the intermediate representation into a first-class data structure that is printable into a human-readable textual form. This will help...
- in understanding what's going on
- enabling different back-ends by ensuring that there's a first-class intermediate representation
- enabling future transformations on a well-defined intermediate data structure, ideally breaking up what the current serializer implementation does
- new ways of testing, e.g. via snapshots of the intermediate representation, or
  (once there is a parser) feeding hand-written IR into the back-end

For example, for this program...
```js
let x = __abstract("number", "(x)");
if (x > 42) {
  let t = Date.now();
  let u = 2 + 3
  console.log(t + u);
} else {
  global.result = x;
}
```
... the IR would currently look like this:
```
(entry point): "main(#0)"
  * value#0 = ">"(@"(x)", 42)
  if value#0
    then: "evaluateNodeForEffects(#4)"
      path conditions value#0
      _$0 := ABSTRACT_FROM_TEMPLATE<template source @"global.Date.now()">[isPure]
      * value#1 = "+"(5, _$0)
      CONSOLE_LOG("log", value#1)
    else: "evaluateNodeForEffects(#11)"
      * value#2 = "!"(value#0)
      path conditions value#2
      GLOBAL_ASSIGNMENT(@"(x)", "result")
```
Notes:
- Indentation reflects structure of the generator tree
- Each line encodes some information. Some of the information is atemporal, e.g.
  - `* value#N = f(args)` // atemporal abstract value
- Some of the information is temporal, e.g.
  - `_$N := op-type<op-data>(args)[metadata]` // generator entry that defines a temporal value
    - `op-data` contains various essential data
    - `args` tends to be a projection of `data` capturing all values that must be visited, but it's not consistent
    - `metadata` is information that helps the visitor compute minimal reachability, but it's not semantically relevant.
  - `op-type<op-data>(args)[metadata]` // generator entry that does not define a temporal value
  - `if ... then ... else`.

```js
(function() {
    let obj = {};
    obj.p = obj;
    global.result = obj;
})();
```
=>
```
(entry point): "main(#0)"
  * object#14 = ObjectValue(properties [p], $Prototype @"Object.prototype")
  * object#14.p = PropertyBinding(descriptor PropertyDescriptor(writable, enumerable, configurable, value object#14))
  GLOBAL_ASSIGNMENT(object#14, "result")
```

Things get slightly ugly with functions.
```js
function f() { }
```
=>
```
(entry point): "main(#0)"
  * declEnv#1 = DeclarativeEnvironmentRecord()
  * globEnv#2 = GlobalEnvironmentRecord($DeclarativeRecord declEnv#1, $ObjectRecord declEnv#1, $VarNames [f], $GlobalThisValue global)
  * lexEnv#0 = LexicalEnvironment(destroyed, environment record globEnv#2)
  * func#13 = ECMAScriptSourceFunctionValue($ConstructorKind base, $ThisMode global, $FunctionKind normal, $FormalParameters 0, $Environment lexEnv#0, properties [arguments, length, caller, prototype, name], $Prototype @"Function.prototype")
  * func#13.arguments = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value undefined))
  * func#13.length = PropertyBinding(descriptor PropertyDescriptor(configurable, value 0))
  * func#13.caller = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value undefined))
  * object#14 = ObjectValue(properties [constructor], $Prototype @"Object.prototype")
  * object#14.constructor = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value func#13))
  * func#13.prototype = PropertyBinding(descriptor PropertyDescriptor(writable, value object#14))
  * func#13.name = PropertyBinding(descriptor PropertyDescriptor(configurable, value "f"))
  GLOBAL_ASSIGNMENT(func#13, "f")
```

Things get really ugly with optimized functions, but that's what it is right now:
```js
function f() { return 2 + 5; }
__optimize(f);
```
=>
```
(entry point): "main(#0)"
  * declEnv#1 = DeclarativeEnvironmentRecord()
  * globEnv#2 = GlobalEnvironmentRecord($DeclarativeRecord declEnv#1, $ObjectRecord declEnv#1, $VarNames [f], $GlobalThisValue global)
  * lexEnv#0 = LexicalEnvironment(destroyed, environment record globEnv#2)
  * func#13 = ECMAScriptSourceFunctionValue($ConstructorKind base, $ThisMode global, $FunctionKind normal, $FormalParameters 0, $Environment lexEnv#0, properties [arguments, length, caller, prototype, name], $Prototype @"Function.prototype")
  * func#13.arguments = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value undefined))
  * func#13.length = PropertyBinding(descriptor PropertyDescriptor(configurable, value 0))
  * func#13.caller = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value undefined))
  * object#15 = ObjectValue(properties [constructor], $Prototype @"Object.prototype")
  * object#15.constructor = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value func#13))
  * func#13.prototype = PropertyBinding(descriptor PropertyDescriptor(writable, value object#15))
  * func#13.name = PropertyBinding(descriptor PropertyDescriptor(configurable, value "f"))
  GLOBAL_ASSIGNMENT(func#13, "f")
=== optimized function func#13
  (entry point): "AdditionalFunctionEffects(#12)"
    RETURN(7)
  * object#16 = ArgumentsExotic(properties [length, callee], symbols [@"Symbol.iterator"], $Prototype @"Object.prototype")
  * object#16.length = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value 0))
  * declEnv#1 = DeclarativeEnvironmentRecord()
  * globEnv#2 = GlobalEnvironmentRecord($DeclarativeRecord declEnv#1, $ObjectRecord declEnv#1, $VarNames [f], $GlobalThisValue global)
  * lexEnv#0 = LexicalEnvironment(destroyed, environment record globEnv#2)
  * func#13 = ECMAScriptSourceFunctionValue($ConstructorKind base, $ThisMode global, $FunctionKind normal, $FormalParameters 0, $Environment lexEnv#0, properties [arguments, length, caller, prototype, name], $Prototype @"Function.prototype")
  * func#13.arguments = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value undefined))
  * func#13.length = PropertyBinding(descriptor PropertyDescriptor(configurable, value 0))
  * func#13.caller = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value undefined))
  * object#15 = ObjectValue(properties [constructor], $Prototype @"Object.prototype")
  * object#15.constructor = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value func#13))
  * func#13.prototype = PropertyBinding(descriptor PropertyDescriptor(writable, value object#15))
  * func#13.name = PropertyBinding(descriptor PropertyDescriptor(configurable, value "f"))
  * object#16.callee = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value func#13))
  * object#16.@"Symbol.iterator" = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value @"Array.prototype.values"))
  * object#16.$Prototype = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value @"Object.prototype"))
  * object#16.$Extensible = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value true))
  * object#16._isPartial = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#16._isLeaked = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#16._isSimple = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#16._simplicityIsTransitive = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#16._isFinal = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#17 = ObjectValue($Prototype null)
  * object#17.$Prototype = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value null))
  * object#17.$Extensible = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value true))
  * object#17._isPartial = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#17._isLeaked = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#17._isSimple = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#17._simplicityIsTransitive = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#17._isFinal = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#18 = ObjectValue(properties [next], $Prototype @"([][Symbol.iterator]().__proto__.__proto__)")
  * func#19 = NativeFunctionValue(properties [length, name], $Prototype @"Function.prototype")
  * func#19.length = PropertyBinding(descriptor PropertyDescriptor(configurable, value 0))
  * func#19.name = PropertyBinding(descriptor PropertyDescriptor(configurable, value "next"))
  * object#18.next = PropertyBinding(descriptor PropertyDescriptor(writable, configurable, value func#19))
  * object#18.$Prototype = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value @"([][Symbol.iterator]().__proto__.__proto__)"))
  * object#18.$Extensible = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value true))
  * object#18._isPartial = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#18._isLeaked = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#18._isSimple = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#18._simplicityIsTransitive = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#18._isFinal = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * object#18.$IteratedList = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(some array))
  * func#19.$Prototype = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value @"Function.prototype"))
  * func#19.$Extensible = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value true))
  * func#19._isPartial = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * func#19._isLeaked = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * func#19._isSimple = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * func#19._simplicityIsTransitive = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  * func#19._isFinal = PropertyBinding(internal slot, descriptor InternalSlotDescriptor(value false))
  modified property bindings: [object#16.$Prototype, object#16.$Extensible, object#16._isPartial, object#16._isLeaked, object#16._isSimple, object#16._simplicityIsTransitive, object#16._isFinal, object#17.$Prototype, object#17.$Extensible, object#17._isPartial, object#17._isLeaked, object#17._isSimple, object#17._simplicityIsTransitive, object#17._isFinal, object#16.length, object#16.@"Symbol.iterator", object#16.callee, object#18.$Prototype, object#18.$Extensible, object#18._isPartial, object#18._isLeaked, object#18._isSimple, object#18._simplicityIsTransitive, object#18._isFinal, object#18.$IteratedList, func#19.$Prototype, func#19.$Extensible, func#19._isPartial, func#19._isLeaked, func#19._isSimple, func#19._simplicityIsTransitive, func#19._isFinal, func#19.length, func#19.name, object#18.next]
  created objects: [object#16, object#17, object#18, func#19]
  result: SimpleNormalCompletion(value 7)
```

There are still a good number of things left to do. In particular:
- further simplify printing to make it more readable (and writable)
- further extend printed format to make it round-trippable
- some details of the current IR is really just an artefact of 2 years of hacking. It is in need of some additional
  rounds of refactorings and simplifications.
  - Particularly problematic / overly complicated are invariants INVARIANT, FULL_INVARIANT_ABSTRACT, FOR_IN, REACT_SSR_TEMPLATE_LITERAL
  - In `TemporalOperationEntry`, there's some duplication going on with `args` and `data`. Consider eliminating `args` and deriving this information when needed from `data`.
  - `OperationDescriptorData` could use some structure, or a (sub)type hierarchy.
  - There are already dedicated generator entry classes for some operations, and then there is `TemporalOperationEntry` with its `data` dumping ground for everything else. This is all a bit arbitrary and should be unified.
  - ...there's much more cruft.

In a way, this PR just provides yet another way of dumping values and generators. Some of the other existing ways should be consolidated or killed.

Added option --ir to test-runner to activate (and test) IR dumping.
Pull Request resolved: https://github.com/facebook/prepack/pull/2493

Differential Revision: D9560883

Pulled By: NTillmann

fbshipit-source-id: 70920c8e1b4139c69329d8f5ab6e6267a35f058b
2018-08-29 13:12:59 -07:00
Herman Venter
838827183b Cache path implications (#2494)
Summary:
Release note: Speed up simplifier by using an implication cache per path branch

The realm's path conditions is now a class instances and an explicit tree, along with caches for expressions that have already been checked for true/false using Path.implies on the current set of path conditions.

The AbstractValueImplicationCounter is still there as flag, to be renamed later. It is no longer used as a global k-limit, but enables k-limits on the cost of constructing a new set of path conditions. When React is the target, path conditions are not re-specialized. This leads to a very nice performance win for the large React internal test.

A number of tweaks to the simplifier were needed to get tests to pass. Some of these were borrowed from PR #2460.
Pull Request resolved: https://github.com/facebook/prepack/pull/2494

Reviewed By: trueadm

Differential Revision: D9554820

Pulled By: hermanventer

fbshipit-source-id: 5fdc550499975fe11c0c954b9502cd4eeab2bafe
2018-08-29 05:38:58 -07:00
Sebastian Markbage
2b68c6e405 Nominally Type Descriptors (#2473)
Summary:
Release notes: Refactor of joined descriptors. Expect a slight performance regression. Will fatal in more cases that we would previously silently possibly generate the wrong code.

Currently we have three types of property descriptors. 1) Descriptors used by internal slots. 2) Normal concrete descriptors. 3) Abstract joined descriptors.

These are all typed as arbitrary an inexact object where all the fields are optional. That means that essentially any object with any typo can be assigned to a descriptor.

We are also not forced to deal with the joined descriptor case. Almost everywhere we assume that joined descriptors are really just a generic descriptor object which doesn't have any attributes on it.

There are so many small bugs related to this so I figured it's time to start dealing with it.

This PR turns this inexact object into nominally typed PropertyDescriptor, AbstractJoinedDescriptor and InternalSlotDescriptor. Essentially the same model as values.

Thanks to this Flow forces me to ensure that I've covered all of these cases. I've dealt with it in the cases I figured I could figure it out and where it was necessary such as the serializer/join/widen. In all other cases where we don't know, I ensure that we throw a fatal error instead of assuming that a joined descriptor is an empty descriptor.
Pull Request resolved: https://github.com/facebook/prepack/pull/2473

Differential Revision: D9526419

Pulled By: sebmarkbage

fbshipit-source-id: 1d3556b2d4608c02ba2570651f4e6a765fa0eea6
2018-08-28 13:54:18 -07:00
Nikolai Tillmann
22b7e1eb53 Simplifying / fixing OperationDescriptorData (#2490)
Summary:
Release notes: None

- Fixing type of `quasis` in Babel and as field
- Instead of storing callTemplate as a derived function, store instead the source string (working towards having a human-readable generator intermediate format)
Pull Request resolved: https://github.com/facebook/prepack/pull/2490

Differential Revision: D9540696

Pulled By: NTillmann

fbshipit-source-id: d7ab8c68857d4b8b4e584894edb3781dce3db2b2
2018-08-28 10:10:57 -07:00