Summary:
Initial bit of support for dealing with abstract loops where the loop body contains assignments to properties with computed names involving loop controlled variables.
Closes https://github.com/facebook/prepack/pull/1286
Differential Revision: D6628885
Pulled By: hermanventer
fbshipit-source-id: 960fa469e3c18e55e5447ac441235a80df2b1629
Summary:
Release note: none
Add some test cases that have loops that delete properties in some iterations but not others.
Deal with it by explicitly testing for __empty values.
Issue #1174
Closes https://github.com/facebook/prepack/pull/1281
Differential Revision: D6622901
Pulled By: hermanventer
fbshipit-source-id: c41a5426b062f08ebeb0e6c2f26ad690d6c43ec8
Summary:
This PR attempts to resolve issue #1140#1093 making additional functions capture precisely the values the rewritten additional function will need.
This is accomplished by visiting the additional function's effects when we encounter a `visitValueFunction` corresponding to that additional function.
All values that need to be serialized in the parent scope of the additional function:
1. Object/Function captures that are
a. from the additional function or nested functions
b. not in CreatedObjects (i.e. created in a parent scope)
2. additional function's captures that will be used by rewritten function
These are re-visited from the function's parent scope to make sure that we record the scopes for the bindings correctly.
`reVisitSet` ensures that Objects/Functions that need to be in a parent scope get placed in the correct parent scope by appending them to the common generator (where `_getTarget` would emit them). The other reason for this is that while serializing additional functions, they don't have access to previous generators/bodies.
Other changes:
- `test-runner.js` now tests simpleClosures option. This makes test-serializer take a long time so
- there is now a `--fast` option as well that runs each test only once.
- `test-runner.js` also has more error output giving actual stacktraces.
- added tests
- moved specialized binding functions into `visitBinding`
- add `react-mocks` compatibility option to CLI to be able to debug `test-react` with cli
Closes https://github.com/facebook/prepack/pull/1279
Differential Revision: D6617232
Pulled By: cblappert
fbshipit-source-id: 6211262561ffc954be8b1346ad7737f4360a2416
Summary:
TL;DR this tracks any reachable object or binding that a side-effectful function could mutate as having an unknown value after that call.
In the React compiler we see a lot of examples like this:
```js
return <div>{obj.unknown.toString()}</div>
```
Where we're calling an abstract function, or even calling a generic abstract value due to unknown being abstract.
This is an example that we currently use Flow types for. Flow lets us know that this is a number and therefore toString is known to be pure. However, fully plugging in Flow will be limiting and hard. Flow is also overkill for our use case. We still can't compile away the function call since we'll have to leave a residual call to toString anyway.
Now we could assume that all calls are pure, however, we also see a lot of patterns like this:
```js
var children = [];
obj.items.forEach(item => children.push(<Item item={item} />);
var data = knownFunction(obj.data);
return <div><Foo>{children}</Foo><Bar data={data} /></div>;
```
In this case the children array gets locally mutated. If we knew the `forEach` function here was an array (as opposed to some other `forEach` side-effectful method), then we know what it could do. Even if we knew this would deal with a loop over an abstract bound. But this assumes that we even know this is an array.
It would be sufficient for us to just leave this call in an treat the children as abstract. Even with best effort, that is more or less what's going to happen anyway.
We don't want to completely bail out on the whole function because we want to know the fact that this always returns a `<div>` with a `<Foo />` and a `<Bar />` in it so that we can continue with those. We can also inline the knownFunction call.
Once we're inside a "pure function" such as a React component or additional function, there can be mutations.
Such a function can only mutate newly created objects and bindings, and read immutable data. That's not technically enforced but that's what the whole principle builds on.
This means that any abstract call to a function that was passed in, or lives in global scope, cannot have side-effects on anything except what was passed in as an argument (or `this`).
This PR introducing a new concept of tainting objects and bindings as abstract values after they've been passed to an impure function call.
After they have been tainted all mutations to them are tracked through a generator.
Any subsequent operations on these objects or bindings behave like access to abstract values.
When we enter evaluation of a "pure function" we track that scope and track all newly created objects within it as "impure".
When an abstract function call happens, I visit all arguments that are in the impure list recursively. I stop when I hit an object not on the list, since that can't be mutated.
For objects, I mark them as "tainted", reset all properties and make it partial. That way all subsequent property accesses are unknown. The abstract function call could've done anything with it, including deleting all properties.
Currently I always serialize tainted objects as empty, but I set all the properties to what they were at the first call.
Once an object is tainted, any subsequent operations on it emit to the generator.
If a function is passed in, I also taint all the _newly created_ bindings that are reachable from that closure.
Reads on a tainted binding return a new derived abstract value that replays a read of that binding. To do that I had to add a way to expand `buildNode` to be able to accept `Binding` as an argument. Not just `Value`. That way the `Referentializer` can decide what name the binding needs to serialize as.
I currently left out error handling. Normally that doesn't matter, because if the function call throws, it will bubble up to the pure function call and act like it would've anyway.
Errors only matters if there is a `try`/`catch` anywhere between the abstract call and the pure function call. That should be solvable but even this case is so rare that it is probably fine to fatal in that case.
Once we have function calls in place, we can later follow up by unlocking other operations that currently only fatals because we don't know if they will invoke side-effectful functions.
Closes https://github.com/facebook/prepack/pull/1142
Differential Revision: D6606775
Pulled By: sebmarkbage
fbshipit-source-id: 3305a58ad7b311d222a4b3ce8437056497154edf
Summary: Marks the start of the next release.
Reviewed By: yinghuitan
Differential Revision: D6607650
fbshipit-source-id: 4e6bbd41e451c8cacf529ca9478654bb9de0401e
Summary:
hermanventer changed the interpreter such that when `popContext` was run, the corresponding `var` bindings from the popped scope were removed. This PR extends that functionality to `LexicalEnvironment`s so that `let` bindings are also removed when the Lexical scope is removed.
This is necessary for #1093 / #1140.
Closes https://github.com/facebook/prepack/pull/1217
Differential Revision: D6594205
Pulled By: cblappert
fbshipit-source-id: 85440e5b591bba6118724140e0e0764f573fbd00
Summary:
Release note: none
This is the first among a number of step to deal with the gnarly edge cases that arise because a property can be absent (empty) rather than just undefined.
Closes https://github.com/facebook/prepack/pull/1278
Differential Revision: D6596190
Pulled By: hermanventer
fbshipit-source-id: f18f181e617a50e1bb39015378330dee14d71815
Summary:
Hi all!
I took the path to implement a custom errorHandler, to be more aligned with the rest of the code, but it may be a mistake.
I reached that point.
```bash
echo "(){}" | yarn prepack
yarn prepack v0.27.5
$ node lib/prepack-cli.js
Unexpected token (1:1) found in stdin
Error: A fatal error occurred while prepacking.
+ (full stack trace)
error Command failed with exit code 1.
```
and when srcmapIn is given but not existing:
```bash
echo "(){}" | yarn prepack -- --srcmapIn notExisting
yarn prepack v0.27.5
$ node lib/prepack-cli.js "--srcmapIn" "notExisting"
No sourcemap found at notExisting.
Unexpected token (1:1) found in stdin
+ (stack trace)
```
Finally when using files with syntax error:
```bash
yarn prepack ../notepad/test.js
yarn prepack v0.27.5
$ node lib/prepack-cli.js "../notepad/test.js"
Unexpected token (1:3) found in input file ../notepad/test.js
+ (stack trace)
```
Closes https://github.com/facebook/prepack/pull/1272
Differential Revision: D6595324
Pulled By: hermanventer
fbshipit-source-id: 6f73a15db5710585ffc9579f4487217a98f921f5
Summary:
Release notes: Adds serialization support for JSX to `React.createElement`
Requires https://github.com/facebook/prepack/pull/1267 to land before tests pass.
This PR adds JSX to `React.createElement` support and also adds a few more React mocks and better handling of React internals to allow all this to happen properly. Other things include:
- ReactElement serialization has been moved to its own file
- The React library object is now checked for to be used
- There is now a `reactOutput` flag, that allows you to choose from either `jsx` or `react-element`.
Closes https://github.com/facebook/prepack/pull/1268
Differential Revision: D6588176
Pulled By: trueadm
fbshipit-source-id: 5799dc42a05a6498e799ab2dbe391057429f6ad7
Summary:
Release Note: none
Found this bug during working on another feature. Every preProcessValue() should be paired with a postProcessValue(). Also add an invariant to check the stack balance.
Closes https://github.com/facebook/prepack/pull/1270
Differential Revision: D6583445
Pulled By: yinghuitan
fbshipit-source-id: 249e38a072909f732cbc9f412fba030a9d6faa4c
Summary:
Release note: none
After recent refactorings in Nuclide, we don't need to build the debugger differently anymore. We can use our transpiled code directly into Nuclide.
This undoes #1240
Closes https://github.com/facebook/prepack/pull/1274
Differential Revision: D6579982
Pulled By: JWZ2018
fbshipit-source-id: 58b487b3f1f020be27fc569c4f5219c660c1aad5
Summary:
Release note: none
This PR aims to do a few optimizations in terms of how JSX/React Elements are handled.
I've introduced a `ReactElementSet` class that aims to handle matching similar React Element/JSX structures by deeply iterating through the various properties on a JSX element. It uses a linked hash map, with the keys being the reference to the specific internal Prepack value. It handles objects, arrays, functions and React element structures.
These optimizations only happen on evaluated component trees.
```jsx
// before:
function MyComponent(props) {
return <div><span>Hello world</span><span>Hello world</span></div>
}
// after:
function MyComponent(props) {
var _0 = <span>Hello world</span>
var _1 = <div>{_0}{_0}</div>
return _1;
}
```
```jsx
// before:
function OtherComponent() {
// ...
}
function MyComponent(props) {
return <div><OtherComponent data={{a: 1, b: 2}} /></div>
}
// after
function OtherComponent() {
// ...
}
function MyComponent(props) {
_1 === void 0 && $f_0();
return _1
}
function $f_0() {
_1 = <div><OtherComponent data={{a: 1, b: 2}} /></div>
}
var _1;
```
Closes https://github.com/facebook/prepack/pull/1196
Differential Revision: D6578563
Pulled By: trueadm
fbshipit-source-id: 2f617fd80d4540228fcb60403cb97e672763876b
Summary:
Release notes: none
When working with the name generator and creating instinct names that include invalid characters, I noticed the output included these characters. Instead they should be replaced like other characters have.
Closes https://github.com/facebook/prepack/pull/1267
Differential Revision: D6577946
Pulled By: trueadm
fbshipit-source-id: 07db9e9cfd519cea128623df41dee35d60b8f8f3
Summary:
Release note: Basic support for do while loops with abstract bounds. Issue #1229
Take properties into account when doing fix point computation. Use property paths rather than phi nodes. Simplify code for local variables as well.
Closes https://github.com/facebook/prepack/pull/1255
Differential Revision: D6576293
Pulled By: hermanventer
fbshipit-source-id: 9e19704cbf5c8cbcc937bd99ec32af9ffe577ebf
Summary:
Release note: add heap graph visualization to website
Moved from #1243
- read in the heap graph data from prepackSources result
- display the graph using [visjs](http://visjs.org/)
Closes https://github.com/facebook/prepack/pull/1265
Differential Revision: D6571860
Pulled By: JWZ2018
fbshipit-source-id: 4c2d9bae91eaffff58df8909214d4c7bc56d1359
Summary:
Release Notes: none
Addresses issue #1244. Now we will put modifications to bindings just before the return statement of the additional function.
Also contains some minor refactors.
Closes https://github.com/facebook/prepack/pull/1251
Differential Revision: D6568331
Pulled By: cblappert
fbshipit-source-id: ea3ae2a783355175f0f23f82bce6543ac535b214
Summary:
Release note: Use conditional returns to refine the path condition. Fixes#1182
When one branch of a conditional is an abrupt completion add the join condition to the path condition. The previous path condition is stored in the saved completion and restored at join point.
Closes https://github.com/facebook/prepack/pull/1212
Reviewed By: hermanventer
Differential Revision: D6562943
Pulled By: simonhj
fbshipit-source-id: fcf53a7c54118628bd3f62e5010f4c1046fd1145
Summary:
Release note: none
- Nuclide does not expect the first stop event from the debug adapters
- caused a bug where the state information is not shown on the first stop in Nuclide
- Remove sending a stopped event on entry
Closes https://github.com/facebook/prepack/pull/1256
Differential Revision: D6561599
Pulled By: JWZ2018
fbshipit-source-id: 942f644ce54e9b52fb5acbd3b217b210bf71b2b3
Summary:
Release Note: none
Remove scopes parameter from _getTarget() so that it is easier to use.
Closes https://github.com/facebook/prepack/pull/1254
Differential Revision: D6557152
Pulled By: yinghuitan
fbshipit-source-id: 7ceb9dc1799fc7960765ad816e73cd0a478a5712
Summary:
Release note: Fix bug #1262
The saved completion that is present before a function call should not be incorporated into the saved completion that is created inside the call, until after return completions have been appropriately joined and applied.
Closes https://github.com/facebook/prepack/pull/1263
Differential Revision: D6560937
Pulled By: hermanventer
fbshipit-source-id: 76e8d67f0ad2227dec9cf54f5f035a34f1941be3
Summary:
Hi all,
It was a good way to get started on contributing.
Closes https://github.com/facebook/prepack/pull/1259
Differential Revision: D6558546
Pulled By: hermanventer
fbshipit-source-id: 815380c88aad36a7e1b34928b4eb6927a7c9d461
Summary:
Release notes: Percentage output of passing tests (passed tests / total tests) should be rounded down instead of up.
From an example I encountered earlier, when we had number of tests passed = 1157 and total tests = 1159, we would display, "Passed: 1157/1159 100%". We should instead display "Passed: 1157/1159 99%"
Closes https://github.com/facebook/prepack/pull/1260
Reviewed By: hermanventer
Differential Revision: D6558323
Pulled By: jhalley
fbshipit-source-id: 01751bacb83760ae49a56a9ef56983fee94487d2
Summary:
Release notes: none
This adds detection support for the legacy `React.createClass`/`create-react-class` API so that we can safely bail out.
Closes https://github.com/facebook/prepack/pull/1257
Differential Revision: D6556374
Pulled By: trueadm
fbshipit-source-id: c71dcd3792be56c7134e743206c5830f1f46ae0d
Summary:
Release note: Changed some erroneous console.log statements to console.error
This addresses issue https://github.com/facebook/prepack/issues/1201. Went through all uses of console.log in the codebase and converted them to console.error if that's what they're supposed to be.
Closes https://github.com/facebook/prepack/pull/1253
Reviewed By: hermanventer
Differential Revision: D6550963
Pulled By: jhalley
fbshipit-source-id: aec0f2f9a0e5745f563628b849fde110388b12cd
Summary:
Release note: Debugger is available!
- remove the flag that hides the debugger
- to check whether to invoke the debugger:
- inFilePath and outFilePath are specified when starting prepack (check in prepack-node.js)
- if so, DebugChannel will read from inFile to see if debugger is attached
Closes https://github.com/facebook/prepack/pull/1249
Differential Revision: D6548604
Pulled By: JWZ2018
fbshipit-source-id: 1d4bee80d95c91da9853871b117cb8a939f4797b
Summary:
Release note: none
To address issue #956 .
The idea is to have all documentation (aka "the website") in a single `docs/` directory on the `master` branch like [Jest](https://github.com/facebook/jest/tree/master/docs) and [Relay](https://github.com/facebook/relay/tree/master/docs) do. This directory then serves as a single source of truth to publish the `gh-pages` branch.
This PR:
- Moves the current content of the `gh-pages` branch to a `docs/` directory in `master`
- Provides a bash script for maintainers to easily publish the `gh-pages` branch from the `docs/` directory. The script also builds `prepack.min.js` from master to make sure gh-pages always has the latest version of prepack.
Additionally, I noticed the `gh-pages` branch had two `prepack.min.js` files (one in `./` and one in `./js/`). I removed the first one because it is apparently not used but it may break other websites if they references that file.
0. Fork the repo to avoid modifying the real website
1. Change the site
`> git checkout master`
`> echo ".nav { background-color: chartreuse; }" >> docs/css/style.css`
`> git add docs/css/style.css`
`> commit -m "The navigation bar looks better in green"`
`> git push`
2. Run the publication script:
`> ./scripts/publish-gh-pages.sh`
3. Verify that the gh-pages has been updated:
`> git checkout gh-pages`
`> git pull`
`> git diff HEAD~ # should show the line you added`
Closes https://github.com/facebook/prepack/pull/1223
Differential Revision: D6547395
Pulled By: j-nolan
fbshipit-source-id: 6e6d3aec97c0bcc2555c421d6f4a889bcd8df208
Summary:
Release notes: none
This addresses the --simpleClosures case mentioned in #1238 (but not the other case where we delay closure scope creation).
Prepend additional functions prelude *after* splicing in function declarations,
otherwise the ordering of the insertions is messed up.
Adding regression test.
Closes https://github.com/facebook/prepack/pull/1241
Differential Revision: D6546269
Pulled By: NTillmann
fbshipit-source-id: eb12c5bbba1b542c4e69599e5abf961359d41652
Summary:
Release note: Handle do-while loops with abstract bounds, for loop bodies only involving locals.
Issue: #1174
This adds a simple fixed point computation for do-while loops only. Currently only loops that updated only local variables and that have no abrupt exits are supported.
This is deliberately as minimal as possible to make review easier. Given the complexity of this feature, thoughtful review would be great.
Closes https://github.com/facebook/prepack/pull/1229
Differential Revision: D6546405
Pulled By: hermanventer
fbshipit-source-id: 205c336a83c17d03344941b13f0a5c6af7989131
Summary:
Release note: none
The debugger needs to be built differently from the rest of Prepack to be compatible with Nuclide. This PR makes building the debugger into a separate command while still keeping the original command to build Prepack.
- make separate envs for building debugger and the rest of Prepack
- add `yarn build-debugger` command
Closes https://github.com/facebook/prepack/pull/1240
Differential Revision: D6534794
Pulled By: JWZ2018
fbshipit-source-id: 384dfbb7d77d46564e028c00a79e97b3657616b5
Summary:
Release Note: add serialized identifier to heap graph label.
Also did a small refactoring to NameGenerator to make it easier to reuse.
Closes https://github.com/facebook/prepack/pull/1236
Differential Revision: D6537426
Pulled By: yinghuitan
fbshipit-source-id: d2eef16c204c466689e2be9471ffd53e4c79459a
Summary:
PrePack generates duplicate argument names when inlining expressions. Take for instance the test in test/serializer/basic/CapturedScope.js. PrePacked with --inlineExpressions it generates several functions like
```
var $_1 = function (c, __scope_2, __scope_2) {
var __captured__scope_2 = __scope_1(__scope_2);
var __captured__scope_2 = __scope_1(__scope_2);
__captured__scope_2[1]++;
__captured__scope_2[2]++;
return c();
};
```
Closes https://github.com/facebook/prepack/pull/1218
Reviewed By: hermanventer
Differential Revision: D6536751
Pulled By: lukas1994
fbshipit-source-id: 8752964d7c099476a4cda3d42996c0aa77cbb5b9
Summary:
Release note: none
- change heap graph data to be in the format expected by visjs
- add colors to each type of node
Closes https://github.com/facebook/prepack/pull/1242
Differential Revision: D6534752
Pulled By: JWZ2018
fbshipit-source-id: 74f8d7296ad5399014e9f60af3d86ea3ebf5102f
Summary:
Fixes#1222 by refusing to emit `.bind` calls when the arguments of the `.bind` would be identifiers for functions that have been generated by the ResidualFunctions code (because we can't guarantee that the ordering will be correct).
Closes https://github.com/facebook/prepack/pull/1227
Differential Revision: D6527609
Pulled By: cblappert
fbshipit-source-id: 55953c70eca5f230e5a9e371ac07219e7cafaa61
Summary:
Release notes: none
Towards closing #1226.
Add regression test case.
Note that simple-closures doesn't work together with delay-initializations,
so delay-initializations now gets silently disabled when needed.
Closes https://github.com/facebook/prepack/pull/1237
Differential Revision: D6526798
Pulled By: NTillmann
fbshipit-source-id: 1b21961aaadd98af9503846b065689db38bd5302
Summary:
Release Note: N/A
getSerializeObjectIdentifierOptional() relies on the internal identifier map to check if a value has been serialized and with identifier. I am going to change this assumption in later PR so refactor the code to remove this API.
Introduce new _serializedValueWithIdentifiers data structure to serve getSerializeObjectIdentifierOptional() API purpose.
Closes https://github.com/facebook/prepack/pull/1232
Differential Revision: D6520560
Pulled By: yinghuitan
fbshipit-source-id: 08a187a4a27c681f39187a14872bcd6919a55a26
Summary:
After testing this in JS environments that don't support `Symbol`, React falls back to using `0xeac7`.
```js
const REACT_ELEMENT_TYPE = hasSymbol ? Symbol["for"]("react.element") : 0xeac7;
```
This adds detection for this.
I've also excluded `_store` from being visited on ReactElement. This was picked up when evaluated DEV React bundles (where `_store` is set on the object).
Closes https://github.com/facebook/prepack/pull/1234
Differential Revision: D6520491
Pulled By: trueadm
fbshipit-source-id: c01b31e22f4f45a5e1933affd4b8c86c6bc72c41
Summary:
Release note: introduce Prepack heap objects graph.
This is the first PR to introduce prepack heap objects graph. The visualization is basic now(no coloring, legend for the nodes) and we need to figure out how best show the ref count.
I would like to land this first so that JWZ2018 can start integrate this into REPL website.
Later I am going to add the final identifier name into the node label.
Closes https://github.com/facebook/prepack/pull/1221
Differential Revision: D6520646
Pulled By: yinghuitan
fbshipit-source-id: 8cc0713b5d3fad82fb685dceeb7875894f908dbe