2015-10-15 02:59:41 +03:00
|
|
|
{
|
|
|
|
"name": "prepack",
|
2018-10-04 18:03:41 +03:00
|
|
|
"version": "0.2.55-alpha.0",
|
2017-04-10 23:35:48 +03:00
|
|
|
"description": "Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.",
|
2017-04-06 04:02:05 +03:00
|
|
|
"homepage": "https://github.com/facebook/prepack",
|
2017-03-30 01:48:22 +03:00
|
|
|
"repository": {
|
|
|
|
"type": "git",
|
2017-04-06 04:02:05 +03:00
|
|
|
"url": "git://github.com/facebook/prepack.git"
|
2017-03-30 01:48:22 +03:00
|
|
|
},
|
2015-10-15 02:59:41 +03:00
|
|
|
"bugs": {
|
2017-04-06 04:02:05 +03:00
|
|
|
"url": "https://github.com/facebook/prepack/issues"
|
2015-10-15 02:59:41 +03:00
|
|
|
},
|
|
|
|
"files": [
|
2017-04-26 22:26:18 +03:00
|
|
|
"LICENSE",
|
|
|
|
"PATENTS",
|
2018-04-06 05:24:35 +03:00
|
|
|
"/bin/",
|
|
|
|
"/lib/"
|
2015-10-15 02:59:41 +03:00
|
|
|
],
|
2017-04-26 22:26:18 +03:00
|
|
|
"bin": {
|
|
|
|
"prepack": "bin/prepack.js",
|
|
|
|
"prepack-repl": "bin/prepack-repl.js"
|
|
|
|
},
|
2017-04-27 10:30:00 +03:00
|
|
|
"main": "lib/prepack-node.js",
|
|
|
|
"browser": "lib/prepack-standalone.js",
|
2015-10-15 02:59:41 +03:00
|
|
|
"scripts": {
|
2018-03-16 00:48:39 +03:00
|
|
|
"build": "yarn build-prepack && yarn build-bundle",
|
2017-07-18 21:42:05 +03:00
|
|
|
"build-scripts": "babel scripts --out-dir lib --source-maps",
|
2018-07-16 23:39:57 +03:00
|
|
|
"build-bundle": "webpack-cli --silent",
|
2018-03-16 00:48:39 +03:00
|
|
|
"build-prepack": "babel src --out-dir lib --source-maps",
|
2018-07-14 19:50:06 +03:00
|
|
|
"watch": "babel src scripts --out-dir lib --watch --source-maps --verbose",
|
2017-04-26 22:26:18 +03:00
|
|
|
"lint": "eslint src scripts",
|
2018-07-18 16:25:26 +03:00
|
|
|
"flow": "flow",
|
|
|
|
"flow-ci": "flow version; flow check",
|
2017-08-04 21:05:40 +03:00
|
|
|
"test-serializer": "babel-node --stack_trace_limit=200 --stack_size=10000 scripts/test-runner.js",
|
2018-07-31 04:26:46 +03:00
|
|
|
"test-serializer-single": "yarn test-serializer --debugNames --verbose --fast --filter",
|
2018-08-24 20:54:26 +03:00
|
|
|
"test-serializer-with-coverage": "./node_modules/.bin/istanbul cover ./lib/test-error-handler.js --dir coverage.error && node --stack_trace_limit=200 --stack_size=10000 ./node_modules/istanbul/lib/cli.js cover ./lib/test-runner.js && ./node_modules/.bin/remap-istanbul -i coverage.error/coverage.json -i coverage/coverage.json -o coverage-sourcemapped -t html",
|
2017-04-26 22:26:18 +03:00
|
|
|
"test-sourcemaps": "babel-node scripts/generate-sourcemaps-test.js && bash < scripts/test-sourcemaps.sh",
|
|
|
|
"test-test262": "babel-node scripts/test262-runner.js",
|
2018-05-01 04:15:09 +03:00
|
|
|
"test-test262-nightly": "NIGHTLY_BUILD=true babel-node scripts/test262-runner.js",
|
2017-12-02 04:37:47 +03:00
|
|
|
"test-test262-new": "babel-node scripts/test262.js",
|
2018-09-01 00:15:40 +03:00
|
|
|
"test-internal": "babel-node --stack_size=10000 --stack_trace_limit=200 --max_old_space_size=32768 scripts/test-internal.js",
|
|
|
|
"test-internal-react": "babel-node --stack_size=10000 --stack_trace_limit=200 --max_old_space_size=32768 scripts/test-internal-react.js",
|
2017-06-20 02:59:25 +03:00
|
|
|
"test-error-handler": "babel-node scripts/test-error-handler.js",
|
|
|
|
"test-error-handler-with-coverage": "./node_modules/.bin/istanbul cover ./lib/test-error-handler.js --dir coverage.error && ./node_modules/.bin/remap-istanbul -i coverage.error/coverage.json -o coverage-sourcemapped.error -t html",
|
2017-07-06 22:35:04 +03:00
|
|
|
"test-std-in": "bash < scripts/test-std-in.sh",
|
2018-07-02 21:16:33 +03:00
|
|
|
"test-react": "jest",
|
|
|
|
"test-react-fast": "SKIP_REACT_JSX_TESTS=true jest",
|
2018-08-12 06:49:07 +03:00
|
|
|
"test": "yarn test-serializer && yarn test-sourcemaps && yarn test-error-handler && yarn test-std-in && yarn test-test262 && yarn test-internal && yarn test-internal-react && yarn test-react",
|
2017-10-20 03:48:24 +03:00
|
|
|
"test-coverage-most": "./node_modules/.bin/istanbul --stack_size=10000 --max_old_space_size=16384 cover ./lib/multi-runner.js --dir coverage.most && ./node_modules/.bin/remap-istanbul -i coverage.most/coverage.json -o coverage-sourcemapped -t html",
|
2018-05-01 04:15:09 +03:00
|
|
|
"test-all-coverage": "./node_modules/.bin/istanbul --stack_size=10000 --max_old_space_size=16384 cover ./lib/multi-runner.js --dir coverage.most && ./node_modules/.bin/istanbul --stack_size=10000 --max_old_space_size=16384 cover ./lib/test262-runner.js --timeout 50 --singleThreaded && ./node_modules/.bin/remap-istanbul -i coverage/coverage.json -i coverage.most/coverage.json -o coverage-sourcemapped -t html",
|
2017-04-26 22:26:18 +03:00
|
|
|
"repl": "node lib/repl-cli.js",
|
2018-03-30 02:34:59 +03:00
|
|
|
"precheck": "yarn prepack-cli --check",
|
2018-08-24 10:02:05 +03:00
|
|
|
"prepack-cli": "node --stack_size=10000 --stack_trace_limit=200 --max_old_space_size=16384 lib/prepack-cli.js --compatibility jsc-600-1-4-17 --mathRandomSeed 0",
|
2018-04-17 04:44:20 +03:00
|
|
|
"validate": "yarn install --frozen-lockfile && yarn build && yarn build-scripts && yarn lint && yarn depcheck && yarn flow && yarn test",
|
2018-04-13 12:58:40 +03:00
|
|
|
"prepublishOnly": "yarn build",
|
2017-06-29 22:16:33 +03:00
|
|
|
"depcheck": "babel-node scripts/detect_bad_deps.js",
|
2017-07-07 21:28:43 +03:00
|
|
|
"prettier": "node ./scripts/prettier.js write-changed",
|
2018-02-23 04:46:50 +03:00
|
|
|
"prettier-all": "node ./scripts/prettier.js write",
|
2018-07-10 19:41:08 +03:00
|
|
|
"prettier-ci": "node ./scripts/prettier.js",
|
Fuzzer (#2374)
Summary:
This PR adds the fuzzer I’ve been working on to the Prepack codebase so other people can contribute, provide feedback, and run it against their changes. The new commands added are:
- `yarn fuzz`: Starts generating tests in the foreground and logs progress. If it finds an error it will try and shrink it before returning the shrunken program to you with the invalid results.
- `yarn fuzz-sample`: See a selection of the programs generated by the fuzzer.
- `yarn fuzz-overnight`: Spin up a worker for each CPU and try to find failing test cases. Your computer will be basically unusable while you run this, so leave it running overnight. Failed test cases will be saved in `fuzzer/overnight.sqlite` so in the morning you can use `sqlite3` to inspect the errors the fuzzer found.
The fuzzer generates programs with an optimized function and executes them twice:
1. In Node.js
2. In Node.js after running Prepack
Then compares the results. If the results are different then the fuzzer will attempt to shrink the program to something easier to debug and return this to you. See [this gist for a sample of generated programs](https://gist.github.com/calebmer/6a727c1f4aa8c08d51940e60d29d336a). Here’s an example of a function you might see:
```js
function f3(a1, a2, a3, a4, a5, a6) {
2;
var x2;
if (0) {
return a1 ? false : a2;
} else {
var x1 = a3;
x2 = x1;
}
var x6;
if (x2) {
var x3;
if (x2) {
x3 = x2;
} else {
x3 = a4;
}
var x4 = x3;
x6 = x4;
} else {
var x5;
if (a5) {
x5 = x2;
} else {
x5 = a6;
}
x6 = f2(x5);
}
return x6;
}
```
So far I’ve reported four bugs reduced from test cases found by this version of the fuzzer. I’ve reported a couple more from old fuzzers I used, but these four from the current version. The shrinking process is not that good and it takes a while as the generated program can get large, so you’ll usually have to do some manual shrinking to get good bug reports. I only ran `yarn fuzz-overnight` for about an hour. It found 28 failures and I reduced those down to these 4.
- #2354
- #2355
- #2361
- #2363
I expect I’ll find more bugs as these get fixed and I add more JavaScript features to the fuzzer. The features I currently have are:
- Scalar primitives (number, string, boolean, null/undefined)
- Functions
- Conditional expressions
- If statements
- Variable declarations
Not too many features, but enough to catch a handful of bugs.
> **Note:** If this PR is too much to review, I’ve created [`calebmer/prepack-fuzzer`](https://github.com/calebmer/prepack-fuzzer) in which my work is broken up into commits as I made them. I then copied these files over to the Prepack repo.
The fuzzer in this PR is a rewrite from the [fuzzer I started with](https://gist.github.com/calebmer/75dd75ebe556681d3a628e75eaffc403). The main lessons I learned from that one are that I should start with a general JS fuzzer instead of a React fuzzer (since adding JS features after the fact to fuzzer designed for React is difficult) and that all nested structures need to be generated with one recursive generator from the generator library I’m using.
To generate programs I use [`leebyron/testcheck`](https://github.com/leebyron/testcheck-js) which is actually a JS compiled version of the official Clojure library [`clojure/test.check`](https://github.com/clojure/test.check). `testcheck` is designed for generative property testing at a much smaller scale then program fuzzing. So I am abusing the library a bit to use it as a fuzzer. My reasoning is that I wanted to write the fuzzer in JS (to have access to the Babel AST) and I didn’t want to write my own case generating framework. If we outgrow `testcheck` then we can keep the DSL, but rewrite the generation/shrinking logic. Although its been working fine for me so far. (Yet I am using a forked version which simply uses some unpublished features in the `testcheck` repo.)
The generator code in `fuzzer/src/gen.js` may look odd to you. It uses immutable.js and a **state monad** implemented with a JS generator so the code looks imperative. I need state since generating various program components depends on things like “what variables are declared at a given point in time,” but because I’m limited to only using a single recursive generator (based on performance lessons I learned from my first fuzzer) I can’t pass around state at the generator level and must instead maintain state at the result level. At first I tried hacking together some imperative state, but when shrinking programs `testcheck` replays some generators to get new programs. So what do you do when you need a stateful process that needs to be replayed? You use a monad.
I could try to fix the bugs I found, but I’d like to find more bugs. I need to add back support for React components and I need to add more language features.
_Which JS language features are the most interesting to fuzz?_
I ranked all the kinds of AST nodes in our internal React bundle [and got this](https://gist.github.com/calebmer/be5e2bad4b12af683522096544fc9568). I’ll be starting with that, but the Prepack team has a better intuition around what’s good for fuzzing. I know there’s been a discussion around temporals recently that I haven’t really been following. What would be good ways to trigger this behavior?
Pull Request resolved: https://github.com/facebook/prepack/pull/2374
Differential Revision: D9180836
Pulled By: calebmer
fbshipit-source-id: 59d3fb59ecc1026a865672e2833f7482ed72139a
2018-08-09 20:35:07 +03:00
|
|
|
"debug-fb-www": "node --stack_trace_limit=200 --stack_size=10000 --max_old_space_size=16384 ./scripts/debug-fb-www.js",
|
|
|
|
"fuzz": "cd fuzzer && yarn && yarn test",
|
|
|
|
"fuzz-sample": "cd fuzzer && yarn && yarn sample",
|
|
|
|
"fuzz-overnight": "cd fuzzer && yarn && yarn overnight"
|
2015-10-15 02:59:41 +03:00
|
|
|
},
|
|
|
|
"dependencies": {
|
2018-08-28 22:52:19 +03:00
|
|
|
"@babel/core": "^7.0.0",
|
|
|
|
"@babel/generator": "^7.0.0",
|
|
|
|
"@babel/node": "^7.0.0",
|
|
|
|
"@babel/parser": "^7.0.0",
|
2018-09-18 14:08:25 +03:00
|
|
|
"@babel/preset-flow": "^7.0.0",
|
2018-08-28 22:52:19 +03:00
|
|
|
"@babel/template": "^7.0.0",
|
|
|
|
"@babel/traverse": "^7.0.0",
|
|
|
|
"@babel/types": "^7.0.0",
|
2018-06-02 22:44:51 +03:00
|
|
|
"fbjs": "^0.8.16",
|
2018-03-03 21:14:49 +03:00
|
|
|
"node-zip": "^1.1.1",
|
2017-10-20 20:52:42 +03:00
|
|
|
"queue-fifo": "^0.2.3",
|
2015-10-15 02:59:41 +03:00
|
|
|
"seedrandom": "^2.4.2",
|
2017-10-20 20:52:42 +03:00
|
|
|
"source-map": "^0.5.6",
|
|
|
|
"vscode-debugadapter": "^1.24.0",
|
Repro option creates package with sourcefiles, debugger startup script (#2289)
Summary:
Release Notes:
- Created DebugReproManager to capture all sourcefiles touched by Prepack (to include minimal subset of useful sourcefiles in the debug package)
- `--repro` splits into two: `--reproUnconditionally` which will create a debug package _regardless_ of Prepack's success/failure, and `--reproOnFatal`, which will _only_ create a debug package if Prepack outputs a `FatalError`.
- The debug package now includes all relevant sourcefiles (except for node modules), a copy of the version of Prepack (lib) that was used when the package was created, and a script to `yarn install` the relevant modules for the included version of Prepack, then start the Nuclide Prepack debugger with the proper parameters for files in the debug package (including original prepack arguments). This is in addition to the original input files.
- The impact of having the `DebugReproManager` on in `--reproOnFatal` mode all the time is negligible, as show in the table below. This flag will be always be enabled on Sandcastle builds so that failures are more easily debugged.
- The time difference between no repro flag and `--reproOnFatal` seems like it can be written off as simple variance between runs. The larger increase when actually creating the zip comes from reading and zipping the files, which takes time proportional how many files are touched.
- SourceMapManager was refactored to not use `Invariant` or `SourceFile`s. This is so that `DebugReproManager` import it without increasing the flow cycle, and allows the `DebugReproManager` to be passed from Prepack to the CLI to create the repro package.
- The repro option introduces a potential for a subtle race condition that is addressed as follows:
- The last `if (!success && reproMode === "none") process.exit(1);` must check reproMode because `generateDebugRepro` involves an async process (directory zipping). If there is an ongoing repro and the process exits, the repro may terminate prematurely, causing no repro to be generated. Instead, this only triggers if there is no repro -- if there is, the `generateDebugRepro` function will handle process exiting if it needs to.
Usage:
```node [prepack] [files to prepack] --reproOnFatal /Absolute/path/to/repro/bundle.zip --debugBuckRoot /buck/root```
or
```node [prepack] [files to prepack] --reproUnconditionally /Absolute/path/to/repro/bundle.zip --debugBuckRoot /buck/root```
Demo: https://www.dropbox.com/s/p62ves2p55fyyl7/--repro%20annotated%20demo.mp4?dl=0
Pull Request resolved: https://github.com/facebook/prepack/pull/2289
Differential Revision: D9002841
Pulled By: caiismyname
fbshipit-source-id: 623b362f963095f1cd8163684fd6e76596e7c4fc
2018-07-27 00:44:31 +03:00
|
|
|
"vscode-debugprotocol": "^1.24.0",
|
|
|
|
"zip-dir": "^1.0.2"
|
2015-10-15 02:59:41 +03:00
|
|
|
},
|
|
|
|
"devDependencies": {
|
2018-08-28 22:52:19 +03:00
|
|
|
"@babel/cli": "^7.0.0",
|
|
|
|
"@babel/plugin-proposal-class-properties": "^7.0.0",
|
|
|
|
"@babel/plugin-proposal-export-default-from": "^7.0.0",
|
|
|
|
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
|
|
|
|
"@babel/plugin-syntax-flow": "^7.0.0",
|
|
|
|
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
|
|
|
|
"@babel/plugin-transform-modules-commonjs": "^7.0.0",
|
|
|
|
"@babel/plugin-transform-react-display-name": "^7.0.0",
|
|
|
|
"@babel/plugin-transform-react-jsx": "^7.0.0",
|
|
|
|
"@babel/preset-env": "^7.0.0",
|
2018-09-18 14:08:25 +03:00
|
|
|
"@babel/preset-flow": "^7.0.0",
|
2018-08-28 22:52:19 +03:00
|
|
|
"@babel/preset-react": "^7.0.0",
|
|
|
|
"@babel/register": "^7.0.0",
|
2018-07-14 19:50:06 +03:00
|
|
|
"babel-core": "7.0.0-bridge.0",
|
|
|
|
"babel-eslint": "^8.2.6",
|
|
|
|
"babel-jest": "^23.4.0",
|
|
|
|
"babel-loader": "^8.0.0-beta",
|
|
|
|
"babel-plugin-jest-hoist": "^23.2.0",
|
2017-04-26 22:26:18 +03:00
|
|
|
"chalk": "^1.1.3",
|
2018-03-06 07:52:03 +03:00
|
|
|
"eslint": "^4.18.2",
|
2018-06-08 14:10:10 +03:00
|
|
|
"eslint-plugin-babel": "^3.3.0",
|
2015-10-15 02:59:41 +03:00
|
|
|
"eslint-plugin-flow-header": "^0.1.1",
|
2018-05-10 08:08:29 +03:00
|
|
|
"eslint-plugin-flowtype": "^2.40.0",
|
2015-10-15 02:59:41 +03:00
|
|
|
"eslint-plugin-header": "^1.0.0",
|
2017-07-18 23:53:50 +03:00
|
|
|
"eslint-plugin-prettier": "^2.1.2",
|
2018-03-03 21:14:49 +03:00
|
|
|
"flow-typed": "^2.3.0",
|
2015-10-15 02:59:41 +03:00
|
|
|
"graceful-fs": "^4.1.11",
|
2017-04-26 22:26:18 +03:00
|
|
|
"invariant": "^2.2.0",
|
|
|
|
"istanbul": "^0.4.5",
|
2018-07-14 19:50:06 +03:00
|
|
|
"jest": "^23.4.1",
|
2018-07-04 15:25:34 +03:00
|
|
|
"js-beautify": "^1.7.5",
|
2017-04-26 22:26:18 +03:00
|
|
|
"js-yaml": "^3.6.1",
|
|
|
|
"jsdom": "^9.2.1",
|
2017-04-15 01:09:34 +03:00
|
|
|
"madge": "^1.6.0",
|
2017-04-26 22:26:18 +03:00
|
|
|
"minimist": "^1.2.0",
|
2019-05-07 20:18:05 +03:00
|
|
|
"prettier": "1.17.0",
|
2018-02-16 18:58:44 +03:00
|
|
|
"prop-types": "^15.6.0",
|
2018-04-11 20:04:02 +03:00
|
|
|
"react": "16.3.1",
|
|
|
|
"react-dom": "16.3.1",
|
2018-07-04 00:42:13 +03:00
|
|
|
"react-native": "^0.55.4",
|
2018-02-08 20:02:54 +03:00
|
|
|
"react-relay": "^1.4.1",
|
2018-04-11 20:04:02 +03:00
|
|
|
"react-test-renderer": "16.3.1",
|
2018-07-14 19:50:06 +03:00
|
|
|
"regenerator-runtime": "^0.12.0",
|
2017-04-26 22:26:18 +03:00
|
|
|
"remap-istanbul": "^0.9.1",
|
|
|
|
"source-map-support": "^0.4.6",
|
2017-12-02 04:37:47 +03:00
|
|
|
"test262-integrator": "^1.2.0",
|
2018-07-14 19:50:06 +03:00
|
|
|
"webpack": "^4.16.0",
|
|
|
|
"webpack-cli": "^3.0.8"
|
2015-10-15 02:59:41 +03:00
|
|
|
},
|
2018-04-19 00:50:48 +03:00
|
|
|
"optionalDependencies": {
|
2018-09-08 02:33:08 +03:00
|
|
|
"v8-profiler-node8": "^6.0.1"
|
2018-04-19 00:50:48 +03:00
|
|
|
},
|
2015-10-15 02:59:41 +03:00
|
|
|
"engines": {
|
2017-06-13 00:36:56 +03:00
|
|
|
"node": ">=6.1.0"
|
2015-10-15 02:59:41 +03:00
|
|
|
},
|
|
|
|
"keywords": [
|
|
|
|
"prepack"
|
|
|
|
],
|
|
|
|
"license": "BSD-3-Clause",
|
2017-11-02 14:28:37 +03:00
|
|
|
"author": "Facebook",
|
|
|
|
"jest": {
|
2018-07-04 00:42:13 +03:00
|
|
|
"preset": "react-native",
|
2018-07-02 21:16:33 +03:00
|
|
|
"roots": [
|
2018-07-04 00:42:13 +03:00
|
|
|
"<rootDir>/node_modules/react-native/",
|
2018-07-02 21:16:33 +03:00
|
|
|
"<rootDir>/lib/",
|
2018-07-04 15:25:34 +03:00
|
|
|
"<rootDir>/test/react/",
|
|
|
|
"<rootDir>/fb-www/"
|
2018-07-02 21:16:33 +03:00
|
|
|
],
|
2018-07-04 00:42:13 +03:00
|
|
|
"testEnvironment": "jsdom",
|
2017-11-02 14:28:37 +03:00
|
|
|
"testMatch": [
|
2018-07-04 15:25:34 +03:00
|
|
|
"**/test/react/*-test.js",
|
|
|
|
"**/fb-www/**/*-test.js"
|
2018-07-14 19:50:06 +03:00
|
|
|
],
|
|
|
|
"transformIgnorePatterns": [
|
|
|
|
"/node_modules/(?!react-native).+\\.js$"
|
2017-11-02 14:28:37 +03:00
|
|
|
]
|
|
|
|
}
|
2015-10-15 02:59:41 +03:00
|
|
|
}
|