Summary:
Release note: none
Resolves#2238
This is a quick fix for the above issue. The underlying cause is that we do not construct completions with effects, but rely on incremental updates in special situations, such as the constructor for ForkedAbruptCompletions.
I'll try to fix the underlying cause in a subsequent PR.
Pull Request resolved: https://github.com/facebook/prepack/pull/2239
Differential Revision: D8795886
Pulled By: hermanventer
fbshipit-source-id: 677f2481ae3d6463a73f36a7e7106afbd92b068e
Summary:
…local state
The logic was already there for the React Compiler's invocations of evaluatePure, this PR just generalizes it a little to be used for optmized functions as well.
Additionally, adds the ability to check for compiler info/warning logs in test-runner + updates test-error-handler.
See #1589
Pull Request resolved: https://github.com/facebook/prepack/pull/2175
Differential Revision: D8786744
Pulled By: cblappert
fbshipit-source-id: 110a4732dd6bd129b4d91047c3c9a24f5249a5e9
Summary:
Release Notes: None
Before `__optimize` wouldn't work when called in a conditional context, now if `__optimize` is called in some conditional context, we extract the FunctionValue from the AbstractValue in the `__optimizedFunctions` map.
Also fixes a bug where __optimize would silently noop when given something other than an `ECMAScriptSourceFunctionValue` causing two tests to fail with `TypeError`. Issue #2213 is setup to track this.
Pull Request resolved: https://github.com/facebook/prepack/pull/2214
Differential Revision: D8785643
Pulled By: cblappert
fbshipit-source-id: 3db992d693dd431aa8a2c5e6eb7ad0a1ecb6b79e
Summary:
This will fail CI if we forgot to run `yarn prettier` before committing.
We do the same in React repo. It prevents committing stale files that later cause unexpected changes.
Pull Request resolved: https://github.com/facebook/prepack/pull/2212
Differential Revision: D8784406
Pulled By: gaearon
fbshipit-source-id: ca948b8e088be8886c8ba865f280ba8d72750f69
Summary:
Release notes: Add ability to rewrite generated code via global.__output
When a special global variable __output is set to an object,
then all global generator entries are forgotten
and replaced by a series of assignments to reflecting the key-value
pairs of the __output object.
This is needed for instant render to emit single render functions only.
Pull Request resolved: https://github.com/facebook/prepack/pull/2218
Differential Revision: D8778269
Pulled By: NTillmann
fbshipit-source-id: 1dbc5ddd68aa5fd7845da8a7f551c8c7ba2b8919
Summary:
Release notes: adds an optimization to Object.assign that attempts to merge calls together where possible
I frequently see `Objet.assign` calls litter our internal bundle. Many of them can actually be merged together to reduce bloat and runtime overhead (on that matter, `Object.assign` isn't a cheap call). We do this by adding a new `TemporalObjectAssignEntry` entry, that allows us to add some fine-tuning of Object.assign temporal entries we create.
The new `TemporalObjectAssignEntry` entry has an optimization that aims to merge entries by checking if linked nodes, specifically the `Object.assign` calls `to` field, to see if it can literally merge the arguments of many `Object.assign`s together. If a `to` is visited and can't be omitted, it doesn't try to apply this optimization. What we end up with, is a single `Object.assign` call and the others all get dead-code eliminated away because of the `mutatesOnly` logic from earlier.
Pull Request resolved: https://github.com/facebook/prepack/pull/2206
Reviewed By: NTillmann
Differential Revision: D8775391
Pulled By: trueadm
fbshipit-source-id: 41e5d6bb1d51fcfff66b2fe758bd51492ec472d9
Summary:
> I’m learning the Prepack/React Fusion codebase, so incorrect assumptions and limited a understanding of systems on my part are both very likely.
While I was experimenting with the React Compiler codebase I found the following invariant violation with the test case after that when using `create-element` as the `reactOutput`.
```
Invariant Violation: value must have been visited
```
```js
const React = require("react");
__evaluatePureFunction(() => {
function Foo(props) {
return <React.Fragment />;
}
__optimizeReactComponentTree(Foo);
module.exports = Foo;
});
```
[[Prepack REPL]](https://prepack.io/repl.html#MYewdgzgLgBASgUwIbFgXhgJwQRwK4CW2AFAETYpSkCUA3AFD0D6TCAbkgDZ5JQIAKebADE8YVAXDFi1GGgB8MAN70YMAGZiJ4GMJAhiAB0whDEWSrVrsUIWBgAeRJQB0wzEgDmAWwRhYAPTyDGoAvoxqLKZQBN4EAF4IzqgAwiDehuB+UAAq2AjEeiB0ETDeIAAmeJwILggAHpmYUBByuvoMoSVAA)
After digging in more, I discovered that this was the same issue which required some clowniness in the React Compiler tests to workaround.
e3f4262c9d/test/react/setupReactTests.js (L116-L119)
The problem with my example is that the React library was not being visited when a `React.Fragment` appeared even though the serializer needed the library to be visited to output code.
This diff makes sure we visit the React library when we see a `React.Fragment` and makes sure we don’t over visit the React library in `jsx` mode.
I also refactored this area of the code and added comments. Let me know if my refactors or comments don’t make sense.
Pull Request resolved: https://github.com/facebook/prepack/pull/2223
Reviewed By: trueadm
Differential Revision: D8774047
Pulled By: calebmer
fbshipit-source-id: 775a626b8a6bd33a5366e6dae6727350835b060e
Summary:
Release note: none
Resolves: #2207
When a PossiblyNormalCompletion has more than one normal path, it is not correct to push only the path leading to the nominally normal completion. Surprisingly, this has not caused all sorts of havoc so far, but clearly this needs fixing.
Interestingly, these changes did uncover some latent bugs, hence the additional changes here.
Testing this more thoroughly will be much easier once PNC composition is fixed. That will take a while, but this PR will help facilitate that.
Pull Request resolved: https://github.com/facebook/prepack/pull/2201
Differential Revision: D8754966
Pulled By: hermanventer
fbshipit-source-id: 220ddc80eaff69b8ee93f75c1943ee1a16adcdee
Summary:
Release notes: none
In an attempt to pull out some of the work from https://github.com/facebook/prepack/pull/2148 to make things easier to consume and review. This PR is one part, where we check the temporal alias values (if an object value has it) and see if we can dedupe the trees. Example below:
Closes https://github.com/facebook/prepack/pull/2193
Differential Revision: D8732542
Pulled By: trueadm
fbshipit-source-id: 352d0048acfef69b5a257c0fe280435fa7baaa7f
Summary:
Release notes: none
We were missing logic for handling abstract arrays with unknown numeric properties when we attempt to get a partial value on the array. I've added a regression test too.
Closes https://github.com/facebook/prepack/pull/2205
Differential Revision: D8732181
Pulled By: trueadm
fbshipit-source-id: 6002eac4b7d4d0b842407a3bb9ea9bcec19f486b
Summary:
Release notes: adds React Native mocks to Prepack
This adds React Native mocks to Prepack and a few basic tests to demonstrate inlining of `View` and `Text`.
Closes https://github.com/facebook/prepack/pull/2096
Differential Revision: D8723932
Pulled By: NTillmann
fbshipit-source-id: 38bd265cd8935ebdf30266ec337378b4ea5b09d6
Summary:
Release notes: Support dynamic invariants via __assume
Resolves#2171. Implements an __assume primitive that injects dynamic invariants into the code.
Source:
```js
x = __abstract("number", "5");
__invariant(x==5, "x should be 5");
```
Generated:
```js
(function () {
var _$0 = this;
var _0 = 5;
_$0.x = _0;
var _1 = _0 == 5;
if (!_1) {
throw new Error("x should be 5");
}
}).call(this);
```
Closes https://github.com/facebook/prepack/pull/2195
Reviewed By: hermanventer
Differential Revision: D8725726
Pulled By: sb98052
fbshipit-source-id: 28db3272199cdb9ae669062344eb82f0ef619bd4
Summary:
Release note: Enhanced handling of Array.map applied to abstract arrays
Fixes#2169.
If an abstract array is the join or a few concrete arrays, we apply the map over all of the concrete arrays and join the results. This is a bit of a hack, much like what we have for switch statements. The code from the latter has been factored out and reused for this.
Closes https://github.com/facebook/prepack/pull/2173
Differential Revision: D8721507
Pulled By: hermanventer
fbshipit-source-id: e08f2dc1d7e78c7b59f9ff7c76ad54b398b8afe9
Summary:
Release note: Fix temporal assignments to intrinsics that happen inside non deterministic loops
Tweak the property set logic to not short circuit when the target object is intrinsic and the RH value is the same as the current (tracked) property value.
Also fix the code generator for loop bodies to not get upset when the lh side is temporal, but rh side is not widened (because it is a constant).
Closes https://github.com/facebook/prepack/pull/2197
Differential Revision: D8721001
Pulled By: hermanventer
fbshipit-source-id: d38565a40fa7ab8b4e30596f0e1dcfc655a4fb5e
Summary:
Release note: special case expression simplification for Instant Render
When instant render is enabled turn x === undefined || x === null into __cannotBecomeObject(x) so that Instant Render can easily compile it down to a single byte code.
Closes https://github.com/facebook/prepack/pull/2188
Differential Revision: D8716594
Pulled By: hermanventer
fbshipit-source-id: bbcb25462f79852d8deac29bfed62e86745e5589
Summary:
Release notes: none
When the `objectWithoutProperties` mock was originally created, my knowledge of Prepack's internals wasn't as good as it was now. Now that I understand how AbstractObjectValues work, we can safely add the known values in `objectWithoutProperties` to the abstract backing object. The backing object was missing these values before and was an empty empty that was partial. This should give more data and value on our internal bundle, where before the values would be lost unnecessarily.
Closes https://github.com/facebook/prepack/pull/2194
Differential Revision: D8716289
Pulled By: trueadm
fbshipit-source-id: 451065473ea09943831f75c0bc15490e73c8d947
Summary:
Currently we have a single giant file with all tests, and a giant snapshot. This is both slow, and hard to work with and iterate on.
In this PR I will refactor our test setup.
- [x] Split it up into multiple files (gets the test running from 45s to 27s)
- [x] Run Prettier on test files
- [x] Split tests further for better performance
- [x] Make it possible to run one test file
- [x] Fix the issue with double test re-runs in watch mode on changes in the test file
- [x] Refactor error handling
- [x] Run Prettier on fixtures
- [x] Add a fast mode with `yarn test-react-fast <Filename>`
- [x] Fix double reruns on failure
Potential followups:
- [x] Figure out why test interruption broke (need https://github.com/facebook/jest/issues/6599 and https://github.com/facebook/jest/issues/6598 fixed)
- [x] Revisit weird things like `this['React']` assignment with a funny comment in every test
Closes https://github.com/facebook/prepack/pull/2187
Differential Revision: D8713639
Pulled By: gaearon
fbshipit-source-id: 5edbfa4e61610ecafff17c0e5e7f84d44cd51168
Summary:
Fixes#2179
In #2179 I describe why we might need to havoc some args to abstract values sometimes. This adds an invariant to ensure that we always have args in the cases we need to havoc.
If this abstract value cannot be an object, then we don't need to havoc since there's nothing that can be mutated.
If this has a known values domain, then we know the possible objects. We only need to havoc those, not the args.
Closes https://github.com/facebook/prepack/pull/2184
Differential Revision: D8701601
Pulled By: sebmarkbage
fbshipit-source-id: d5fecbed4cff8013bc768cb6e277094d9ff16d9c
Summary:
Release note: Improve source location information
Changes to make sure that the source location of the call expression appears in the corresponding execution context record. Also emit execution records with no source location from stack traces. These are due to calls to internal helper methods for iterating over objects and arrays for argument destructuring.
Finally fix a CompilerDiagnostic construction call to include a source location.
Closes https://github.com/facebook/prepack/pull/2183
Differential Revision: D8698271
Pulled By: hermanventer
fbshipit-source-id: 10f77f718db645a4784723c3eca4bd4e06eb43f8
Summary:
Release notes: none
Fixes nested `evaluatePure` calls, where before they would collide and overwrite one another. Also ensure React reconciler uses side-effect detection on nested optimized closures. This fixes a React test which should have been failing before, but wasn't.
Closes https://github.com/facebook/prepack/pull/2166
Differential Revision: D8681422
Pulled By: trueadm
fbshipit-source-id: 8941812407d1bda5af0343a09210aeff24a36cff
Summary:
Release notes: adds `mutatesOnly` to generator entries to better allow for DCE
This PR adds a new option that can be passed as an optional arg to `generator.deriveAbstract` called `mutatesOnly `. See https://github.com/facebook/prepack/pull/2132#pullrequestreview-130509488 for details. With it, we can better dead-code eliminate generator entries when the value entries that are flagged as mutating are dead code.
The test showing this is below:
Input:
```js
global.f = function() {
var x = global.__abstract ? global.__abstract({}, "({})") : {};
global.__makeSimple && __makeSimple(x);
Object.assign({}, x);
return 1;
};
if (global.__optimize) __optimize(f);
```
Output (with master):
```js
var _$2 = this;
var _$3 = _$2.Object;
var _$4 = _$3.assign;
var _0 = function () {
var _$0 = _$4({}, {});
return 1;
};
```
Output (with the changes in this PR):
```js
var _0 = function () {
return 1;
};
var _2 = function () {
return global.f();
};
```
Closes https://github.com/facebook/prepack/pull/2132
Differential Revision: D8667764
Pulled By: trueadm
fbshipit-source-id: 5121da7d73330befeb5a39ea50d7b773256d70bc
Summary:
Release note: More simplification of equality expressions
Resolves issue: #2172
Expressions like (c ? x : y) === null can sometimes be simplified by first rewriting them as (c ? x === null : y === null). Add such a case to the simplifier.
Closes https://github.com/facebook/prepack/pull/2174
Differential Revision: D8666251
Pulled By: hermanventer
fbshipit-source-id: 5b0d56fb091e25bfcdf879be3403cb5a982375ae
Summary:
Release notes: None
We used to find random bugs where the `computed` flag wasn't set right.
But even if it's set correctly, we sometimes generated suboptimal code,
e.g. `a["0"]` for an array access.
I reviewed all occurrences of `t.memberExpression`, and redirected all that involve
potentially interesting computations to a new helper function `memberExpressionHelper`
which does "the right thing". This function should always be used.
Added regression test for an array access that used to be suboptimal (observed in InstantRender).
Closes https://github.com/facebook/prepack/pull/2162
Differential Revision: D8625006
Pulled By: NTillmann
fbshipit-source-id: f9211260c08d9195a9f4cc48502cba0794fe84f9
Summary:
Release notes: adds basic ES2015 arrow function serialization
This allows Prepack to serialize back to arrow functions and also traverse them correctly when understanding `this`.
Closes https://github.com/facebook/prepack/pull/1650
Differential Revision: D8623368
Pulled By: trueadm
fbshipit-source-id: 9be7849770148b67e5f17eee88a633aac906b6e2
Summary:
Release notes: standard for loops and while loops have a recovery mechanism in pure scope
This PR provides a bail-out recovery mechanism in pure scope for FatalErrors thrown and caught from for/while loops. Until now, if a FatalError occurs from trying to evaluate abstract for/while loops, we'd have to recover at a higher point in the callstack, which wasn't always possible (the loop may be at the root of a function/component).
The ideal long-term strategy is to properly model out the different cases for loops, but this is a complex and time-consuming process. This PR adds a recovery mechanism that serializes out the original for loop, but within a newly created wrapper function containing the loop logic and a function call to that newly created function wrapper. This allows us to still run the same code at runtime, where we were unable to evaluate and optimize it at build time.
For now, this PR only adds recovery support for standard `for` and `while` loops (as they go through the same code path). We already have some basic evaluation for `do while` loops, but trying to adapt that code to work with the failing test case (https://github.com/facebook/prepack/issues/2055) didn't work for me – we have so many strange problems to deal with first before we can properly handle that issue.
In cases where the loop uses `this`, the context is found and correctly called with the wrapper function. In cases of usage of `return`, `arguments` and labelled `break/continue` we bail out again as this is not currently supported in the scope of this PR (can be added in a follow up PR, but I wanted to keep the scope of this PR limited).
For example, take this failing case on master:
```js
function fn(props, splitPoint) {
var text = props.text || "";
text = text.replace(/\s*$/, "");
if (splitPoint !== null) {
while (text[splitPoint - 1] === "\n") {
splitPoint--;
}
}
return splitPoint;
}
```
This serializes out to:
```js
var _0 = function (props, splitPoint) {
var __scope_0 = new Array(1);
var __get_scope_binding_0 = function (__selector) {
var __captured;
switch (__selector) {
case 0:
__captured = [_G, _E];
break;
}
__scope_0[__selector] = __captured;
return __captured;
};
var _C = function () {
var __captured__scope_1 = __scope_0[0] || __get_scope_binding_0(0);
for (; __captured__scope_1[1][__captured__scope_1[0] - 1] === "\n";) {
__captured__scope_1[0]--;
}
};
var _$0 = props.text;
var _$2 = (_$0 || "").replace(/\s*$/, "");
var _6 = splitPoint !== null;
var _G = _6 ? void 0 : splitPoint;
var _E = _6 ? void 0 : _$2;
if (_6) {
(__scope_0[0] || __get_scope_binding_0(0))[0] = splitPoint;
(__scope_0[0] || __get_scope_binding_0(0))[1] = _$2;
var _$5 = _C();
}
var _$6 = (__scope_0[0] || __get_scope_binding_0(0))[0];
return _$6;
};
```
Furthermore, an idea that might be a good follow up PR would be to break the wrapper function into two functions, depending on some heuristics. If we can detect that the loop body does not have any unsupported side-effects like writing to variables that are havoced etc, we can then tell Prepack to optimize the inner function wrapper for the loop body. That way, at least some parts of the loop get optimized (the outer bindings will be havoced before this point, so it should work okay). I think I suggested this in person with hermanventer and sebmarkbage in Seattle as a potential way to optimize complex loops that we can't compute the fixed point for right now.
Fixes#2055
Closes https://github.com/facebook/prepack/pull/2118
Differential Revision: D8410341
Pulled By: trueadm
fbshipit-source-id: ee7e6b1bc1feadf0c924e4f82506ca32ca1dadc9
Summary:
Release notes: none
Fixes a bug where the argument list gets mutated and padded with undefined values, so instead we slice it a copy of it so we don't mutate the same array and pass the mutated array instead. Fixes https://github.com/facebook/prepack/issues/2153.
Closes https://github.com/facebook/prepack/pull/2156
Differential Revision: D8610746
Pulled By: trueadm
fbshipit-source-id: 1b6f37693323c813d60f43ab7e9977a99f86ff47
Summary:
Release notes: in pure mode, allow Object.assign to continue evaluation rather than throwing FatalErrors
This PR adds bail-out support of `Object.assign` sources within the `Object.assign` implementation. This allows us to continue evaluation in pure scope without bailing out of the Object.assign entirely (like we currently do) upon a FatalError occurring. Given we have snapshotting in `Object.assign`, we don't need to havoc the sources.
This allows us to inline and evaluate far more within our internal bundles. Fixes https://github.com/facebook/prepack/issues/2064
Closes https://github.com/facebook/prepack/pull/2068
Differential Revision: D8579441
Pulled By: trueadm
fbshipit-source-id: 0e97b54e0c8af63f1e3cd08fca6c7f375ee3c615
Summary:
Release notes: Fixes to leaked declarative bindings
Leaked declarative bindings need to be accessed out-of-band as far
as the serializer is concerned which otherwise only puts final
values into locations.
To make that work, whenever two states are merged where a
declarative binding in one has been leaked but not in the other,
this now gets harmonized by also recording the materialization
side effect into the generator of the other.
The result is that a binding always ends up being fully leaked or not.
For leaked mutable bindings, the tracked value becomes irrelevant, and
is now truly made unavailable. For leaked immutable bindings, the last
value is retained, and we no longer need the strange `leakedImmutableValue` field.
Leaked bindings are now referentialized as simple variables, bypassing the
delayed captured-scope logic. This produces nicer more efficient code, but,
at least for now, has the downside that it rules out sharing of function bodies.
This change is a step towards the (to be publicly documented)
long-term plan to clean up Prepack's handling of leaking and havocing.
(Similar to what this change does for declarative bindings, we'll also must
revisit what happens for leaked object properties. But that's for later.)
This fixes#2122 (issue havocing value in conditional) and adds regression test.
This fixes#2007 (Conceptual issue with havoced bindings) and adds regression test.
Closes https://github.com/facebook/prepack/pull/2125
Differential Revision: D8549299
Pulled By: NTillmann
fbshipit-source-id: 28c3681beafd3890668b72a828f59582c636a6c9
Summary:
Release note: none
Attempts adding support for promises in test-runner.js. `inspect` can now return Promises, which will be resolved before checking it value.
Closes https://github.com/facebook/prepack/pull/2115
Differential Revision: D8550825
Pulled By: hermanventer
fbshipit-source-id: 3f9781f6e34016dcb61bd436400a1bfb51932452
Summary:
Release notes: none
There was a bug, where React abstract object values with the same intrinsic name were incorrectly being de-duped and re-used. This is a normal expected Prepack optimization, but it actually breaks React components that expect to be able to create many values with the same intrinsic name. We now mark such objects and ensure they do not correctly return `true` from `equals()`. Fixes https://github.com/facebook/prepack/issues/2089
Closes https://github.com/facebook/prepack/pull/2126
Differential Revision: D8448171
Pulled By: trueadm
fbshipit-source-id: d21fddd70576e6e55c41070ac43ce2f58a059e7a
Summary:
Release notes: none
This PR moves the logic of sanitizing ReactElements for `firstRenderOnly` mode to the serialization phase instead of during reconciliation. The plan is to create a follow up PR that introduces a new phase after the visitor phase, that skips values that were detected as dead code once the visitor stage finishes, but that's not in scope for this PR.
Closes https://github.com/facebook/prepack/pull/2123
Differential Revision: D8435440
Pulled By: trueadm
fbshipit-source-id: f442525e663a7bc0f9608b96eb7d7a2389a707b7
Summary:
Release notes: fixes serialization of bindings when shared between optimized functions
This PR fixes a long standing bug with nested optimized functions where bindings would incorrectly serialize to the main body scope when the binding was shared between nested optimized functions and their parent optimized function scopes. This allows us to not skip 2 React tests and I also added a serializer regression test that demonstrates the same problem so we don't regress.
Closes https://github.com/facebook/prepack/pull/2117
Differential Revision: D8408712
Pulled By: trueadm
fbshipit-source-id: 0e0a306f9195fcb5b57fa7f8cef1c65dbef4998f
Summary:
Release notes: none
When we create temporals that are pure, let's mark them as pure and also skip creating invariants for them too. Making these changes allows the serializer to not emit temporals that never end up getting used, reducing the output and also making it easier to debug the output (less spam of temporals).
Closes https://github.com/facebook/prepack/pull/2097
Differential Revision: D8329043
Pulled By: trueadm
fbshipit-source-id: f1ef4185793115dd7982b8162a7e3dc4038a15f9
Summary:
Release notes: none
This is a long standing fix, where ReactElements should be created lazily but are currently not done so. To do this, we now use the `temporalAlias` code paths on lazy branched ReactElements to ensure they are emitted as temporal entries when we "branch" (i.e. conditional) and have many possible routes where ReactElements may or may not be created.
Fixes https://github.com/facebook/prepack/issues/2113. Depends on https://github.com/facebook/prepack/pull/2112
Closes https://github.com/facebook/prepack/pull/2107
Differential Revision: D8383327
Pulled By: trueadm
fbshipit-source-id: bbcff45ddd07406b18bcddce2de0279fb52da1a1
Summary:
Release notes: improves ReactElement creation by re-using ReactElement nodes where possible
We already have a pretty good ReactElement equivalence system to re-use ReactElements. We weren't using it to its full power though. When we have nested ReactElements, we don't use the equivalence system at all, meaning we duplicate lots of ReactElements when we can re-use.
This is a nice performance optimization. I've added a test that should prevent regressions here too.
Closes https://github.com/facebook/prepack/pull/2114
Differential Revision: D8381595
Pulled By: trueadm
fbshipit-source-id: befabd04326a162f8ab6a00e089cdada052cf6c8
Summary:
Release notes: none
Whilst working on adding React Native mocks, I ran into cases where context should be inlining but it wasn't. It now is inlining far better, with more test coverage. Furthermore, we now have a new config flag to pass to `__optimizeReactComponentTree`, in the case of `isRoot` to state that the tree is a root component tree (rather than a a branch of another tree).
Closes https://github.com/facebook/prepack/pull/2098
Differential Revision: D8348381
Pulled By: trueadm
fbshipit-source-id: 5e01bd77437e8bc3d1f22ff47d668897152203a0
Summary:
The code didn't work without it sometimes because conceptually all code outside of `getTrials` is an isolated "bundle". We can only access its internals through the `Root` reference. This fixes the tests to follow this constraint and removes the hack.
Closes https://github.com/facebook/prepack/pull/2102
Differential Revision: D8333634
Pulled By: gaearon
fbshipit-source-id: 1fb24751490042beae55a133f64351a9be9f903c
Summary:
There is a case when prepack emits non-computed member expressions in `rebuildObjectProperty` for properties which cannot be used this way. This PR is to fix#2084 .
Closes https://github.com/facebook/prepack/pull/2093
Differential Revision: D8319018
Pulled By: hotsnr
fbshipit-source-id: a27b943b541f6210d44c1e9a5887915eec5c6359
Summary:
Release notes: none
This fixes an issue where `createDefaultPropsHelper` gets created in a branch of effects, and is cached on the `realm`. Instead `createDefaultPropsHelper` should get created during the init phase, so the function is accessible throughout the entire lifecycle of the realm.
Closes https://github.com/facebook/prepack/pull/2087
Differential Revision: D8290010
Pulled By: trueadm
fbshipit-source-id: 324035cdd3c8a951c44849e1ccbfca9798a551b0
Summary:
Release notes: fixes a range of spread bugs with ReactElements
This is a very important PR for React reconciliation, it fixes many undiscovered bugs and adds a huge amount of test coverage that was previously missing.
Whilst testing quite complex cases of JSX spreads in combination with defaultProps on our internal bundle I noticed that there were some bugs appearing, but because the branches where these bugs were appearing were not used on firstRender, it meant we got away with it on our internal tests.
We now use snapshotting and properly evaluateForEffects when recovering from `Object.assign` with ReactElement creation of config/props. We also properly use the `temporalAlias` to ensure we reference the correct object.
Closes https://github.com/facebook/prepack/pull/2070
Differential Revision: D8243793
Pulled By: trueadm
fbshipit-source-id: e8c37aa6750c0a6d41f12249d8872004da3ab3a6
Summary:
Release notes:
This PR is a follow up to https://github.com/facebook/prepack/pull/2051, which we found to have issues and had to be reverted. The main cause of the issue in the previous PR was that `realm.evaluateWithAbstractConditional` was being given a `ReturnCompletion`, which are a type of `AbruptCompletion`. There is logic to correctly throw such completions. So instead of passing a `ReturnCompletion` to `realm.evaluateWithAbstractConditional`, we instead pass the value and then wrap the `realm.evaluateWithAbstractConditional` call with a function that adds back on the `ReturnCompletion`.
Fixing this brought about a bunch of deeper issues that were causing tests to fail (regression tests added) around the unknown array and its prototype methods. We were only handling a handful of methods before, but that was fragile. So this PR now adds support for all the of current prototype methods on `Array` for unknown arrays – following the spec as to what the return value should be in each case.
Finally, a change was made to the React reconciler to ensure that we return the unknown array in cases where it is passed an unknown array without a ReactHint (which is expected, but was missed and thus a regression from a previous PR).
Closes https://github.com/facebook/prepack/pull/2061
Differential Revision: D8229848
Pulled By: trueadm
fbshipit-source-id: 02dbd1c7e1cd03de4f6745daed57d13ea24537a8
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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