Summary:
Release note: Adds experimental React functional component folding optimizations
This PR is stacked upon PRs #1118 and #1117. Thus, those PRs should be merged before this PR is merged to reduce noise in the diff.
This PR adds a new React Reconciler into Prepack's serialization process, so that React components trees can be folded/inlined into a single component at build time. To fold a component tree, it must be explicitly done via `__registerReactComponentRoot(nameOfComponent)`.
This PR only attempts to fold React functional components, not React ES2015 class components (that will come in another PR at a later date). Furthermore, the `props` parameter on a root component must contain Flow type annotations (otherwise we will have no idea what the values might be). Support flow `propTypes` might also be an addition, but not for this PR.
If the reconciler comes across a component that it cannot fold/inline, it will "bail-out" and try and continue the process without that particular component being folded into the tree.
An example of how this all works (input):
```jsx
function App(props: {title: string}) {
return (
<div>
<ChildComponent title={props.title} />
</div>
);
}
function ChildComponent(props) {
return (
<span>
<SubChildComponent {...props} />
</span>
);
}
function SubChildComponent(props) {
return <span>{props.title.toString()}</span>
}
__registerReactComponentRoot(App);
global.App = App;
```
Output:
```jsx
(function () {
"use strict";
var _$1 = this;
var _0 = function (props) {
var _$0 = props.title;
return <div><span><span>{_$0}</span></span></div>;
};
_$1.App = _0;
}).call(this);
```
Closes https://github.com/facebook/prepack/pull/1120
Differential Revision: D6237333
Pulled By: trueadm
fbshipit-source-id: b58c7d8979ca79a766bb2ee2eb01a380d37c3101
Summary:
For the React folding optimizations to work on ES2015 class components, we need to get the Flow type annotations for the `Component`. For example:
```jsx
type Props = { ... };
type State = { ... };
class MyComponent extends React.Component<Props, State> {
render() { ... }
}
```
The type annotations are used in the reconciliation process as hints for the shape of abstract objects.
Closes https://github.com/facebook/prepack/pull/1128
Differential Revision: D6238366
Pulled By: trueadm
fbshipit-source-id: 776135e3b5d479d21a6b2d32fdacae3d63852f16
Summary:
Introduce lazy objects feature for raw objects in Prepack with supported runtime.
Lazy object is a collaboration feature between the Prepack and new runtime that supports this feature. With this feature, object can be created with a special LazyObjectsRuntime.createLazyObject() API. The object created with this API can be a light-weight placeholder object. Once the lazy object is *touched/used* the first time, runtime is responsible to callback the registered initialization function to hydrate the object into a real object.
By doing this we will save both memory and object creation speed.
Currently, Prepack only supports lazy for raw objects.
The APIs that runtime needs to support:
1. LazyObjectsRuntime.createLazyObject(<lazy_object_id>);
2. LazyObjectsRuntime.setLazyObjectInitializer(<well-known-callback>).
Under lazy objects mode, Prepack will serialize all lazy objects into two parts:
1. All lazy objects are created via lightweight LazyObjectsRuntime.createLazyObject() call.
2. Lazy objects' property assignments are delayed in a callback function which is registered with the runtime.
TODO:
1. Test-runner support for lazy mode.
2. Support more object types for this feature
3. Remove "reference count === 1" objects' root and directly serialize into callback function.
4. Figure out "reference count > 1" objects that are safe to remove root from global anonymous function and directly serialize into callback function.
Closes https://github.com/facebook/prepack/pull/1129
Differential Revision: D6234286
Pulled By: yinghuitan
fbshipit-source-id: fb8f3c0ff2e4189b27b5f98a20a30bdea045f67a
Summary:
Update Flow and fix errors found by new version.
I'm none to sure the changes to the code are desirable. Perhaps the flow types for babel-types need to be updated?
Closes https://github.com/facebook/prepack/pull/1127
Differential Revision: D6222475
Pulled By: hermanventer
fbshipit-source-id: 208b89787914fc7d1e322cb14a6ff2374cd24b9a
Summary:
Release note: none
This PR adds the React/Jest testing infrastructure to Prepack and is stacked on the PR https://github.com/facebook/prepack/pull/1117. Thus, that PR should be merged before this PR is merged to reduce noise in the diff.
This will allow us to test various runtime outputs of React 16 when running original source vs Prepacked source to see if there are any issues/differences that might have an impact on applications. The primary reason for this is to track regressions for the component folding PRs that will land in the future.
Please note, this PR does not contain any reconciler changes, thus `__registerReactComponentRoot(App);` has been commented out of tests to ensure they don't prematurely fail. A follow up PR will enable them once the other React functional component folding PRs get landed.
This PR also adds some mock React globals to be used within tests (and maybe to be further integrated into folding at a future point too). The mocks include `React.Component` and `React.cloneElement` for now.
Furthermore, a `utils/json.js` utility file exists to help normalize the results from the React test renderer so that adjacent JSON text nodes get merged, which is something that may exist because of how the reconciler (once the PR lands) handles inlining of child nodes.
The command to run React tests is `yarn test-react`.
Closes https://github.com/facebook/prepack/pull/1118
Reviewed By: cblappert
Differential Revision: D6208263
Pulled By: trueadm
fbshipit-source-id: d54f3b0e1cc3240e1f142d3da08bc279e4153889
Summary:
Release Note: Fix wait generator body for delay initializations.
Fix#1106
There are three issues need to be fixed here:
1. _processValue() should only call _emitAfterWaitingForGeneratorBody() for generator body.
2. emitAfterWaiting() needs to handle emitting into non-generator body
3. _serializeAbstractValue() needs to wait for all its own generator body to be available.
Closes https://github.com/facebook/prepack/pull/1113
Differential Revision: D6215017
Pulled By: yinghuitan
fbshipit-source-id: 82461f1152855a2b7cae8e8033374d58ac199e91
Summary:
Release note: Introduce model functions for environment properties that may result in optional values.
Rather than special case intrinsic abstract objects, revert to treating them as not null and not undefined. Instead, there is now an abstract value kind "abstractConcreteUnion" which is the union of an abstract value with one or more concrete values. There are also new helper functions: __abstractOrNull, __abstractOrNullOrUndefined and __abstractOrUndefined that can be used to construct such unions.
The serializer need not know anything about these new kind of values, since their build nodes just defer to the build nodes of the single embedded abstract value that must always form part of the union.
The simplifier has been extended to simplify unions into their constituents if the path conditions allow it.
The rest of this request is just removing all of the places where special logic was needed to allow intrinsic abstract objects to behave like they might be null or undefined.
Issue #1001.
Closes https://github.com/facebook/prepack/pull/1123
Differential Revision: D6212688
Pulled By: hermanventer
fbshipit-source-id: 8f6a24b8d8fd4afe4196f25f95ba60929ab9c788
Summary:
Release note: none
- add a parser class to parse adapter commands
- add a formatter class to format messages sent through the channels
- move the message queue from the adapter into the AdapterChannel
Closes https://github.com/facebook/prepack/pull/1114
Differential Revision: D6211129
Pulled By: JWZ2018
fbshipit-source-id: f2466ed8edf644b7a834db840354646214c4f275
Summary:
Release note: none
This is one part of the component folding PRs (the original has been split up). This PR makes small changes to existing code and adds in:
- a new Prepack global hook `__registerReactComponentRoot` that works in a similar way to additional functions
- some tidy up and moving around of JSX/React code
- added `checkReactRootComponents` stub function in the functions serializer code that will be used in upcoming PRs
Closes https://github.com/facebook/prepack/pull/1117
Differential Revision: D6198875
Pulled By: trueadm
fbshipit-source-id: ea183e40b8e6519a88dc574a08804e9f706c5390
Summary:
Release note: none
With the `reactEnabled` option turned on, Flow now get parsed by Babylon, which can break the output. So this PR traverses the AST after serialization and strips all Flow types using the same method from the core Babel strip Flow types plugin to ensure the Flow types aren't in the final output.
Closes https://github.com/facebook/prepack/pull/1119
Differential Revision: D6198276
Pulled By: trueadm
fbshipit-source-id: 343d612fcf6e88757c062a3c0c46ddc570148c60
Summary:
Define two new flags for test-runner.js:
--repl <path> : If present the, the prepack sources of test are evaluated
using by piping to the process instead of in a new node context.
--es5 : run babel on tests, used if the repl does not support es6.
To further deal with es6 a new test header flag is introduced, es6. If a test is
not relevant in a non es6 world, the test is skipped if the es5 flag is also set.
This flag has been added to some tests.
Running subprocess for each test is obviously more expensive so the default
behavior is unchanged and still uses a new context.
Closes https://github.com/facebook/prepack/pull/1103
Differential Revision: D6192670
Pulled By: simonhj
fbshipit-source-id: 35e4b819d863634f3273a4da7984c7a71d8c4fb9
Summary:
Release note: none
- add in unique request IDs for requests between debug adapter and Prepack
- use request IDs to register callbacks for adapter to respond to UI.
Prevsiouly, the responses from the adapter to the UI to already implemented requests (continue and set breakpoints) do not need any information from Prepack, they only needed an acknowledgement. To handle other requests such as stackframe, variable, etc, the adapter requires information from Prepack before being able to respond to the UI. This PR makes the responses for all requests into callbacks so they can be sent when Prepack has sent back any needed information.
Closes https://github.com/facebook/prepack/pull/1112
Differential Revision: D6189193
Pulled By: JWZ2018
fbshipit-source-id: 1e4e5ab74107e360f4d4d5a3755180ead4a6f70c
Summary:
Instead of delaying modules that throw conditionally, let the exception bubble up to the require call and then forget it (after emitting a warning). This allows more global state to be optimized and should be OK if it is understood that throwing an unhandled exception in module initialization code is not a supported scenario.
Probably, the temporal point where the require call happens should contain a conditional throw statement, which would be equivalent to current behavior. For now, this causes invariants to fire in the serializer, probably because of bugs in how the state at the time of the exception is restored and presented to the throw statement.
It is also an option to let the exception escape the require call itself and possibly bubble all the way to the top level. This would be more correct than the current behavior since it should match the runtime behavior of the unprepacked code. This too is currently buggy. It also a bit of performance concern because it uses much more saved state.
Closes https://github.com/facebook/prepack/pull/1104
Differential Revision: D6189032
Pulled By: hermanventer
fbshipit-source-id: 71c6352eddca4d88ae030fdcbfb76e7a39839e73
Summary:
Release note: none
- autosend initialize and configurationDone requests on start up of the CLI
- those requests were user commands before but they can be done without any user input
Closes https://github.com/facebook/prepack/pull/1105
Differential Revision: D6187557
Pulled By: JWZ2018
fbshipit-source-id: a9ba9a42c1910054118846acdd35d408615d0092
Summary:
Builtin functions that are side-effect free can trivially be modified to return abstract values if one or more of their arguments are abstract.
This pull request provides such behavior for the Error constructor, Error.prototype.toString and String.prototype.split and slice.
Closes https://github.com/facebook/prepack/pull/1110
Differential Revision: D6182526
Pulled By: hermanventer
fbshipit-source-id: d95c8045ff75c35f1b55dc668c080aa394ccb43d
Summary:
The + operator already checks if its operands are abstract and generates a suitable abstract value as the result in that case. In the case of concrete operands that become abstract after conversion, however, it just gave up.
This pull request fixes this by introducing a variation of ToPrimitive that can result in an abstract value and then using that in the place of ToPrimitive in computeBinary and dealing with the case where the result is abstract.
Closes https://github.com/facebook/prepack/pull/1108
Differential Revision: D6182523
Pulled By: hermanventer
fbshipit-source-id: 9e550f6f7fab8ee5e8974228a6b0451fb549893e
Summary:
Release note: none
A PossiblyNormalCompletion is neither normal nor abrupt but a weird entanglement of the two. Hence such a completion should neither be returned from an evaluation function nor thrown, unless of course, a completion is actually expected (evaluateCompletion), in which case it is returned just like any other completion.
This request establishes this behavior and changes the return types of the evaluate functions accordingly. In terms of behavior, it now consistently stores possibly normal completions in the current context and updates them there as appropriate. Only when a completion is explicitly requested, does the wave function collapse.
One side effect of this is that joined abrupt completions are also better supported now and they turn into possibly normal completions when incorporate one or more return completions and become the return value of a call. This means that early termination is no longer necessary when a joined abrupt completion is encountered.
Closes https://github.com/facebook/prepack/pull/1072
Reviewed By: cblappert
Differential Revision: D6027356
Pulled By: hermanventer
fbshipit-source-id: 7aca428f0ecf07a5865de842037fe1eda3b1817f
Summary:
Release note: none
Issue: #907
- Set up AdapterChannel object to read and write to Prepack
- Changed Prepack DebugChannel to read and write in the same format
- Implement init, stopped, terminated events
- Implement set breakpoints end to end
The adapter will hold a queue to store requests to Prepack that came from the UI. When Prepack is ready to receive a request, the adapter will send a request from the queue through this AdapterChannel.
Closes https://github.com/facebook/prepack/pull/1091
Differential Revision: D6174872
Pulled By: JWZ2018
fbshipit-source-id: 63c0ebf32bd76d7c6214c5a294b38e07c6be51f7
Summary:
There are only three places that use addEntry() directly. This refactoring moves all three cases into the Generator class itself and mark _addEntry() private. By doing this, we can read Generator class itself to see all the generator entry adding logic instead of searching the whole codebase.
Closes https://github.com/facebook/prepack/pull/1100
Differential Revision: D6161391
Pulled By: yinghuitan
fbshipit-source-id: 6a44a406b95afb8747a9c40c8079f6b6c0402304
Summary: Make prepack work with `js_bundle_genrule` by creating a nodejs_binary call that wraps the prepack CLI.
Reviewed By: davidaurelio
Differential Revision: D6107598
fbshipit-source-id: 6cf3992ecfdc3e15eeed648d341389f4415b79a6
Summary:
Release Note: no
We used to only serialize all code into generator body(either main generator or child generator). But with recently changes, there are additional other emit bodies: delay initializations body, additional function body, and lazy objects body(coming).
Without a type field to categorize these bodies, it is very hard to reason/debug in the emitter.
This is the first refactoring to add strong type to emit body and improve emitter reasoning.
It also fixed a TODO item in Emitter.
Closes https://github.com/facebook/prepack/pull/1096
Differential Revision: D6112434
Pulled By: yinghuitan
fbshipit-source-id: 80ab2ea9bfd73f2d952878c15831cbe7837e8cd7
Summary:
Release note: none
Issue: #907
- Mock UI as a CLI to communicate with the adapter
- Starter code for the debugger adapter with an initialize request
Closes https://github.com/facebook/prepack/pull/1088
Differential Revision: D6108024
Pulled By: JWZ2018
fbshipit-source-id: 506ec039dcb1ff540872cb2e1a87a165cfd22e4d
Summary: Adds new `test-coverage-all` command to `package.json` which will run and compose all test coverage information into one html.
Reviewed By: hermanventer
Differential Revision: D6052366
fbshipit-source-id: 208259fa79185267f6c7a51ca8baf08ffb707e97
Summary:
Release notes: none
- Add defined flow libs
- Starting with vscode-debugadapter and vscode-debugprotocol
- vscode-debugprotocol obtained from public Nuclide open source
- vscode-debugadapter generated using https://github.com/joarwilk/flowgen and modified
Test Plan:
`yarn flow`
Closes https://github.com/facebook/prepack/pull/1095
Differential Revision: D6106213
Pulled By: JWZ2018
fbshipit-source-id: f1a50c835ed36dd43326d6c273ea73ec80d3c0cc
Summary: Bump version number for new alpha
Reviewed By: cblappert
Differential Revision: D6079917
fbshipit-source-id: b7f640001a830813a1b2343efc4ccfeac9810679
Summary:
Release notes:
Generate code for uncaught exceptions at the top level
Adds JSX and ReactElement evaluation/serialization support
Avoid duplicate nested function bodies
Reviewed By: cblappert
Differential Revision: D6079861
fbshipit-source-id: e80e813469def0b98b1799edb79217f45980f911
Summary:
Release Note: Avoid duplicate nested function body(Part2)
Deal with the situation that nested function duplicates with a residual function did not use factory function.
This makes the sample code in issue #777 working.
TODO: Deal with function declaration.
Closes https://github.com/facebook/prepack/pull/1086
Differential Revision: D6081649
Pulled By: yinghuitan
fbshipit-source-id: 20a5a7fa3f053f1aa083345df56a089be1c10d6a
Summary:
Release Note: Avoid duplicate nested function body(Part1)
Avoids duplicating the nested function body with other residual functions. Currently the implementation has the following limitations:
1. Did not deal with the situation that nested function duplicates with a residual function did not use factory function.
2. Did not deal with function declaration
I will address these limitations in later PR.
Closes https://github.com/facebook/prepack/pull/1081
Differential Revision: D6078328
Pulled By: yinghuitan
fbshipit-source-id: 3a6b6dd0b99a5cdb8cffeeba85d257682c3db40e
Summary:
No longer copy entries from one generator to another and make realm.addPriorEffects into a functional version realm.composeEffects, which does not mutate its second argument. Also tweak ancestor logic so that generators that become nested via compose and join report the newly created generators as their parents.
Closes https://github.com/facebook/prepack/pull/1080
Differential Revision: D6068250
Pulled By: hermanventer
fbshipit-source-id: b7961ff3bffe9506e8cbba0926d5d3be33405001
Summary:
Release Notes: none
Additional Functions will now serialize changes to bindings in parent scopes properly. See modified tests for example.
Will add more tests tomorrow.
Closes https://github.com/facebook/prepack/pull/1079
Differential Revision: D6067094
Pulled By: cblappert
fbshipit-source-id: 44bb4895fb72cf8fd1d1a2514e4494de5a7d67c9
Summary:
Rather than do some simplifications inside the factory functions, let the factory functions call simplifyAbstractValue. Some precautions are needed to avoid unbounded recursion.
Closes https://github.com/facebook/prepack/pull/1078
Differential Revision: D6042041
Pulled By: hermanventer
fbshipit-source-id: 84883a01b37d30e08bafa4c1d7f588856a6e323a
Summary:
Write a debugger for Prepack's interpreter which can interact with a client
- set up debugger in prepack and connect
- set up proxy to communicate with client, currently set to be command line
- currently turned debugger off with a flag
Closes https://github.com/facebook/prepack/pull/1035
Differential Revision: D6038235
Pulled By: JWZ2018
fbshipit-source-id: df1693cd2cf973bae32a43308ee38c8906b29143
Summary:
Release Note: none
This PR should provide external tooling, that wraps Prepack Node, the ability to define Prepack globals. This will allow the React compiler to use standalone Prepack with the only differences being specific globals that are added (for React related stubs).
The `additionalGlobals` is a function that passes through `realm` like other globals are handled.
Closes https://github.com/facebook/prepack/pull/1073
Differential Revision: D6039946
Pulled By: trueadm
fbshipit-source-id: f38155244d8d3836b56f39fe964ed0f13b198621
Summary:
Release note: Generate code for uncaught exceptions
This is a high priority fix for a land blocking issue. Please review ASAP.
Exceptions that (conditionally or unconditionally) propagate to the top level program used to cause Prepack to fail.
The new behavior is to generate top level code that will (conditionally) throw the exceptions at runtime.
Closes https://github.com/facebook/prepack/pull/1083
Differential Revision: D6050038
Pulled By: hermanventer
fbshipit-source-id: 666c058befdebf2ed5f97bed74818db57b86f34b
Summary:
Release notes: none
This is a no new functionality refactor that gets rid of the duplication of logic between these two functions.
Addresses #1019.
I don't think I'm quite done with the issue, since the factory functions also contain simplification logic.
Closes https://github.com/facebook/prepack/pull/1074
Differential Revision: D6035089
Pulled By: hermanventer
fbshipit-source-id: 11f3d1a51927ae67beddfa46197088228b93cb9e
Summary:
This PR makes each additional function have its own CaptureScopeAccessFunction and contains some small refactors to make the code cleaner. The reason for each additional function having its own CaptureAccessFunction is so that we can emit the access function (and all of its initializations) into the additional function instead of the global prelude).
Small refactor:
- It separates out additionalFunction's processing from that of normal functions
Closes https://github.com/facebook/prepack/pull/1050
Differential Revision: D6034027
Pulled By: cblappert
fbshipit-source-id: f403dcfb3cc8cf742970b95fde3e9750ae62b8b0
Summary:
Otherwise they will error trying to initialize a binding that doesn't exist.
Fixes evaluation of:
```js
(function() {
class Foo {
}
result = Foo;
})();
```
What do I have to do to run more test262 tests?
Closes https://github.com/facebook/prepack/pull/1034
Differential Revision: D6029314
Pulled By: sebmarkbage
fbshipit-source-id: 3e309df21103216500cbe6a0ae12ce1dc9640bdf
Summary:
Bump version for new release:
1. Enhance Additional Functions testing and functionality.
2. Enhance factorifyObjects() for delay initializations code block.
3. Fix a bug that Prepack may generate invalid syntax for abstract model with special characters in binding name.
4. Support exceptions that are thrown, inside a try-catch, based on an abstract condition.
5. Allow Map, Set, WeakMap and WeakSet to be used inside branches of abstract conditionals.
6. Allow use of arguments.caller property in non strict mode.
Reviewed By: hermanventer
Differential Revision: D6024226
fbshipit-source-id: 99cfcbe6071d4d5820edd8ba838c209586f4fa71
Summary:
Adds the ability to register additional functions at runtime with a global `__registerAdditionalFunction` call. This call will record the function and expose it at the global scope under the internal `__additionalFunctions` object. Note that `checkThatFunctionsAreIndependent` will still run them at the global scope.
This allows for less restrictive tests that and prepares for additional functions that don't have to be global.
Additionally small refactor of properties in `Function` class
Requested by trueadm.
Closes https://github.com/facebook/prepack/pull/1055
Differential Revision: D6020846
Pulled By: cblappert
fbshipit-source-id: 3a040d914de28fa75d8c3470c1066f694c52b8e3
Summary:
This PR enables factorifyObjects() for --delayInitializations body. Will look into later for --inlineExpressions
Closes https://github.com/facebook/prepack/pull/1042
Differential Revision: D6014974
Pulled By: yinghuitan
fbshipit-source-id: 08bfb289d9f92a1cde0ed648328cb198d55f9682
Summary:
Progress towards #632.
There's a lot more that can be done here - for example, we could also eliminate `if (0) foo()` - but presumably that should be done by partial evaluators in a less ad-hoc way.
Closes https://github.com/facebook/prepack/pull/1061
Differential Revision: D6012613
Pulled By: NTillmann
fbshipit-source-id: a7dd6b64a42be34dddf1a59f363ed101feefda64