Summary:
Release note: Partially fixes#1182
When dealing with x || y and x && y where x is an abstract value, we can avoid evaluating x if it is known to be false in the first case and true in the second. When x is being refined with the path condition, it helps to know that the refined result will only be checked for truthiness. Duly add a call to Environment.GetConditionValue to make this happen.
Closes https://github.com/facebook/prepack/pull/1184
Differential Revision: D6420018
Pulled By: hermanventer
fbshipit-source-id: ec45808b0235cda896634c09940a8d20b318eb48
Summary:
hermanventer suggests use Proxy to mock test-runner hydration for Lazy Objects which is very promising. Here are the improvements using proxy hook mocking:
1. More accurate hydration simulation
2. The 4 failed tests all succeed now.
3. All test mocking support are in test-runner now. No need to serialize ugly test runner comment.
4. I find real bugs after switching to Proxy simulation.
I also changed the test-runner a bit to output full runnable code when test-runner failed. This makes lazy object debugging much easier.
Closes https://github.com/facebook/prepack/pull/1188
Differential Revision: D6402100
Pulled By: yinghuitan
fbshipit-source-id: 1f9ebff99e4b23ff614d8d82fedd112ab8848a75
Summary:
Release note: Fixes#1179
When a property is written to object, the rather convoluted logic for checking if it is allowed and if a setter is involved end up asking the object three times if it already has such a property.
In the case of a simple partial object, this caused three useless references to the property to appear in the generated code, since the absence of a property is regarded as OK and produces a temporal abstract value that just reads from the object at runtime.
Fixed this by adding a special case when writing to a missing property on a simple partial object.
Closes https://github.com/facebook/prepack/pull/1183
Differential Revision: D6399970
Pulled By: hermanventer
fbshipit-source-id: b964ee399583f3f4f30dc2f1930e06a856952635
Summary:
Fix a few problem that came to light when an environmental model was updated to include an optional boolean flag.
Closes https://github.com/facebook/prepack/pull/1169
Differential Revision: D6363050
Pulled By: hermanventer
fbshipit-source-id: 6b92f76045c759e4ae02507e41c4024af937dafc
Summary:
Currently, you can only fold functional components. This PR aims to allow functional component folding directly into a class component. Essentially, this is an incremental step to adding full class component folding.
Closes https://github.com/facebook/prepack/pull/1135
Differential Revision: D6347566
Pulled By: trueadm
fbshipit-source-id: 18cfe3b9583334d4e3500004b562adec3fa9ecee
Summary:
Serializing the arguments of an "abstractConcreteUnion" causes the abstract element to be assigned to a temp twice (once as a argument and once as the union). Avoid this by returning the serialized value of the abstract argument as the result of serializing the union.
Closes https://github.com/facebook/prepack/pull/1158
Differential Revision: D6337410
Pulled By: hermanventer
fbshipit-source-id: 6eaaa09de1622da076dbe58d5f2a490cb6f3d45b
Summary:
Creating a nameless intrinsic object could result in an abstract value with a useless hash in cases where the location is unknown. Instead, use a unique counter.
Closes https://github.com/facebook/prepack/pull/1156
Differential Revision: D6331059
Pulled By: hermanventer
fbshipit-source-id: efcfa4bb418074d086b3f282d18ba70c307dda97
Summary:
Release notes: Provides support for joining properties that have get and set methods. Also now fully support properties that are only defined in one branch of an unknown conditional.
The main thing that happens here is that descriptors that result from joins now track the join condition and the original descriptors, so that the serializer can emit conditional code for defining the entire property, which allows it to also conditionally omit properties altogether.
Issue #1015
Closes https://github.com/facebook/prepack/pull/1116
Differential Revision: D6331039
Pulled By: hermanventer
fbshipit-source-id: 42d635d37b9880398cc4e039f2d59a9a5d03cec0
Summary:
Release Note: enable lazy objects mode in test-runner.
Note: I will try hermanventer's suggestion to move all lazy objects creation to prelude and hydrate them after that in future PR for a better way to deal with lazy objects testing issue.
1. Enables lazy objects mode in test runner.
2. For JSON.stringify() and for...in constructs that hydrate lazy objects in global code, I added "force hydrate lazy objects" attribute in the generated code telling test-runner to hydrate the objects immediately
3. Disable lazy objects mode for 3 factorify tests and 4 abstract tests.
4. Skip lazy objects mode for react compiler, additional function tests.
5. Fix a bug which only shows up in lazy objects mode: a) if the target body is non-generator body and delay reason is generator body there is no need to wait for it. b) we should use targetBody instead of this._body in emitter if delayReason is a Value.
Closes https://github.com/facebook/prepack/pull/1147
Differential Revision: D6326474
Pulled By: yinghuitan
fbshipit-source-id: 84fd8d3550ea4685da418224c28247ad330da8bf
Summary:
For global let bindings, the serializer ignored the CSE value provided by the visitor. This led to an invariant failure when looking up the scope of a value that had been replaced by an equivalent value during CSE analysis in the visitor.
Closes https://github.com/facebook/prepack/pull/1149
Differential Revision: D6325186
Pulled By: hermanventer
fbshipit-source-id: 421d5bfc3f4e0c9ec7730af6ff3a38d4b926bcae
Summary:
After adding some tests, it turns out that logic to apply keys to arrays was un-needed. This was because, after running the same code through React, the same errors occur when keys are omitted from arrays. We don't need to do any clever tricks to add keys, as it might actually break logic on things that don't need them. I've added the relevant tests and removed the key adding logic, which should help us with the de-duping work (https://github.com/facebook/prepack/issues/1150).
Closes https://github.com/facebook/prepack/pull/1151
Differential Revision: D6323878
Pulled By: trueadm
fbshipit-source-id: ec3fa90c48332ef0715e94335c558570040ed81c
Summary:
Followup to #1061; I thought of another case where it was too aggressive.
Do-while loops with always-false conditions can't be replaced by their body because their body might contain a break or continue, which is illegal (or will have different semantics) if the loop becomes a normal block. In principle the body of the loop could be walked to find those, but frankly I doubt it will come up enough to be worth it.
Closes https://github.com/facebook/prepack/pull/1145
Differential Revision: D6303312
Pulled By: hermanventer
fbshipit-source-id: 0d677076fea6f225573a36fbbc9df1a0bebd959a
Summary:
Release Notes: none.
This fixes#1093. At a high level, captures are currently needed by the additional function only if they are modified.
Implementation-wise we tentatively create all bindings with callbacks to visit them and delete them to make sure that after Additional Functions are visited we have a precise set of captures.
Functionality of the PR is fully there but I would like to refactor it in some way because I feel like it can be cleaner.
Closes https://github.com/facebook/prepack/pull/1107
Differential Revision: D6290712
Pulled By: cblappert
fbshipit-source-id: 8b812e28f83c2cb216c01eb52a10f6cb0873ea8d
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:
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
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:
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:
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:
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: 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:
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:
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:
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:
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
Summary:
This clone is needed before because we may not be able to completely share the function bodies due to mutable binding captured scope array access. With my changes associated with #935, all function instances can be shared now, so this clone is unnecessary.
Closes https://github.com/facebook/prepack/pull/1053
Differential Revision: D6009681
Pulled By: yinghuitan
fbshipit-source-id: 09e671bfac3a8eceda63376d9a864a491151910e
Summary:
All of this complexity is because of the need to separate complex completions (containing conditional throw completions) that arrive at the join point at the end of a function body into a separate return completion with a joined value, along with a now possibly normal completion that collects all of the throw completions.
Since the call expression needs to return a value, not a completion, the return completion is thrown away and its value is returned, while the possibly normal completion is stashed in the current execution environment. From there the latter is eventually copied to the caller environment and it is joined with any further completions until the next join point arrives.
If this next join point is a catch, the possibly normal completion will be consumed and the field in the current execution environment will be cleared (unless of course, the catch clause has a conditional abrupt completion).
Closes https://github.com/facebook/prepack/pull/1062
Differential Revision: D6003059
Pulled By: hermanventer
fbshipit-source-id: 91780ae6a051039608c19eb049cdab02652bb73e
Summary:
If the try block of a try-catch statement possibly throws an exception, bring the effects of the catch handler into the state of the exceptional control flow and carry on.
Closes https://github.com/facebook/prepack/pull/1046
Differential Revision: D5989477
Pulled By: hermanventer
fbshipit-source-id: 37dcd36e817d642122602554f71e0ba19706c400
Summary:
Fixes#988
trueadm hopefully you can just patch this into your branch easily
Closes https://github.com/facebook/prepack/pull/1052
Differential Revision: D5990102
Pulled By: cblappert
fbshipit-source-id: dd37530f6b56332724631423e02a928d944a88c5
Summary:
Remove calls to ThrowIfInternalSlotNotWritable from these types because their internal properties are now tracked. Add some rudimentary tests for them.
Note that a lot of operations still fall over because the linear searching code gives up as soon as it encounters an abstract value. Fixing that will be a bit more work.
Closes https://github.com/facebook/prepack/pull/1043
Differential Revision: D5980113
Pulled By: hermanventer
fbshipit-source-id: 86254337ada1de666f2f1d4ada40dfa06beb52a4
Summary:
Map values that are updated in the context of unknown conditions now have change tracking for the elements of the $MapData property and the array values in these properties can now be joined.
Some rudimentary support for Flow typing property bindings with values of type Array is also provided. It resorts to using any for the element type because Flow seems unable to deal with the union of two array types.
Most uses of the value property of a property binding object come from properties that can never have (native) arrays as values, so many invariants to the effect are needed.
Partially addressed #573
Closes https://github.com/facebook/prepack/pull/1040
Differential Revision: D5966066
Pulled By: hermanventer
fbshipit-source-id: 8ceea960f780d63d185d24202e316d310a2e4ea5
Summary:
This PR moves `VisitedBindings` so that it is a part of FunctionInstance. This is the first in a series of refactors before a PR to fix Issue #990.
Closes https://github.com/facebook/prepack/pull/1029
Differential Revision: D5945739
Pulled By: cblappert
fbshipit-source-id: 7813c159421d0fc9d13ad3482145d2fff68550a2
Summary:
Do more simplification inside refineWithPathCondition. (Right now, it is a bit awkward to use the actual simplifier here.)
Also tweak various things and delete some code that is a) uncovered by tests and b) probably not reachable anyway.
With these changes, Prepack can now deal with all the modules that are conditionally required in our benchmark application.
Closes https://github.com/facebook/prepack/pull/996
Differential Revision: D5930379
Pulled By: hermanventer
fbshipit-source-id: 095c042253c29029ef5818441c80490c42811c20
Summary:
Simplify if conditions before using them as the join condition for the true and else branches.
Beef up simplifier to simplify && and || expressions and to try to simplify equality expressions of the form "(cond ? xx : yy) (==|!=|===|!==) (undefined|null)" to just "cond" or "!cond"
Closes https://github.com/facebook/prepack/pull/983
Differential Revision: D5929527
Pulled By: hermanventer
fbshipit-source-id: dcc04598ab90df10a32203b692db098137d01ea7
Summary:
Also add some other bits and pieces that are needed to get path.js to 100% unit test coverage.
Closes https://github.com/facebook/prepack/pull/975
Differential Revision: D5909857
Pulled By: hermanventer
fbshipit-source-id: bd2e5472db20415a0c42bbd7fbd160315acfeae3
Summary:
Currently works for all test cases except `noconflict-existantobject.js`.
There are a couple things that are dubious in the current implementation that I will address as I iterate on it:
* We don't visit things correctly in the visitor or the serializer -- we should be visiting only:
* generator entries in effects
* Bindings, PropertyBindings in effects not relating to CreatedObjects
* There is currently no way to emit to the main body after the main generator has been serialized -- we may need to if a value is only reachable from one of the additional functions.
* More thought needs to go into how this interacts with
* speculative initialization
* require optimization
* inlining
Closes https://github.com/facebook/prepack/pull/912
Differential Revision: D5859741
Pulled By: cblappert
fbshipit-source-id: 9fe7bd4429ad53629582f9fb7154a28971159554